mirror of
https://github.com/torvalds/linux.git
synced 2024-11-24 21:21:41 +00:00
Merge branch 'sa1100' into devel
This commit is contained in:
commit
3d14b5beba
@ -86,4 +86,9 @@
|
||||
!Iinclude/trace/events/irq.h
|
||||
</chapter>
|
||||
|
||||
<chapter id="signal">
|
||||
<title>SIGNAL</title>
|
||||
!Iinclude/trace/events/signal.h
|
||||
</chapter>
|
||||
|
||||
</book>
|
||||
|
@ -1,185 +1,10 @@
|
||||
CONFIG_RCU_TRACE debugfs Files and Formats
|
||||
|
||||
|
||||
The rcupreempt and rcutree implementations of RCU provide debugfs trace
|
||||
output that summarizes counters and state. This information is useful for
|
||||
debugging RCU itself, and can sometimes also help to debug abuses of RCU.
|
||||
Note that the rcuclassic implementation of RCU does not provide debugfs
|
||||
trace output.
|
||||
|
||||
The following sections describe the debugfs files and formats for
|
||||
preemptable RCU (rcupreempt) and hierarchical RCU (rcutree).
|
||||
|
||||
|
||||
Preemptable RCU debugfs Files and Formats
|
||||
|
||||
This implementation of RCU provides three debugfs files under the
|
||||
top-level directory RCU: rcu/rcuctrs (which displays the per-CPU
|
||||
counters used by preemptable RCU) rcu/rcugp (which displays grace-period
|
||||
counters), and rcu/rcustats (which internal counters for debugging RCU).
|
||||
|
||||
The output of "cat rcu/rcuctrs" looks as follows:
|
||||
|
||||
CPU last cur F M
|
||||
0 5 -5 0 0
|
||||
1 -1 0 0 0
|
||||
2 0 1 0 0
|
||||
3 0 1 0 0
|
||||
4 0 1 0 0
|
||||
5 0 1 0 0
|
||||
6 0 2 0 0
|
||||
7 0 -1 0 0
|
||||
8 0 1 0 0
|
||||
ggp = 26226, state = waitzero
|
||||
|
||||
The per-CPU fields are as follows:
|
||||
|
||||
o "CPU" gives the CPU number. Offline CPUs are not displayed.
|
||||
|
||||
o "last" gives the value of the counter that is being decremented
|
||||
for the current grace period phase. In the example above,
|
||||
the counters sum to 4, indicating that there are still four
|
||||
RCU read-side critical sections still running that started
|
||||
before the last counter flip.
|
||||
|
||||
o "cur" gives the value of the counter that is currently being
|
||||
both incremented (by rcu_read_lock()) and decremented (by
|
||||
rcu_read_unlock()). In the example above, the counters sum to
|
||||
1, indicating that there is only one RCU read-side critical section
|
||||
still running that started after the last counter flip.
|
||||
|
||||
o "F" indicates whether RCU is waiting for this CPU to acknowledge
|
||||
a counter flip. In the above example, RCU is not waiting on any,
|
||||
which is consistent with the state being "waitzero" rather than
|
||||
"waitack".
|
||||
|
||||
o "M" indicates whether RCU is waiting for this CPU to execute a
|
||||
memory barrier. In the above example, RCU is not waiting on any,
|
||||
which is consistent with the state being "waitzero" rather than
|
||||
"waitmb".
|
||||
|
||||
o "ggp" is the global grace-period counter.
|
||||
|
||||
o "state" is the RCU state, which can be one of the following:
|
||||
|
||||
o "idle": there is no grace period in progress.
|
||||
|
||||
o "waitack": RCU just incremented the global grace-period
|
||||
counter, which has the effect of reversing the roles of
|
||||
the "last" and "cur" counters above, and is waiting for
|
||||
all the CPUs to acknowledge the flip. Once the flip has
|
||||
been acknowledged, CPUs will no longer be incrementing
|
||||
what are now the "last" counters, so that their sum will
|
||||
decrease monotonically down to zero.
|
||||
|
||||
o "waitzero": RCU is waiting for the sum of the "last" counters
|
||||
to decrease to zero.
|
||||
|
||||
o "waitmb": RCU is waiting for each CPU to execute a memory
|
||||
barrier, which ensures that instructions from a given CPU's
|
||||
last RCU read-side critical section cannot be reordered
|
||||
with instructions following the memory-barrier instruction.
|
||||
|
||||
The output of "cat rcu/rcugp" looks as follows:
|
||||
|
||||
oldggp=48870 newggp=48873
|
||||
|
||||
Note that reading from this file provokes a synchronize_rcu(). The
|
||||
"oldggp" value is that of "ggp" from rcu/rcuctrs above, taken before
|
||||
executing the synchronize_rcu(), and the "newggp" value is also the
|
||||
"ggp" value, but taken after the synchronize_rcu() command returns.
|
||||
|
||||
|
||||
The output of "cat rcu/rcugp" looks as follows:
|
||||
|
||||
na=1337955 nl=40 wa=1337915 wl=44 da=1337871 dl=0 dr=1337871 di=1337871
|
||||
1=50989 e1=6138 i1=49722 ie1=82 g1=49640 a1=315203 ae1=265563 a2=49640
|
||||
z1=1401244 ze1=1351605 z2=49639 m1=5661253 me1=5611614 m2=49639
|
||||
|
||||
These are counters tracking internal preemptable-RCU events, however,
|
||||
some of them may be useful for debugging algorithms using RCU. In
|
||||
particular, the "nl", "wl", and "dl" values track the number of RCU
|
||||
callbacks in various states. The fields are as follows:
|
||||
|
||||
o "na" is the total number of RCU callbacks that have been enqueued
|
||||
since boot.
|
||||
|
||||
o "nl" is the number of RCU callbacks waiting for the previous
|
||||
grace period to end so that they can start waiting on the next
|
||||
grace period.
|
||||
|
||||
o "wa" is the total number of RCU callbacks that have started waiting
|
||||
for a grace period since boot. "na" should be roughly equal to
|
||||
"nl" plus "wa".
|
||||
|
||||
o "wl" is the number of RCU callbacks currently waiting for their
|
||||
grace period to end.
|
||||
|
||||
o "da" is the total number of RCU callbacks whose grace periods
|
||||
have completed since boot. "wa" should be roughly equal to
|
||||
"wl" plus "da".
|
||||
|
||||
o "dr" is the total number of RCU callbacks that have been removed
|
||||
from the list of callbacks ready to invoke. "dr" should be roughly
|
||||
equal to "da".
|
||||
|
||||
o "di" is the total number of RCU callbacks that have been invoked
|
||||
since boot. "di" should be roughly equal to "da", though some
|
||||
early versions of preemptable RCU had a bug so that only the
|
||||
last CPU's count of invocations was displayed, rather than the
|
||||
sum of all CPU's counts.
|
||||
|
||||
o "1" is the number of calls to rcu_try_flip(). This should be
|
||||
roughly equal to the sum of "e1", "i1", "a1", "z1", and "m1"
|
||||
described below. In other words, the number of times that
|
||||
the state machine is visited should be equal to the sum of the
|
||||
number of times that each state is visited plus the number of
|
||||
times that the state-machine lock acquisition failed.
|
||||
|
||||
o "e1" is the number of times that rcu_try_flip() was unable to
|
||||
acquire the fliplock.
|
||||
|
||||
o "i1" is the number of calls to rcu_try_flip_idle().
|
||||
|
||||
o "ie1" is the number of times rcu_try_flip_idle() exited early
|
||||
due to the calling CPU having no work for RCU.
|
||||
|
||||
o "g1" is the number of times that rcu_try_flip_idle() decided
|
||||
to start a new grace period. "i1" should be roughly equal to
|
||||
"ie1" plus "g1".
|
||||
|
||||
o "a1" is the number of calls to rcu_try_flip_waitack().
|
||||
|
||||
o "ae1" is the number of times that rcu_try_flip_waitack() found
|
||||
that at least one CPU had not yet acknowledge the new grace period
|
||||
(AKA "counter flip").
|
||||
|
||||
o "a2" is the number of time rcu_try_flip_waitack() found that
|
||||
all CPUs had acknowledged. "a1" should be roughly equal to
|
||||
"ae1" plus "a2". (This particular output was collected on
|
||||
a 128-CPU machine, hence the smaller-than-usual fraction of
|
||||
calls to rcu_try_flip_waitack() finding all CPUs having already
|
||||
acknowledged.)
|
||||
|
||||
o "z1" is the number of calls to rcu_try_flip_waitzero().
|
||||
|
||||
o "ze1" is the number of times that rcu_try_flip_waitzero() found
|
||||
that not all of the old RCU read-side critical sections had
|
||||
completed.
|
||||
|
||||
o "z2" is the number of times that rcu_try_flip_waitzero() finds
|
||||
the sum of the counters equal to zero, in other words, that
|
||||
all of the old RCU read-side critical sections had completed.
|
||||
The value of "z1" should be roughly equal to "ze1" plus
|
||||
"z2".
|
||||
|
||||
o "m1" is the number of calls to rcu_try_flip_waitmb().
|
||||
|
||||
o "me1" is the number of times that rcu_try_flip_waitmb() finds
|
||||
that at least one CPU has not yet executed a memory barrier.
|
||||
|
||||
o "m2" is the number of times that rcu_try_flip_waitmb() finds that
|
||||
all CPUs have executed a memory barrier.
|
||||
The rcutree implementation of RCU provides debugfs trace output that
|
||||
summarizes counters and state. This information is useful for debugging
|
||||
RCU itself, and can sometimes also help to debug abuses of RCU.
|
||||
The following sections describe the debugfs files and formats.
|
||||
|
||||
|
||||
Hierarchical RCU debugfs Files and Formats
|
||||
@ -210,9 +35,10 @@ rcu_bh:
|
||||
6 c=-275 g=-275 pq=1 pqc=-275 qp=0 dt=859/1 dn=0 df=15 of=0 ri=0 ql=0 b=10
|
||||
7 c=-275 g=-275 pq=1 pqc=-275 qp=0 dt=3761/1 dn=0 df=15 of=0 ri=0 ql=0 b=10
|
||||
|
||||
The first section lists the rcu_data structures for rcu, the second for
|
||||
rcu_bh. Each section has one line per CPU, or eight for this 8-CPU system.
|
||||
The fields are as follows:
|
||||
The first section lists the rcu_data structures for rcu_sched, the second
|
||||
for rcu_bh. Note that CONFIG_TREE_PREEMPT_RCU kernels will have an
|
||||
additional section for rcu_preempt. Each section has one line per CPU,
|
||||
or eight for this 8-CPU system. The fields are as follows:
|
||||
|
||||
o The number at the beginning of each line is the CPU number.
|
||||
CPUs numbers followed by an exclamation mark are offline,
|
||||
@ -223,9 +49,9 @@ o The number at the beginning of each line is the CPU number.
|
||||
|
||||
o "c" is the count of grace periods that this CPU believes have
|
||||
completed. CPUs in dynticks idle mode may lag quite a ways
|
||||
behind, for example, CPU 4 under "rcu" above, which has slept
|
||||
through the past 25 RCU grace periods. It is not unusual to
|
||||
see CPUs lagging by thousands of grace periods.
|
||||
behind, for example, CPU 4 under "rcu_sched" above, which has
|
||||
slept through the past 25 RCU grace periods. It is not unusual
|
||||
to see CPUs lagging by thousands of grace periods.
|
||||
|
||||
o "g" is the count of grace periods that this CPU believes have
|
||||
started. Again, CPUs in dynticks idle mode may lag behind.
|
||||
@ -308,8 +134,10 @@ The output of "cat rcu/rcugp" looks as follows:
|
||||
rcu_sched: completed=33062 gpnum=33063
|
||||
rcu_bh: completed=464 gpnum=464
|
||||
|
||||
Again, this output is for both "rcu" and "rcu_bh". The fields are
|
||||
taken from the rcu_state structure, and are as follows:
|
||||
Again, this output is for both "rcu_sched" and "rcu_bh". Note that
|
||||
kernels built with CONFIG_TREE_PREEMPT_RCU will have an additional
|
||||
"rcu_preempt" line. The fields are taken from the rcu_state structure,
|
||||
and are as follows:
|
||||
|
||||
o "completed" is the number of grace periods that have completed.
|
||||
It is comparable to the "c" field from rcu/rcudata in that a
|
||||
@ -324,23 +152,24 @@ o "gpnum" is the number of grace periods that have started. It is
|
||||
If these two fields are equal (as they are for "rcu_bh" above),
|
||||
then there is no grace period in progress, in other words, RCU
|
||||
is idle. On the other hand, if the two fields differ (as they
|
||||
do for "rcu" above), then an RCU grace period is in progress.
|
||||
do for "rcu_sched" above), then an RCU grace period is in progress.
|
||||
|
||||
|
||||
The output of "cat rcu/rcuhier" looks as follows, with very long lines:
|
||||
|
||||
c=6902 g=6903 s=2 jfq=3 j=72c7 nfqs=13142/nfqsng=0(13142) fqlh=6
|
||||
1/1 0:127 ^0
|
||||
3/3 0:35 ^0 0/0 36:71 ^1 0/0 72:107 ^2 0/0 108:127 ^3
|
||||
3/3f 0:5 ^0 2/3 6:11 ^1 0/0 12:17 ^2 0/0 18:23 ^3 0/0 24:29 ^4 0/0 30:35 ^5 0/0 36:41 ^0 0/0 42:47 ^1 0/0 48:53 ^2 0/0 54:59 ^3 0/0 60:65 ^4 0/0 66:71 ^5 0/0 72:77 ^0 0/0 78:83 ^1 0/0 84:89 ^2 0/0 90:95 ^3 0/0 96:101 ^4 0/0 102:107 ^5 0/0 108:113 ^0 0/0 114:119 ^1 0/0 120:125 ^2 0/0 126:127 ^3
|
||||
c=6902 g=6903 s=2 jfq=3 j=72c7 nfqs=13142/nfqsng=0(13142) fqlh=6 oqlen=0
|
||||
1/1 .>. 0:127 ^0
|
||||
3/3 .>. 0:35 ^0 0/0 .>. 36:71 ^1 0/0 .>. 72:107 ^2 0/0 .>. 108:127 ^3
|
||||
3/3f .>. 0:5 ^0 2/3 .>. 6:11 ^1 0/0 .>. 12:17 ^2 0/0 .>. 18:23 ^3 0/0 .>. 24:29 ^4 0/0 .>. 30:35 ^5 0/0 .>. 36:41 ^0 0/0 .>. 42:47 ^1 0/0 .>. 48:53 ^2 0/0 .>. 54:59 ^3 0/0 .>. 60:65 ^4 0/0 .>. 66:71 ^5 0/0 .>. 72:77 ^0 0/0 .>. 78:83 ^1 0/0 .>. 84:89 ^2 0/0 .>. 90:95 ^3 0/0 .>. 96:101 ^4 0/0 .>. 102:107 ^5 0/0 .>. 108:113 ^0 0/0 .>. 114:119 ^1 0/0 .>. 120:125 ^2 0/0 .>. 126:127 ^3
|
||||
rcu_bh:
|
||||
c=-226 g=-226 s=1 jfq=-5701 j=72c7 nfqs=88/nfqsng=0(88) fqlh=0
|
||||
0/1 0:127 ^0
|
||||
0/3 0:35 ^0 0/0 36:71 ^1 0/0 72:107 ^2 0/0 108:127 ^3
|
||||
0/3f 0:5 ^0 0/3 6:11 ^1 0/0 12:17 ^2 0/0 18:23 ^3 0/0 24:29 ^4 0/0 30:35 ^5 0/0 36:41 ^0 0/0 42:47 ^1 0/0 48:53 ^2 0/0 54:59 ^3 0/0 60:65 ^4 0/0 66:71 ^5 0/0 72:77 ^0 0/0 78:83 ^1 0/0 84:89 ^2 0/0 90:95 ^3 0/0 96:101 ^4 0/0 102:107 ^5 0/0 108:113 ^0 0/0 114:119 ^1 0/0 120:125 ^2 0/0 126:127 ^3
|
||||
c=-226 g=-226 s=1 jfq=-5701 j=72c7 nfqs=88/nfqsng=0(88) fqlh=0 oqlen=0
|
||||
0/1 .>. 0:127 ^0
|
||||
0/3 .>. 0:35 ^0 0/0 .>. 36:71 ^1 0/0 .>. 72:107 ^2 0/0 .>. 108:127 ^3
|
||||
0/3f .>. 0:5 ^0 0/3 .>. 6:11 ^1 0/0 .>. 12:17 ^2 0/0 .>. 18:23 ^3 0/0 .>. 24:29 ^4 0/0 .>. 30:35 ^5 0/0 .>. 36:41 ^0 0/0 .>. 42:47 ^1 0/0 .>. 48:53 ^2 0/0 .>. 54:59 ^3 0/0 .>. 60:65 ^4 0/0 .>. 66:71 ^5 0/0 .>. 72:77 ^0 0/0 .>. 78:83 ^1 0/0 .>. 84:89 ^2 0/0 .>. 90:95 ^3 0/0 .>. 96:101 ^4 0/0 .>. 102:107 ^5 0/0 .>. 108:113 ^0 0/0 .>. 114:119 ^1 0/0 .>. 120:125 ^2 0/0 .>. 126:127 ^3
|
||||
|
||||
This is once again split into "rcu" and "rcu_bh" portions. The fields are
|
||||
as follows:
|
||||
This is once again split into "rcu_sched" and "rcu_bh" portions,
|
||||
and CONFIG_TREE_PREEMPT_RCU kernels will again have an additional
|
||||
"rcu_preempt" section. The fields are as follows:
|
||||
|
||||
o "c" is exactly the same as "completed" under rcu/rcugp.
|
||||
|
||||
@ -372,6 +201,11 @@ o "fqlh" is the number of calls to force_quiescent_state() that
|
||||
exited immediately (without even being counted in nfqs above)
|
||||
due to contention on ->fqslock.
|
||||
|
||||
o "oqlen" is the number of callbacks on the "orphan" callback
|
||||
list. RCU callbacks are placed on this list by CPUs going
|
||||
offline, and are "adopted" either by the CPU helping the outgoing
|
||||
CPU or by the next rcu_barrier*() call, whichever comes first.
|
||||
|
||||
o Each element of the form "1/1 0:127 ^0" represents one struct
|
||||
rcu_node. Each line represents one level of the hierarchy, from
|
||||
root to leaves. It is best to think of the rcu_data structures
|
||||
@ -379,7 +213,7 @@ o Each element of the form "1/1 0:127 ^0" represents one struct
|
||||
might be either one, two, or three levels of rcu_node structures,
|
||||
depending on the relationship between CONFIG_RCU_FANOUT and
|
||||
CONFIG_NR_CPUS.
|
||||
|
||||
|
||||
o The numbers separated by the "/" are the qsmask followed
|
||||
by the qsmaskinit. The qsmask will have one bit
|
||||
set for each entity in the next lower level that
|
||||
@ -389,10 +223,19 @@ o Each element of the form "1/1 0:127 ^0" represents one struct
|
||||
The value of qsmaskinit is assigned to that of qsmask
|
||||
at the beginning of each grace period.
|
||||
|
||||
For example, for "rcu", the qsmask of the first entry
|
||||
of the lowest level is 0x14, meaning that we are still
|
||||
waiting for CPUs 2 and 4 to check in for the current
|
||||
grace period.
|
||||
For example, for "rcu_sched", the qsmask of the first
|
||||
entry of the lowest level is 0x14, meaning that we
|
||||
are still waiting for CPUs 2 and 4 to check in for the
|
||||
current grace period.
|
||||
|
||||
o The characters separated by the ">" indicate the state
|
||||
of the blocked-tasks lists. A "T" preceding the ">"
|
||||
indicates that at least one task blocked in an RCU
|
||||
read-side critical section blocks the current grace
|
||||
period, while a "." preceding the ">" indicates otherwise.
|
||||
The character following the ">" indicates similarly for
|
||||
the next grace period. A "T" should appear in this
|
||||
field only for rcu-preempt.
|
||||
|
||||
o The numbers separated by the ":" are the range of CPUs
|
||||
served by this struct rcu_node. This can be helpful
|
||||
@ -431,8 +274,9 @@ rcu_bh:
|
||||
6 np=120834 qsp=9902 cbr=0 cng=0 gpc=6 gps=3 nf=2 nn=110921
|
||||
7 np=144888 qsp=26336 cbr=0 cng=0 gpc=8 gps=2 nf=0 nn=118542
|
||||
|
||||
As always, this is once again split into "rcu" and "rcu_bh" portions.
|
||||
The fields are as follows:
|
||||
As always, this is once again split into "rcu_sched" and "rcu_bh"
|
||||
portions, with CONFIG_TREE_PREEMPT_RCU kernels having an additional
|
||||
"rcu_preempt" section. The fields are as follows:
|
||||
|
||||
o "np" is the number of times that __rcu_pending() has been invoked
|
||||
for the corresponding flavor of RCU.
|
||||
|
@ -830,7 +830,7 @@ sched: Critical sections Grace period Barrier
|
||||
SRCU: Critical sections Grace period Barrier
|
||||
|
||||
srcu_read_lock synchronize_srcu N/A
|
||||
srcu_read_unlock
|
||||
srcu_read_unlock synchronize_srcu_expedited
|
||||
|
||||
SRCU: Initialization/cleanup
|
||||
init_srcu_struct
|
||||
|
@ -65,6 +65,7 @@ aicdb.h*
|
||||
asm-offsets.h
|
||||
asm_offsets.h
|
||||
autoconf.h*
|
||||
av_permissions.h
|
||||
bbootsect
|
||||
bin2c
|
||||
binkernel.spec
|
||||
@ -95,12 +96,14 @@ docproc
|
||||
elf2ecoff
|
||||
elfconfig.h*
|
||||
fixdep
|
||||
flask.h
|
||||
fore200e_mkfirm
|
||||
fore200e_pca_fw.c*
|
||||
gconf
|
||||
gen-devlist
|
||||
gen_crc32table
|
||||
gen_init_cpio
|
||||
genheaders
|
||||
genksyms
|
||||
*_gray256.c
|
||||
ihex2fw
|
||||
|
@ -6,6 +6,21 @@ be removed from this file.
|
||||
|
||||
---------------------------
|
||||
|
||||
What: USER_SCHED
|
||||
When: 2.6.34
|
||||
|
||||
Why: USER_SCHED was implemented as a proof of concept for group scheduling.
|
||||
The effect of USER_SCHED can already be achieved from userspace with
|
||||
the help of libcgroup. The removal of USER_SCHED will also simplify
|
||||
the scheduler code with the removal of one major ifdef. There are also
|
||||
issues USER_SCHED has with USER_NS. A decision was taken not to fix
|
||||
those and instead remove USER_SCHED. Also new group scheduling
|
||||
features will not be implemented for USER_SCHED.
|
||||
|
||||
Who: Dhaval Giani <dhaval@linux.vnet.ibm.com>
|
||||
|
||||
---------------------------
|
||||
|
||||
What: PRISM54
|
||||
When: 2.6.34
|
||||
|
||||
|
@ -1072,7 +1072,8 @@ second). The meanings of the columns are as follows, from left to right:
|
||||
- irq: servicing interrupts
|
||||
- softirq: servicing softirqs
|
||||
- steal: involuntary wait
|
||||
- guest: running a guest
|
||||
- guest: running a normal guest
|
||||
- guest_nice: running a niced guest
|
||||
|
||||
The "intr" line gives counts of interrupts serviced since boot time, for each
|
||||
of the possible system interrupts. The first column is the total of all
|
||||
|
@ -85,7 +85,6 @@ parameter is applicable:
|
||||
PPT Parallel port support is enabled.
|
||||
PS2 Appropriate PS/2 support is enabled.
|
||||
RAM RAM disk support is enabled.
|
||||
ROOTPLUG The example Root Plug LSM is enabled.
|
||||
S390 S390 architecture is enabled.
|
||||
SCSI Appropriate SCSI support is enabled.
|
||||
A lot of drivers has their options described inside of
|
||||
@ -345,6 +344,15 @@ and is between 256 and 4096 characters. It is defined in the file
|
||||
Change the amount of debugging information output
|
||||
when initialising the APIC and IO-APIC components.
|
||||
|
||||
show_lapic= [APIC,X86] Advanced Programmable Interrupt Controller
|
||||
Limit apic dumping. The parameter defines the maximal
|
||||
number of local apics being dumped. Also it is possible
|
||||
to set it to "all" by meaning -- no limit here.
|
||||
Format: { 1 (default) | 2 | ... | all }.
|
||||
The parameter valid if only apic=debug or
|
||||
apic=verbose is specified.
|
||||
Example: apic=debug show_lapic=all
|
||||
|
||||
apm= [APM] Advanced Power Management
|
||||
See header of arch/x86/kernel/apm_32.c.
|
||||
|
||||
@ -779,6 +787,13 @@ and is between 256 and 4096 characters. It is defined in the file
|
||||
by the set_ftrace_notrace file in the debugfs
|
||||
tracing directory.
|
||||
|
||||
ftrace_graph_filter=[function-list]
|
||||
[FTRACE] Limit the top level callers functions traced
|
||||
by the function graph tracer at boot up.
|
||||
function-list is a comma separated list of functions
|
||||
that can be changed at run time by the
|
||||
set_graph_function file in the debugfs tracing directory.
|
||||
|
||||
gamecon.map[2|3]=
|
||||
[HW,JOY] Multisystem joystick and NES/SNES/PSX pad
|
||||
support via parallel port (up to 5 devices per port)
|
||||
@ -2032,8 +2047,15 @@ and is between 256 and 4096 characters. It is defined in the file
|
||||
|
||||
print-fatal-signals=
|
||||
[KNL] debug: print fatal signals
|
||||
print-fatal-signals=1: print segfault info to
|
||||
the kernel console.
|
||||
|
||||
If enabled, warn about various signal handling
|
||||
related application anomalies: too many signals,
|
||||
too many POSIX.1 timers, fatal signals causing a
|
||||
coredump - etc.
|
||||
|
||||
If you hit the warning due to signal overflow,
|
||||
you might want to try "ulimit -i unlimited".
|
||||
|
||||
default: off.
|
||||
|
||||
printk.time= Show timing data prefixed to each printk message line
|
||||
@ -2164,15 +2186,6 @@ and is between 256 and 4096 characters. It is defined in the file
|
||||
Useful for devices that are detected asynchronously
|
||||
(e.g. USB and MMC devices).
|
||||
|
||||
root_plug.vendor_id=
|
||||
[ROOTPLUG] Override the default vendor ID
|
||||
|
||||
root_plug.product_id=
|
||||
[ROOTPLUG] Override the default product ID
|
||||
|
||||
root_plug.debug=
|
||||
[ROOTPLUG] Enable debugging output
|
||||
|
||||
rw [KNL] Mount root device read-write on boot
|
||||
|
||||
S [KNL] Run init in single mode
|
||||
@ -2182,6 +2195,8 @@ and is between 256 and 4096 characters. It is defined in the file
|
||||
|
||||
sbni= [NET] Granch SBNI12 leased line adapter
|
||||
|
||||
sched_debug [KNL] Enables verbose scheduler debug messages.
|
||||
|
||||
sc1200wdt= [HW,WDT] SC1200 WDT (watchdog) driver
|
||||
Format: <io>[,<timeout>[,<isapnp>]]
|
||||
|
||||
|
@ -1,5 +1,17 @@
|
||||
This file details changes in 2.6 which affect PCMCIA card driver authors:
|
||||
|
||||
* no cs_error / CS_CHECK / CONFIG_PCMCIA_DEBUG (as of 2.6.33)
|
||||
Instead of the cs_error() callback or the CS_CHECK() macro, please use
|
||||
Linux-style checking of return values, and -- if necessary -- debug
|
||||
messages using "dev_dbg()" or "pr_debug()".
|
||||
|
||||
* New CIS tuple access (as of 2.6.33)
|
||||
Instead of pcmcia_get_{first,next}_tuple(), pcmcia_get_tuple_data() and
|
||||
pcmcia_parse_tuple(), a driver shall use "pcmcia_get_tuple()" if it is
|
||||
only interested in one (raw) tuple, or "pcmcia_loop_tuple()" if it is
|
||||
interested in all tuples of one type. To decode the MAC from CISTPL_FUNCE,
|
||||
a new helper "pcmcia_get_mac_from_cis()" was added.
|
||||
|
||||
* New configuration loop helper (as of 2.6.28)
|
||||
By calling pcmcia_loop_config(), a driver can iterate over all available
|
||||
configuration options. During a driver's probe() phase, one doesn't need
|
||||
|
@ -279,9 +279,9 @@ The slow-work thread pool has a number of configurables:
|
||||
VIEWING EXECUTING AND QUEUED ITEMS
|
||||
==================================
|
||||
|
||||
If CONFIG_SLOW_WORK_PROC is enabled, a proc file is made available:
|
||||
If CONFIG_SLOW_WORK_DEBUG is enabled, a debugfs file is made available:
|
||||
|
||||
/proc/slow_work_rq
|
||||
/sys/kernel/debug/slow_work/runqueue
|
||||
|
||||
through which the list of work items being executed and the queues of items to
|
||||
be executed may be viewed. The owner of a work item is given the chance to
|
||||
|
@ -213,10 +213,19 @@ If you can't trace NMI functions, then skip this option.
|
||||
<details to be filled>
|
||||
|
||||
|
||||
HAVE_FTRACE_SYSCALLS
|
||||
HAVE_SYSCALL_TRACEPOINTS
|
||||
---------------------
|
||||
|
||||
<details to be filled>
|
||||
You need very few things to get the syscalls tracing in an arch.
|
||||
|
||||
- Have a NR_syscalls variable in <asm/unistd.h> that provides the number
|
||||
of syscalls supported by the arch.
|
||||
- Implement arch_syscall_addr() that resolves a syscall address from a
|
||||
syscall number.
|
||||
- Support the TIF_SYSCALL_TRACEPOINT thread flags
|
||||
- Put the trace_sys_enter() and trace_sys_exit() tracepoints calls from ptrace
|
||||
in the ptrace syscalls tracing path.
|
||||
- Tag this arch as HAVE_SYSCALL_TRACEPOINTS.
|
||||
|
||||
|
||||
HAVE_FTRACE_MCOUNT_RECORD
|
||||
|
149
Documentation/trace/kprobetrace.txt
Normal file
149
Documentation/trace/kprobetrace.txt
Normal file
@ -0,0 +1,149 @@
|
||||
Kprobe-based Event Tracing
|
||||
==========================
|
||||
|
||||
Documentation is written by Masami Hiramatsu
|
||||
|
||||
|
||||
Overview
|
||||
--------
|
||||
These events are similar to tracepoint based events. Instead of Tracepoint,
|
||||
this is based on kprobes (kprobe and kretprobe). So it can probe wherever
|
||||
kprobes can probe (this means, all functions body except for __kprobes
|
||||
functions). Unlike the Tracepoint based event, this can be added and removed
|
||||
dynamically, on the fly.
|
||||
|
||||
To enable this feature, build your kernel with CONFIG_KPROBE_TRACING=y.
|
||||
|
||||
Similar to the events tracer, this doesn't need to be activated via
|
||||
current_tracer. Instead of that, add probe points via
|
||||
/sys/kernel/debug/tracing/kprobe_events, and enable it via
|
||||
/sys/kernel/debug/tracing/events/kprobes/<EVENT>/enabled.
|
||||
|
||||
|
||||
Synopsis of kprobe_events
|
||||
-------------------------
|
||||
p[:[GRP/]EVENT] SYMBOL[+offs]|MEMADDR [FETCHARGS] : Set a probe
|
||||
r[:[GRP/]EVENT] SYMBOL[+0] [FETCHARGS] : Set a return probe
|
||||
|
||||
GRP : Group name. If omitted, use "kprobes" for it.
|
||||
EVENT : Event name. If omitted, the event name is generated
|
||||
based on SYMBOL+offs or MEMADDR.
|
||||
SYMBOL[+offs] : Symbol+offset where the probe is inserted.
|
||||
MEMADDR : Address where the probe is inserted.
|
||||
|
||||
FETCHARGS : Arguments. Each probe can have up to 128 args.
|
||||
%REG : Fetch register REG
|
||||
@ADDR : Fetch memory at ADDR (ADDR should be in kernel)
|
||||
@SYM[+|-offs] : Fetch memory at SYM +|- offs (SYM should be a data symbol)
|
||||
$stackN : Fetch Nth entry of stack (N >= 0)
|
||||
$stack : Fetch stack address.
|
||||
$argN : Fetch function argument. (N >= 0)(*)
|
||||
$retval : Fetch return value.(**)
|
||||
+|-offs(FETCHARG) : Fetch memory at FETCHARG +|- offs address.(***)
|
||||
NAME=FETCHARG: Set NAME as the argument name of FETCHARG.
|
||||
|
||||
(*) aN may not correct on asmlinkaged functions and at the middle of
|
||||
function body.
|
||||
(**) only for return probe.
|
||||
(***) this is useful for fetching a field of data structures.
|
||||
|
||||
|
||||
Per-Probe Event Filtering
|
||||
-------------------------
|
||||
Per-probe event filtering feature allows you to set different filter on each
|
||||
probe and gives you what arguments will be shown in trace buffer. If an event
|
||||
name is specified right after 'p:' or 'r:' in kprobe_events, it adds an event
|
||||
under tracing/events/kprobes/<EVENT>, at the directory you can see 'id',
|
||||
'enabled', 'format' and 'filter'.
|
||||
|
||||
enabled:
|
||||
You can enable/disable the probe by writing 1 or 0 on it.
|
||||
|
||||
format:
|
||||
This shows the format of this probe event.
|
||||
|
||||
filter:
|
||||
You can write filtering rules of this event.
|
||||
|
||||
id:
|
||||
This shows the id of this probe event.
|
||||
|
||||
|
||||
Event Profiling
|
||||
---------------
|
||||
You can check the total number of probe hits and probe miss-hits via
|
||||
/sys/kernel/debug/tracing/kprobe_profile.
|
||||
The first column is event name, the second is the number of probe hits,
|
||||
the third is the number of probe miss-hits.
|
||||
|
||||
|
||||
Usage examples
|
||||
--------------
|
||||
To add a probe as a new event, write a new definition to kprobe_events
|
||||
as below.
|
||||
|
||||
echo p:myprobe do_sys_open dfd=$arg0 filename=$arg1 flags=$arg2 mode=$arg3 > /sys/kernel/debug/tracing/kprobe_events
|
||||
|
||||
This sets a kprobe on the top of do_sys_open() function with recording
|
||||
1st to 4th arguments as "myprobe" event. As this example shows, users can
|
||||
choose more familiar names for each arguments.
|
||||
|
||||
echo r:myretprobe do_sys_open $retval >> /sys/kernel/debug/tracing/kprobe_events
|
||||
|
||||
This sets a kretprobe on the return point of do_sys_open() function with
|
||||
recording return value as "myretprobe" event.
|
||||
You can see the format of these events via
|
||||
/sys/kernel/debug/tracing/events/kprobes/<EVENT>/format.
|
||||
|
||||
cat /sys/kernel/debug/tracing/events/kprobes/myprobe/format
|
||||
name: myprobe
|
||||
ID: 75
|
||||
format:
|
||||
field:unsigned short common_type; offset:0; size:2;
|
||||
field:unsigned char common_flags; offset:2; size:1;
|
||||
field:unsigned char common_preempt_count; offset:3; size:1;
|
||||
field:int common_pid; offset:4; size:4;
|
||||
field:int common_tgid; offset:8; size:4;
|
||||
|
||||
field: unsigned long ip; offset:16;tsize:8;
|
||||
field: int nargs; offset:24;tsize:4;
|
||||
field: unsigned long dfd; offset:32;tsize:8;
|
||||
field: unsigned long filename; offset:40;tsize:8;
|
||||
field: unsigned long flags; offset:48;tsize:8;
|
||||
field: unsigned long mode; offset:56;tsize:8;
|
||||
|
||||
print fmt: "(%lx) dfd=%lx filename=%lx flags=%lx mode=%lx", REC->ip, REC->dfd, REC->filename, REC->flags, REC->mode
|
||||
|
||||
|
||||
You can see that the event has 4 arguments as in the expressions you specified.
|
||||
|
||||
echo > /sys/kernel/debug/tracing/kprobe_events
|
||||
|
||||
This clears all probe points.
|
||||
|
||||
Right after definition, each event is disabled by default. For tracing these
|
||||
events, you need to enable it.
|
||||
|
||||
echo 1 > /sys/kernel/debug/tracing/events/kprobes/myprobe/enable
|
||||
echo 1 > /sys/kernel/debug/tracing/events/kprobes/myretprobe/enable
|
||||
|
||||
And you can see the traced information via /sys/kernel/debug/tracing/trace.
|
||||
|
||||
cat /sys/kernel/debug/tracing/trace
|
||||
# tracer: nop
|
||||
#
|
||||
# TASK-PID CPU# TIMESTAMP FUNCTION
|
||||
# | | | | |
|
||||
<...>-1447 [001] 1038282.286875: myprobe: (do_sys_open+0x0/0xd6) dfd=3 filename=7fffd1ec4440 flags=8000 mode=0
|
||||
<...>-1447 [001] 1038282.286878: myretprobe: (sys_openat+0xc/0xe <- do_sys_open) $retval=fffffffffffffffe
|
||||
<...>-1447 [001] 1038282.286885: myprobe: (do_sys_open+0x0/0xd6) dfd=ffffff9c filename=40413c flags=8000 mode=1b6
|
||||
<...>-1447 [001] 1038282.286915: myretprobe: (sys_open+0x1b/0x1d <- do_sys_open) $retval=3
|
||||
<...>-1447 [001] 1038282.286969: myprobe: (do_sys_open+0x0/0xd6) dfd=ffffff9c filename=4041c6 flags=98800 mode=10
|
||||
<...>-1447 [001] 1038282.286976: myretprobe: (sys_open+0x1b/0x1d <- do_sys_open) $retval=3
|
||||
|
||||
|
||||
Each line shows when the kernel hits an event, and <- SYMBOL means kernel
|
||||
returns from SYMBOL(e.g. "sys_open+0x1b/0x1d <- do_sys_open" means kernel
|
||||
returns from do_sys_open to sys_open+0x1b).
|
||||
|
||||
|
@ -3045,11 +3045,8 @@ S: Maintained
|
||||
F: fs/autofs4/
|
||||
|
||||
KERNEL BUILD
|
||||
M: Sam Ravnborg <sam@ravnborg.org>
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/sam/kbuild-next.git
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/sam/kbuild-fixes.git
|
||||
L: linux-kbuild@vger.kernel.org
|
||||
S: Maintained
|
||||
S: Orphan
|
||||
F: Documentation/kbuild/
|
||||
F: Makefile
|
||||
F: scripts/Makefile.*
|
||||
|
3
Makefile
3
Makefile
@ -1,7 +1,7 @@
|
||||
VERSION = 2
|
||||
PATCHLEVEL = 6
|
||||
SUBLEVEL = 32
|
||||
EXTRAVERSION = -rc8
|
||||
EXTRAVERSION =
|
||||
NAME = Man-Eating Seals of Antiquity
|
||||
|
||||
# *DOCUMENTATION*
|
||||
@ -379,6 +379,7 @@ export RCS_TAR_IGNORE := --exclude SCCS --exclude BitKeeper --exclude .svn --exc
|
||||
PHONY += scripts_basic
|
||||
scripts_basic:
|
||||
$(Q)$(MAKE) $(build)=scripts/basic
|
||||
$(Q)rm -f .tmp_quiet_recordmcount
|
||||
|
||||
# To avoid any implicit rule to kick in, define an empty command.
|
||||
scripts/basic/%: scripts_basic ;
|
||||
|
@ -126,4 +126,11 @@ config HAVE_DMA_API_DEBUG
|
||||
config HAVE_DEFAULT_NO_SPIN_MUTEXES
|
||||
bool
|
||||
|
||||
config HAVE_HW_BREAKPOINT
|
||||
bool
|
||||
depends on HAVE_PERF_EVENTS
|
||||
select ANON_INODES
|
||||
select PERF_EVENTS
|
||||
|
||||
|
||||
source "kernel/gcov/Kconfig"
|
||||
|
@ -61,21 +61,24 @@ register struct thread_info *__current_thread_info __asm__("$8");
|
||||
/*
|
||||
* Thread information flags:
|
||||
* - these are process state flags and used from assembly
|
||||
* - pending work-to-be-done flags come first to fit in and immediate operand.
|
||||
* - pending work-to-be-done flags come first and must be assigned to be
|
||||
* within bits 0 to 7 to fit in and immediate operand.
|
||||
* - ALPHA_UAC_SHIFT below must be kept consistent with the unaligned
|
||||
* control flags.
|
||||
*
|
||||
* TIF_SYSCALL_TRACE is known to be 0 via blbs.
|
||||
*/
|
||||
#define TIF_SYSCALL_TRACE 0 /* syscall trace active */
|
||||
#define TIF_SIGPENDING 1 /* signal pending */
|
||||
#define TIF_NEED_RESCHED 2 /* rescheduling necessary */
|
||||
#define TIF_POLLING_NRFLAG 3 /* poll_idle is polling NEED_RESCHED */
|
||||
#define TIF_DIE_IF_KERNEL 4 /* dik recursion lock */
|
||||
#define TIF_UAC_NOPRINT 5 /* see sysinfo.h */
|
||||
#define TIF_UAC_NOFIX 6
|
||||
#define TIF_UAC_SIGBUS 7
|
||||
#define TIF_MEMDIE 8
|
||||
#define TIF_RESTORE_SIGMASK 9 /* restore signal mask in do_signal */
|
||||
#define TIF_NOTIFY_RESUME 10 /* callback before returning to user */
|
||||
#define TIF_NOTIFY_RESUME 1 /* callback before returning to user */
|
||||
#define TIF_SIGPENDING 2 /* signal pending */
|
||||
#define TIF_NEED_RESCHED 3 /* rescheduling necessary */
|
||||
#define TIF_POLLING_NRFLAG 8 /* poll_idle is polling NEED_RESCHED */
|
||||
#define TIF_DIE_IF_KERNEL 9 /* dik recursion lock */
|
||||
#define TIF_UAC_NOPRINT 10 /* see sysinfo.h */
|
||||
#define TIF_UAC_NOFIX 11
|
||||
#define TIF_UAC_SIGBUS 12
|
||||
#define TIF_MEMDIE 13
|
||||
#define TIF_RESTORE_SIGMASK 14 /* restore signal mask in do_signal */
|
||||
#define TIF_FREEZE 16 /* is freezing for suspend */
|
||||
|
||||
#define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE)
|
||||
@ -94,7 +97,7 @@ register struct thread_info *__current_thread_info __asm__("$8");
|
||||
#define _TIF_ALLWORK_MASK (_TIF_WORK_MASK \
|
||||
| _TIF_SYSCALL_TRACE)
|
||||
|
||||
#define ALPHA_UAC_SHIFT 6
|
||||
#define ALPHA_UAC_SHIFT 10
|
||||
#define ALPHA_UAC_MASK (1 << TIF_UAC_NOPRINT | 1 << TIF_UAC_NOFIX | \
|
||||
1 << TIF_UAC_SIGBUS)
|
||||
|
||||
|
@ -1103,6 +1103,8 @@ marvel_agp_info(void)
|
||||
* Allocate the info structure.
|
||||
*/
|
||||
agp = kmalloc(sizeof(*agp), GFP_KERNEL);
|
||||
if (!agp)
|
||||
return NULL;
|
||||
|
||||
/*
|
||||
* Fill it in.
|
||||
|
@ -757,6 +757,8 @@ titan_agp_info(void)
|
||||
* Allocate the info structure.
|
||||
*/
|
||||
agp = kmalloc(sizeof(*agp), GFP_KERNEL);
|
||||
if (!agp)
|
||||
return NULL;
|
||||
|
||||
/*
|
||||
* Fill it in.
|
||||
|
@ -92,7 +92,7 @@ show_interrupts(struct seq_file *p, void *v)
|
||||
for_each_online_cpu(j)
|
||||
seq_printf(p, "%10u ", kstat_irqs_cpu(irq, j));
|
||||
#endif
|
||||
seq_printf(p, " %14s", irq_desc[irq].chip->typename);
|
||||
seq_printf(p, " %14s", irq_desc[irq].chip->name);
|
||||
seq_printf(p, " %c%s",
|
||||
(action->flags & IRQF_DISABLED)?'+':' ',
|
||||
action->name);
|
||||
|
@ -228,7 +228,7 @@ struct irqaction timer_irqaction = {
|
||||
};
|
||||
|
||||
static struct irq_chip rtc_irq_type = {
|
||||
.typename = "RTC",
|
||||
.name = "RTC",
|
||||
.startup = rtc_startup,
|
||||
.shutdown = rtc_enable_disable,
|
||||
.enable = rtc_enable_disable,
|
||||
|
@ -84,7 +84,7 @@ i8259a_end_irq(unsigned int irq)
|
||||
}
|
||||
|
||||
struct irq_chip i8259a_irq_type = {
|
||||
.typename = "XT-PIC",
|
||||
.name = "XT-PIC",
|
||||
.startup = i8259a_startup_irq,
|
||||
.shutdown = i8259a_disable_irq,
|
||||
.enable = i8259a_enable_irq,
|
||||
|
@ -71,7 +71,7 @@ pyxis_mask_and_ack_irq(unsigned int irq)
|
||||
}
|
||||
|
||||
static struct irq_chip pyxis_irq_type = {
|
||||
.typename = "PYXIS",
|
||||
.name = "PYXIS",
|
||||
.startup = pyxis_startup_irq,
|
||||
.shutdown = pyxis_disable_irq,
|
||||
.enable = pyxis_enable_irq,
|
||||
|
@ -49,7 +49,7 @@ srm_end_irq(unsigned int irq)
|
||||
|
||||
/* Handle interrupts from the SRM, assuming no additional weirdness. */
|
||||
static struct irq_chip srm_irq_type = {
|
||||
.typename = "SRM",
|
||||
.name = "SRM",
|
||||
.startup = srm_startup_irq,
|
||||
.shutdown = srm_disable_irq,
|
||||
.enable = srm_enable_irq,
|
||||
|
@ -90,7 +90,7 @@ alcor_end_irq(unsigned int irq)
|
||||
}
|
||||
|
||||
static struct irq_chip alcor_irq_type = {
|
||||
.typename = "ALCOR",
|
||||
.name = "ALCOR",
|
||||
.startup = alcor_startup_irq,
|
||||
.shutdown = alcor_disable_irq,
|
||||
.enable = alcor_enable_irq,
|
||||
|
@ -72,7 +72,7 @@ cabriolet_end_irq(unsigned int irq)
|
||||
}
|
||||
|
||||
static struct irq_chip cabriolet_irq_type = {
|
||||
.typename = "CABRIOLET",
|
||||
.name = "CABRIOLET",
|
||||
.startup = cabriolet_startup_irq,
|
||||
.shutdown = cabriolet_disable_irq,
|
||||
.enable = cabriolet_enable_irq,
|
||||
|
@ -199,7 +199,7 @@ clipper_set_affinity(unsigned int irq, const struct cpumask *affinity)
|
||||
}
|
||||
|
||||
static struct irq_chip dp264_irq_type = {
|
||||
.typename = "DP264",
|
||||
.name = "DP264",
|
||||
.startup = dp264_startup_irq,
|
||||
.shutdown = dp264_disable_irq,
|
||||
.enable = dp264_enable_irq,
|
||||
@ -210,7 +210,7 @@ static struct irq_chip dp264_irq_type = {
|
||||
};
|
||||
|
||||
static struct irq_chip clipper_irq_type = {
|
||||
.typename = "CLIPPER",
|
||||
.name = "CLIPPER",
|
||||
.startup = clipper_startup_irq,
|
||||
.shutdown = clipper_disable_irq,
|
||||
.enable = clipper_enable_irq,
|
||||
|
@ -70,7 +70,7 @@ eb64p_end_irq(unsigned int irq)
|
||||
}
|
||||
|
||||
static struct irq_chip eb64p_irq_type = {
|
||||
.typename = "EB64P",
|
||||
.name = "EB64P",
|
||||
.startup = eb64p_startup_irq,
|
||||
.shutdown = eb64p_disable_irq,
|
||||
.enable = eb64p_enable_irq,
|
||||
|
@ -81,7 +81,7 @@ eiger_end_irq(unsigned int irq)
|
||||
}
|
||||
|
||||
static struct irq_chip eiger_irq_type = {
|
||||
.typename = "EIGER",
|
||||
.name = "EIGER",
|
||||
.startup = eiger_startup_irq,
|
||||
.shutdown = eiger_disable_irq,
|
||||
.enable = eiger_enable_irq,
|
||||
|
@ -119,7 +119,7 @@ jensen_local_end(unsigned int irq)
|
||||
}
|
||||
|
||||
static struct irq_chip jensen_local_irq_type = {
|
||||
.typename = "LOCAL",
|
||||
.name = "LOCAL",
|
||||
.startup = jensen_local_startup,
|
||||
.shutdown = jensen_local_shutdown,
|
||||
.enable = jensen_local_enable,
|
||||
|
@ -170,7 +170,7 @@ marvel_irq_noop_return(unsigned int irq)
|
||||
}
|
||||
|
||||
static struct irq_chip marvel_legacy_irq_type = {
|
||||
.typename = "LEGACY",
|
||||
.name = "LEGACY",
|
||||
.startup = marvel_irq_noop_return,
|
||||
.shutdown = marvel_irq_noop,
|
||||
.enable = marvel_irq_noop,
|
||||
@ -180,7 +180,7 @@ static struct irq_chip marvel_legacy_irq_type = {
|
||||
};
|
||||
|
||||
static struct irq_chip io7_lsi_irq_type = {
|
||||
.typename = "LSI",
|
||||
.name = "LSI",
|
||||
.startup = io7_startup_irq,
|
||||
.shutdown = io7_disable_irq,
|
||||
.enable = io7_enable_irq,
|
||||
@ -190,7 +190,7 @@ static struct irq_chip io7_lsi_irq_type = {
|
||||
};
|
||||
|
||||
static struct irq_chip io7_msi_irq_type = {
|
||||
.typename = "MSI",
|
||||
.name = "MSI",
|
||||
.startup = io7_startup_irq,
|
||||
.shutdown = io7_disable_irq,
|
||||
.enable = io7_enable_irq,
|
||||
|
@ -69,7 +69,7 @@ mikasa_end_irq(unsigned int irq)
|
||||
}
|
||||
|
||||
static struct irq_chip mikasa_irq_type = {
|
||||
.typename = "MIKASA",
|
||||
.name = "MIKASA",
|
||||
.startup = mikasa_startup_irq,
|
||||
.shutdown = mikasa_disable_irq,
|
||||
.enable = mikasa_enable_irq,
|
||||
|
@ -74,7 +74,7 @@ noritake_end_irq(unsigned int irq)
|
||||
}
|
||||
|
||||
static struct irq_chip noritake_irq_type = {
|
||||
.typename = "NORITAKE",
|
||||
.name = "NORITAKE",
|
||||
.startup = noritake_startup_irq,
|
||||
.shutdown = noritake_disable_irq,
|
||||
.enable = noritake_enable_irq,
|
||||
|
@ -136,7 +136,7 @@ rawhide_end_irq(unsigned int irq)
|
||||
}
|
||||
|
||||
static struct irq_chip rawhide_irq_type = {
|
||||
.typename = "RAWHIDE",
|
||||
.name = "RAWHIDE",
|
||||
.startup = rawhide_startup_irq,
|
||||
.shutdown = rawhide_disable_irq,
|
||||
.enable = rawhide_enable_irq,
|
||||
|
@ -66,7 +66,7 @@ ruffian_init_irq(void)
|
||||
common_init_isa_dma();
|
||||
}
|
||||
|
||||
#define RUFFIAN_LATCH ((PIT_TICK_RATE + HZ / 2) / HZ)
|
||||
#define RUFFIAN_LATCH DIV_ROUND_CLOSEST(PIT_TICK_RATE, HZ)
|
||||
|
||||
static void __init
|
||||
ruffian_init_rtc(void)
|
||||
|
@ -73,7 +73,7 @@ rx164_end_irq(unsigned int irq)
|
||||
}
|
||||
|
||||
static struct irq_chip rx164_irq_type = {
|
||||
.typename = "RX164",
|
||||
.name = "RX164",
|
||||
.startup = rx164_startup_irq,
|
||||
.shutdown = rx164_disable_irq,
|
||||
.enable = rx164_enable_irq,
|
||||
|
@ -502,7 +502,7 @@ sable_lynx_mask_and_ack_irq(unsigned int irq)
|
||||
}
|
||||
|
||||
static struct irq_chip sable_lynx_irq_type = {
|
||||
.typename = "SABLE/LYNX",
|
||||
.name = "SABLE/LYNX",
|
||||
.startup = sable_lynx_startup_irq,
|
||||
.shutdown = sable_lynx_disable_irq,
|
||||
.enable = sable_lynx_enable_irq,
|
||||
|
@ -75,7 +75,7 @@ takara_end_irq(unsigned int irq)
|
||||
}
|
||||
|
||||
static struct irq_chip takara_irq_type = {
|
||||
.typename = "TAKARA",
|
||||
.name = "TAKARA",
|
||||
.startup = takara_startup_irq,
|
||||
.shutdown = takara_disable_irq,
|
||||
.enable = takara_enable_irq,
|
||||
|
@ -195,7 +195,7 @@ init_titan_irqs(struct irq_chip * ops, int imin, int imax)
|
||||
}
|
||||
|
||||
static struct irq_chip titan_irq_type = {
|
||||
.typename = "TITAN",
|
||||
.name = "TITAN",
|
||||
.startup = titan_startup_irq,
|
||||
.shutdown = titan_disable_irq,
|
||||
.enable = titan_enable_irq,
|
||||
|
@ -158,7 +158,7 @@ wildfire_end_irq(unsigned int irq)
|
||||
}
|
||||
|
||||
static struct irq_chip wildfire_irq_type = {
|
||||
.typename = "WILDFIRE",
|
||||
.name = "WILDFIRE",
|
||||
.startup = wildfire_startup_irq,
|
||||
.shutdown = wildfire_disable_irq,
|
||||
.enable = wildfire_enable_irq,
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -53,23 +53,23 @@ config SA1100_COLLIE
|
||||
|
||||
config SA1100_H3100
|
||||
bool "Compaq iPAQ H3100"
|
||||
select HTC_EGPIO
|
||||
help
|
||||
Say Y here if you intend to run this kernel on the Compaq iPAQ
|
||||
H3100 handheld computer. Information about this machine and the
|
||||
Linux port to this machine can be found at:
|
||||
|
||||
<http://www.handhelds.org/Compaq/index.html#iPAQ_H3100>
|
||||
<http://www.compaq.com/products/handhelds/pocketpc/>
|
||||
|
||||
config SA1100_H3600
|
||||
bool "Compaq iPAQ H3600/H3700"
|
||||
select HTC_EGPIO
|
||||
help
|
||||
Say Y here if you intend to run this kernel on the Compaq iPAQ
|
||||
H3600 handheld computer. Information about this machine and the
|
||||
Linux port to this machine can be found at:
|
||||
|
||||
<http://www.handhelds.org/Compaq/index.html#iPAQ_H3600>
|
||||
<http://www.compaq.com/products/handhelds/pocketpc/>
|
||||
|
||||
config SA1100_BADGE4
|
||||
bool "HP Labs BadgePAD 4"
|
||||
|
@ -25,8 +25,8 @@ led-$(CONFIG_SA1100_CERF) += leds-cerf.o
|
||||
|
||||
obj-$(CONFIG_SA1100_COLLIE) += collie.o
|
||||
|
||||
obj-$(CONFIG_SA1100_H3100) += h3600.o
|
||||
obj-$(CONFIG_SA1100_H3600) += h3600.o
|
||||
obj-$(CONFIG_SA1100_H3100) += h3100.o h3xxx.o
|
||||
obj-$(CONFIG_SA1100_H3600) += h3600.o h3xxx.o
|
||||
|
||||
obj-$(CONFIG_SA1100_HACKKIT) += hackkit.o
|
||||
led-$(CONFIG_SA1100_HACKKIT) += leds-hackkit.o
|
||||
|
@ -249,10 +249,10 @@ static void __init assabet_init(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
sa11x0_set_flash_data(&assabet_flash_data, assabet_flash_resources,
|
||||
ARRAY_SIZE(assabet_flash_resources));
|
||||
sa11x0_set_irda_data(&assabet_irda_data);
|
||||
sa11x0_set_mcp_data(&assabet_mcp_data);
|
||||
sa11x0_register_mtd(&assabet_flash_data, assabet_flash_resources,
|
||||
ARRAY_SIZE(assabet_flash_resources));
|
||||
sa11x0_register_irda(&assabet_irda_data);
|
||||
sa11x0_register_mcp(&assabet_mcp_data);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -212,7 +212,7 @@ static int __init badge4_init(void)
|
||||
/* maybe turn on 5v0 from the start */
|
||||
badge4_set_5V(BADGE4_5V_INITIALLY, five_v_on);
|
||||
|
||||
sa11x0_set_flash_data(&badge4_flash_data, &badge4_flash_resource, 1);
|
||||
sa11x0_register_mtd(&badge4_flash_data, &badge4_flash_resource, 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -129,8 +129,8 @@ static struct mcp_plat_data cerf_mcp_data = {
|
||||
static void __init cerf_init(void)
|
||||
{
|
||||
platform_add_devices(cerf_devices, ARRAY_SIZE(cerf_devices));
|
||||
sa11x0_set_flash_data(&cerf_flash_data, &cerf_flash_resource, 1);
|
||||
sa11x0_set_mcp_data(&cerf_mcp_data);
|
||||
sa11x0_register_mtd(&cerf_flash_data, &cerf_flash_resource, 1);
|
||||
sa11x0_register_mcp(&cerf_mcp_data);
|
||||
}
|
||||
|
||||
MACHINE_START(CERF, "Intrinsyc CerfBoard/CerfCube")
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include <linux/mtd/partitions.h>
|
||||
#include <linux/timer.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/pda_power.h>
|
||||
|
||||
#include <mach/hardware.h>
|
||||
#include <asm/mach-types.h>
|
||||
@ -56,6 +57,7 @@ static struct resource collie_scoop_resources[] = {
|
||||
static struct scoop_config collie_scoop_setup = {
|
||||
.io_dir = COLLIE_SCOOP_IO_DIR,
|
||||
.io_out = COLLIE_SCOOP_IO_OUT,
|
||||
.gpio_base = COLLIE_SCOOP_GPIO_BASE,
|
||||
};
|
||||
|
||||
struct platform_device colliescoop_device = {
|
||||
@ -85,6 +87,70 @@ static struct scoop_pcmcia_config collie_pcmcia_config = {
|
||||
static struct mcp_plat_data collie_mcp_data = {
|
||||
.mccr0 = MCCR0_ADM | MCCR0_ExtClk,
|
||||
.sclk_rate = 9216000,
|
||||
.gpio_base = COLLIE_TC35143_GPIO_BASE,
|
||||
};
|
||||
|
||||
/*
|
||||
* Collie AC IN
|
||||
*/
|
||||
static int collie_power_init(struct device *dev)
|
||||
{
|
||||
int ret = gpio_request(COLLIE_GPIO_AC_IN, "ac in");
|
||||
if (ret)
|
||||
goto err_gpio_req;
|
||||
|
||||
ret = gpio_direction_input(COLLIE_GPIO_AC_IN);
|
||||
if (ret)
|
||||
goto err_gpio_in;
|
||||
|
||||
return 0;
|
||||
|
||||
err_gpio_in:
|
||||
gpio_free(COLLIE_GPIO_AC_IN);
|
||||
err_gpio_req:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void collie_power_exit(struct device *dev)
|
||||
{
|
||||
gpio_free(COLLIE_GPIO_AC_IN);
|
||||
}
|
||||
|
||||
static int collie_power_ac_online(void)
|
||||
{
|
||||
return gpio_get_value(COLLIE_GPIO_AC_IN) == 2;
|
||||
}
|
||||
|
||||
static char *collie_ac_supplied_to[] = {
|
||||
"main-battery",
|
||||
"backup-battery",
|
||||
};
|
||||
|
||||
static struct pda_power_pdata collie_power_data = {
|
||||
.init = collie_power_init,
|
||||
.is_ac_online = collie_power_ac_online,
|
||||
.exit = collie_power_exit,
|
||||
.supplied_to = collie_ac_supplied_to,
|
||||
.num_supplicants = ARRAY_SIZE(collie_ac_supplied_to),
|
||||
};
|
||||
|
||||
static struct resource collie_power_resource[] = {
|
||||
{
|
||||
.name = "ac",
|
||||
.start = gpio_to_irq(COLLIE_GPIO_AC_IN),
|
||||
.end = gpio_to_irq(COLLIE_GPIO_AC_IN),
|
||||
.flags = IORESOURCE_IRQ |
|
||||
IORESOURCE_IRQ_HIGHEDGE |
|
||||
IORESOURCE_IRQ_LOWEDGE,
|
||||
},
|
||||
};
|
||||
|
||||
static struct platform_device collie_power_device = {
|
||||
.name = "pda-power",
|
||||
.id = -1,
|
||||
.dev.platform_data = &collie_power_data,
|
||||
.resource = collie_power_resource,
|
||||
.num_resources = ARRAY_SIZE(collie_power_resource),
|
||||
};
|
||||
|
||||
#ifdef CONFIG_SHARP_LOCOMO
|
||||
@ -178,6 +244,7 @@ struct platform_device collie_locomo_device = {
|
||||
static struct platform_device *devices[] __initdata = {
|
||||
&collie_locomo_device,
|
||||
&colliescoop_device,
|
||||
&collie_power_device,
|
||||
};
|
||||
|
||||
static struct mtd_partition collie_partitions[] = {
|
||||
@ -248,22 +315,24 @@ static void __init collie_init(void)
|
||||
GPDR = GPIO_LDD8 | GPIO_LDD9 | GPIO_LDD10 | GPIO_LDD11 | GPIO_LDD12 |
|
||||
GPIO_LDD13 | GPIO_LDD14 | GPIO_LDD15 | GPIO_SSP_TXD |
|
||||
GPIO_SSP_SCLK | GPIO_SSP_SFRM | GPIO_SDLC_SCLK |
|
||||
COLLIE_GPIO_UCB1x00_RESET | COLLIE_GPIO_nMIC_ON |
|
||||
COLLIE_GPIO_nREMOCON_ON | GPIO_32_768kHz;
|
||||
_COLLIE_GPIO_UCB1x00_RESET | _COLLIE_GPIO_nMIC_ON |
|
||||
_COLLIE_GPIO_nREMOCON_ON | GPIO_32_768kHz;
|
||||
|
||||
PPDR = PPC_LDD0 | PPC_LDD1 | PPC_LDD2 | PPC_LDD3 | PPC_LDD4 | PPC_LDD5 |
|
||||
PPC_LDD6 | PPC_LDD7 | PPC_L_PCLK | PPC_L_LCLK | PPC_L_FCLK | PPC_L_BIAS |
|
||||
PPC_TXD1 | PPC_TXD2 | PPC_TXD3 | PPC_TXD4 | PPC_SCLK | PPC_SFRM;
|
||||
|
||||
PWER = COLLIE_GPIO_AC_IN | COLLIE_GPIO_CO | COLLIE_GPIO_ON_KEY |
|
||||
COLLIE_GPIO_WAKEUP | COLLIE_GPIO_nREMOCON_INT | PWER_RTC;
|
||||
PWER = _COLLIE_GPIO_AC_IN | _COLLIE_GPIO_CO | _COLLIE_GPIO_ON_KEY |
|
||||
_COLLIE_GPIO_WAKEUP | _COLLIE_GPIO_nREMOCON_INT | PWER_RTC;
|
||||
|
||||
PGSR = COLLIE_GPIO_nREMOCON_ON;
|
||||
PGSR = _COLLIE_GPIO_nREMOCON_ON;
|
||||
|
||||
PSDR = PPC_RXD1 | PPC_RXD2 | PPC_RXD3 | PPC_RXD4;
|
||||
|
||||
PCFR = PCFR_OPDE;
|
||||
|
||||
GPSR |= _COLLIE_GPIO_UCB1x00_RESET;
|
||||
|
||||
|
||||
platform_scoop_config = &collie_pcmcia_config;
|
||||
|
||||
@ -272,9 +341,9 @@ static void __init collie_init(void)
|
||||
printk(KERN_WARNING "collie: Unable to register LoCoMo device\n");
|
||||
}
|
||||
|
||||
sa11x0_set_flash_data(&collie_flash_data, collie_flash_resources,
|
||||
ARRAY_SIZE(collie_flash_resources));
|
||||
sa11x0_set_mcp_data(&collie_mcp_data);
|
||||
sa11x0_register_mtd(&collie_flash_data, collie_flash_resources,
|
||||
ARRAY_SIZE(collie_flash_resources));
|
||||
sa11x0_register_mcp(&collie_mcp_data);
|
||||
|
||||
sharpsl_save_param();
|
||||
}
|
||||
|
@ -162,6 +162,17 @@ static void sa1100_power_off(void)
|
||||
PMCR = PMCR_SF;
|
||||
}
|
||||
|
||||
static void sa11x0_register_device(struct platform_device *dev, void *data)
|
||||
{
|
||||
int err;
|
||||
dev->dev.platform_data = data;
|
||||
err = platform_device_register(dev);
|
||||
if (err)
|
||||
printk(KERN_ERR "Unable to register device %s: %d\n",
|
||||
dev->name, err);
|
||||
}
|
||||
|
||||
|
||||
static struct resource sa11x0udc_resources[] = {
|
||||
[0] = {
|
||||
.start = 0x80000000,
|
||||
@ -234,9 +245,9 @@ static struct platform_device sa11x0mcp_device = {
|
||||
.resource = sa11x0mcp_resources,
|
||||
};
|
||||
|
||||
void sa11x0_set_mcp_data(struct mcp_plat_data *data)
|
||||
void sa11x0_register_mcp(struct mcp_plat_data *data)
|
||||
{
|
||||
sa11x0mcp_device.dev.platform_data = data;
|
||||
sa11x0_register_device(&sa11x0mcp_device, data);
|
||||
}
|
||||
|
||||
static struct resource sa11x0ssp_resources[] = {
|
||||
@ -293,13 +304,13 @@ static struct platform_device sa11x0mtd_device = {
|
||||
.id = -1,
|
||||
};
|
||||
|
||||
void sa11x0_set_flash_data(struct flash_platform_data *flash,
|
||||
struct resource *res, int nr)
|
||||
void sa11x0_register_mtd(struct flash_platform_data *flash,
|
||||
struct resource *res, int nr)
|
||||
{
|
||||
flash->name = "sa1100";
|
||||
sa11x0mtd_device.dev.platform_data = flash;
|
||||
sa11x0mtd_device.resource = res;
|
||||
sa11x0mtd_device.num_resources = nr;
|
||||
sa11x0_register_device(&sa11x0mtd_device, flash);
|
||||
}
|
||||
|
||||
static struct resource sa11x0ir_resources[] = {
|
||||
@ -329,9 +340,9 @@ static struct platform_device sa11x0ir_device = {
|
||||
.resource = sa11x0ir_resources,
|
||||
};
|
||||
|
||||
void sa11x0_set_irda_data(struct irda_platform_data *irda)
|
||||
void sa11x0_register_irda(struct irda_platform_data *irda)
|
||||
{
|
||||
sa11x0ir_device.dev.platform_data = irda;
|
||||
sa11x0_register_device(&sa11x0ir_device, irda);
|
||||
}
|
||||
|
||||
static struct platform_device sa11x0rtc_device = {
|
||||
@ -343,21 +354,15 @@ static struct platform_device *sa11x0_devices[] __initdata = {
|
||||
&sa11x0udc_device,
|
||||
&sa11x0uart1_device,
|
||||
&sa11x0uart3_device,
|
||||
&sa11x0mcp_device,
|
||||
&sa11x0ssp_device,
|
||||
&sa11x0pcmcia_device,
|
||||
&sa11x0fb_device,
|
||||
&sa11x0mtd_device,
|
||||
&sa11x0rtc_device,
|
||||
};
|
||||
|
||||
static int __init sa1100_init(void)
|
||||
{
|
||||
pm_power_off = sa1100_power_off;
|
||||
|
||||
if (sa11x0ir_device.dev.platform_data)
|
||||
platform_device_register(&sa11x0ir_device);
|
||||
|
||||
return platform_add_devices(sa11x0_devices, ARRAY_SIZE(sa11x0_devices));
|
||||
}
|
||||
|
||||
|
@ -32,14 +32,11 @@ extern unsigned int sa11x0_ppcr_to_freq(unsigned int idx);
|
||||
struct flash_platform_data;
|
||||
struct resource;
|
||||
|
||||
extern void sa11x0_set_flash_data(struct flash_platform_data *flash,
|
||||
struct resource *res, int nr);
|
||||
|
||||
struct sa11x0_ssp_plat_ops;
|
||||
extern void sa11x0_set_ssp_data(struct sa11x0_ssp_plat_ops *ops);
|
||||
void sa11x0_register_mtd(struct flash_platform_data *flash,
|
||||
struct resource *res, int nr);
|
||||
|
||||
struct irda_platform_data;
|
||||
void sa11x0_set_irda_data(struct irda_platform_data *irda);
|
||||
void sa11x0_register_irda(struct irda_platform_data *irda);
|
||||
|
||||
struct mcp_plat_data;
|
||||
void sa11x0_set_mcp_data(struct mcp_plat_data *data);
|
||||
void sa11x0_register_mcp(struct mcp_plat_data *data);
|
||||
|
95
arch/arm/mach-sa1100/h3100.c
Normal file
95
arch/arm/mach-sa1100/h3100.c
Normal file
@ -0,0 +1,95 @@
|
||||
/*
|
||||
* Support for Compaq iPAQ H3100 handheld computer
|
||||
*
|
||||
* Copyright (c) 2000,1 Compaq Computer Corporation. (Author: Jamey Hicks)
|
||||
* Copyright (c) 2009 Dmitry Artamonow <mad_soft@inbox.ru>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/gpio.h>
|
||||
|
||||
#include <asm/mach-types.h>
|
||||
#include <asm/mach/arch.h>
|
||||
#include <asm/mach/irda.h>
|
||||
|
||||
#include <mach/h3xxx.h>
|
||||
|
||||
#include "generic.h"
|
||||
|
||||
/*
|
||||
* helper for sa1100fb
|
||||
*/
|
||||
static void h3100_lcd_power(int enable)
|
||||
{
|
||||
if (!gpio_request(H3XXX_EGPIO_LCD_ON, "LCD ON")) {
|
||||
gpio_set_value(H3100_GPIO_LCD_3V_ON, enable);
|
||||
gpio_direction_output(H3XXX_EGPIO_LCD_ON, enable);
|
||||
gpio_free(H3XXX_EGPIO_LCD_ON);
|
||||
} else {
|
||||
pr_err("%s: can't request H3XXX_EGPIO_LCD_ON\n", __func__);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void __init h3100_map_io(void)
|
||||
{
|
||||
h3xxx_map_io();
|
||||
|
||||
sa1100fb_lcd_power = h3100_lcd_power;
|
||||
|
||||
/* Older bootldrs put GPIO2-9 in alternate mode on the
|
||||
assumption that they are used for video */
|
||||
GAFR &= ~0x000001fb;
|
||||
}
|
||||
|
||||
/*
|
||||
* This turns the IRDA power on or off on the Compaq H3100
|
||||
*/
|
||||
static int h3100_irda_set_power(struct device *dev, unsigned int state)
|
||||
{
|
||||
gpio_set_value(H3100_GPIO_IR_ON, state);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void h3100_irda_set_speed(struct device *dev, unsigned int speed)
|
||||
{
|
||||
gpio_set_value(H3100_GPIO_IR_FSEL, !(speed < 4000000));
|
||||
}
|
||||
|
||||
static struct irda_platform_data h3100_irda_data = {
|
||||
.set_power = h3100_irda_set_power,
|
||||
.set_speed = h3100_irda_set_speed,
|
||||
};
|
||||
|
||||
static struct gpio_default_state h3100_default_gpio[] = {
|
||||
{ H3100_GPIO_IR_ON, GPIO_MODE_OUT0, "IrDA power" },
|
||||
{ H3100_GPIO_IR_FSEL, GPIO_MODE_OUT0, "IrDA fsel" },
|
||||
{ H3XXX_GPIO_COM_DCD, GPIO_MODE_IN, "COM DCD" },
|
||||
{ H3XXX_GPIO_COM_CTS, GPIO_MODE_IN, "COM CTS" },
|
||||
{ H3XXX_GPIO_COM_RTS, GPIO_MODE_OUT0, "COM RTS" },
|
||||
{ H3100_GPIO_LCD_3V_ON, GPIO_MODE_OUT0, "LCD 3v" },
|
||||
};
|
||||
|
||||
static void __init h3100_mach_init(void)
|
||||
{
|
||||
h3xxx_init_gpio(h3100_default_gpio, ARRAY_SIZE(h3100_default_gpio));
|
||||
h3xxx_mach_init();
|
||||
sa11x0_register_irda(&h3100_irda_data);
|
||||
}
|
||||
|
||||
MACHINE_START(H3100, "Compaq iPAQ H3100")
|
||||
.phys_io = 0x80000000,
|
||||
.io_pg_offst = ((0xf8000000) >> 18) & 0xfffc,
|
||||
.boot_params = 0xc0000100,
|
||||
.map_io = h3100_map_io,
|
||||
.init_irq = sa1100_init_irq,
|
||||
.timer = &sa1100_timer,
|
||||
.init_machine = h3100_mach_init,
|
||||
MACHINE_END
|
||||
|
@ -1,421 +1,127 @@
|
||||
/*
|
||||
* Hardware definitions for Compaq iPAQ H3xxx Handheld Computers
|
||||
* Support for Compaq iPAQ H3600 handheld computer
|
||||
*
|
||||
* Copyright 2000,1 Compaq Computer Corporation.
|
||||
* Copyright (c) 2000,1 Compaq Computer Corporation. (Author: Jamey Hicks)
|
||||
* Copyright (c) 2009 Dmitry Artamonow <mad_soft@inbox.ru>
|
||||
*
|
||||
* Use consistent with the GNU GPL is permitted,
|
||||
* provided that this copyright notice is
|
||||
* preserved in its entirety in all copies and derived works.
|
||||
*
|
||||
* COMPAQ COMPUTER CORPORATION MAKES NO WARRANTIES, EXPRESSED OR IMPLIED,
|
||||
* AS TO THE USEFULNESS OR CORRECTNESS OF THIS CODE OR ITS
|
||||
* FITNESS FOR ANY PARTICULAR PURPOSE.
|
||||
*
|
||||
* Author: Jamey Hicks.
|
||||
*
|
||||
* History:
|
||||
*
|
||||
* 2001-10-?? Andrew Christian Added support for iPAQ H3800
|
||||
* and abstracted EGPIO interface.
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
*/
|
||||
#include <linux/module.h>
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/tty.h>
|
||||
#include <linux/pm.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/mtd/mtd.h>
|
||||
#include <linux/mtd/partitions.h>
|
||||
#include <linux/serial_core.h>
|
||||
#include <linux/gpio.h>
|
||||
|
||||
#include <asm/irq.h>
|
||||
#include <mach/hardware.h>
|
||||
#include <asm/mach-types.h>
|
||||
#include <asm/setup.h>
|
||||
|
||||
#include <asm/mach/irq.h>
|
||||
#include <asm/mach/arch.h>
|
||||
#include <asm/mach/flash.h>
|
||||
#include <asm/mach/irda.h>
|
||||
#include <asm/mach/map.h>
|
||||
#include <asm/mach/serial_sa1100.h>
|
||||
|
||||
#include <mach/h3600.h>
|
||||
#include <mach/h3600_gpio.h>
|
||||
#include <mach/h3xxx.h>
|
||||
|
||||
#include "generic.h"
|
||||
|
||||
void (*assign_h3600_egpio)(enum ipaq_egpio_type x, int level);
|
||||
EXPORT_SYMBOL(assign_h3600_egpio);
|
||||
|
||||
static struct mtd_partition h3xxx_partitions[] = {
|
||||
{
|
||||
.name = "H3XXX boot firmware",
|
||||
.size = 0x00040000,
|
||||
.offset = 0,
|
||||
.mask_flags = MTD_WRITEABLE, /* force read-only */
|
||||
}, {
|
||||
.name = "H3XXX rootfs",
|
||||
.size = MTDPART_SIZ_FULL,
|
||||
.offset = 0x00040000,
|
||||
}
|
||||
};
|
||||
|
||||
static void h3xxx_set_vpp(int vpp)
|
||||
{
|
||||
assign_h3600_egpio(IPAQ_EGPIO_VPP_ON, vpp);
|
||||
}
|
||||
|
||||
static struct flash_platform_data h3xxx_flash_data = {
|
||||
.map_name = "cfi_probe",
|
||||
.set_vpp = h3xxx_set_vpp,
|
||||
.parts = h3xxx_partitions,
|
||||
.nr_parts = ARRAY_SIZE(h3xxx_partitions),
|
||||
};
|
||||
|
||||
static struct resource h3xxx_flash_resource = {
|
||||
.start = SA1100_CS0_PHYS,
|
||||
.end = SA1100_CS0_PHYS + SZ_32M - 1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
};
|
||||
|
||||
/*
|
||||
* This turns the IRDA power on or off on the Compaq H3600
|
||||
*/
|
||||
static int h3600_irda_set_power(struct device *dev, unsigned int state)
|
||||
{
|
||||
assign_h3600_egpio( IPAQ_EGPIO_IR_ON, state );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void h3600_irda_set_speed(struct device *dev, unsigned int speed)
|
||||
{
|
||||
assign_h3600_egpio(IPAQ_EGPIO_IR_FSEL, !(speed < 4000000));
|
||||
}
|
||||
|
||||
static struct irda_platform_data h3600_irda_data = {
|
||||
.set_power = h3600_irda_set_power,
|
||||
.set_speed = h3600_irda_set_speed,
|
||||
};
|
||||
|
||||
static void h3xxx_mach_init(void)
|
||||
{
|
||||
sa11x0_set_flash_data(&h3xxx_flash_data, &h3xxx_flash_resource, 1);
|
||||
sa11x0_set_irda_data(&h3600_irda_data);
|
||||
}
|
||||
|
||||
/*
|
||||
* low-level UART features
|
||||
*/
|
||||
|
||||
static void h3600_uart_set_mctrl(struct uart_port *port, u_int mctrl)
|
||||
{
|
||||
if (port->mapbase == _Ser3UTCR0) {
|
||||
if (mctrl & TIOCM_RTS)
|
||||
GPCR = GPIO_H3600_COM_RTS;
|
||||
else
|
||||
GPSR = GPIO_H3600_COM_RTS;
|
||||
}
|
||||
}
|
||||
|
||||
static u_int h3600_uart_get_mctrl(struct uart_port *port)
|
||||
{
|
||||
u_int ret = TIOCM_CD | TIOCM_CTS | TIOCM_DSR;
|
||||
|
||||
if (port->mapbase == _Ser3UTCR0) {
|
||||
int gplr = GPLR;
|
||||
/* DCD and CTS bits are inverted in GPLR by RS232 transceiver */
|
||||
if (gplr & GPIO_H3600_COM_DCD)
|
||||
ret &= ~TIOCM_CD;
|
||||
if (gplr & GPIO_H3600_COM_CTS)
|
||||
ret &= ~TIOCM_CTS;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void h3600_uart_pm(struct uart_port *port, u_int state, u_int oldstate)
|
||||
{
|
||||
if (port->mapbase == _Ser2UTCR0) { /* TODO: REMOVE THIS */
|
||||
assign_h3600_egpio(IPAQ_EGPIO_IR_ON, !state);
|
||||
} else if (port->mapbase == _Ser3UTCR0) {
|
||||
assign_h3600_egpio(IPAQ_EGPIO_RS232_ON, !state);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Enable/Disable wake up events for this serial port.
|
||||
* Obviously, we only support this on the normal COM port.
|
||||
*/
|
||||
static int h3600_uart_set_wake(struct uart_port *port, u_int enable)
|
||||
{
|
||||
int err = -EINVAL;
|
||||
|
||||
if (port->mapbase == _Ser3UTCR0) {
|
||||
if (enable)
|
||||
PWER |= PWER_GPIO23 | PWER_GPIO25; /* DCD and CTS */
|
||||
else
|
||||
PWER &= ~(PWER_GPIO23 | PWER_GPIO25); /* DCD and CTS */
|
||||
err = 0;
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
static struct sa1100_port_fns h3600_port_fns __initdata = {
|
||||
.set_mctrl = h3600_uart_set_mctrl,
|
||||
.get_mctrl = h3600_uart_get_mctrl,
|
||||
.pm = h3600_uart_pm,
|
||||
.set_wake = h3600_uart_set_wake,
|
||||
};
|
||||
|
||||
/*
|
||||
* helper for sa1100fb
|
||||
*/
|
||||
static void h3xxx_lcd_power(int enable)
|
||||
static void h3600_lcd_power(int enable)
|
||||
{
|
||||
assign_h3600_egpio(IPAQ_EGPIO_LCD_POWER, enable);
|
||||
}
|
||||
|
||||
static struct map_desc h3600_io_desc[] __initdata = {
|
||||
{ /* static memory bank 2 CS#2 */
|
||||
.virtual = H3600_BANK_2_VIRT,
|
||||
.pfn = __phys_to_pfn(SA1100_CS2_PHYS),
|
||||
.length = 0x02800000,
|
||||
.type = MT_DEVICE
|
||||
}, { /* static memory bank 4 CS#4 */
|
||||
.virtual = H3600_BANK_4_VIRT,
|
||||
.pfn = __phys_to_pfn(SA1100_CS4_PHYS),
|
||||
.length = 0x00800000,
|
||||
.type = MT_DEVICE
|
||||
}, { /* EGPIO 0 CS#5 */
|
||||
.virtual = H3600_EGPIO_VIRT,
|
||||
.pfn = __phys_to_pfn(H3600_EGPIO_PHYS),
|
||||
.length = 0x01000000,
|
||||
.type = MT_DEVICE
|
||||
if (gpio_request(H3XXX_EGPIO_LCD_ON, "LCD power")) {
|
||||
pr_err("%s: can't request H3XXX_EGPIO_LCD_ON\n", __func__);
|
||||
goto err1;
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
* Common map_io initialization
|
||||
*/
|
||||
|
||||
static void __init h3xxx_map_io(void)
|
||||
{
|
||||
sa1100_map_io();
|
||||
iotable_init(h3600_io_desc, ARRAY_SIZE(h3600_io_desc));
|
||||
|
||||
sa1100_register_uart_fns(&h3600_port_fns);
|
||||
sa1100_register_uart(0, 3); /* Common serial port */
|
||||
// sa1100_register_uart(1, 1); /* Microcontroller on 3100/3600 */
|
||||
|
||||
/* Ensure those pins are outputs and driving low */
|
||||
PPDR |= PPC_TXD4 | PPC_SCLK | PPC_SFRM;
|
||||
PPSR &= ~(PPC_TXD4 | PPC_SCLK | PPC_SFRM);
|
||||
|
||||
/* Configure suspend conditions */
|
||||
PGSR = 0;
|
||||
PWER = PWER_GPIO0 | PWER_RTC;
|
||||
PCFR = PCFR_OPDE;
|
||||
PSDR = 0;
|
||||
|
||||
sa1100fb_lcd_power = h3xxx_lcd_power;
|
||||
}
|
||||
|
||||
/************************* H3100 *************************/
|
||||
|
||||
#ifdef CONFIG_SA1100_H3100
|
||||
|
||||
#define H3100_EGPIO (*(volatile unsigned int *)H3600_EGPIO_VIRT)
|
||||
static unsigned int h3100_egpio = 0;
|
||||
|
||||
static void h3100_control_egpio(enum ipaq_egpio_type x, int setp)
|
||||
{
|
||||
unsigned int egpio = 0;
|
||||
long gpio = 0;
|
||||
unsigned long flags;
|
||||
|
||||
switch (x) {
|
||||
case IPAQ_EGPIO_LCD_POWER:
|
||||
egpio |= EGPIO_H3600_LCD_ON;
|
||||
gpio |= GPIO_H3100_LCD_3V_ON;
|
||||
break;
|
||||
case IPAQ_EGPIO_LCD_ENABLE:
|
||||
break;
|
||||
case IPAQ_EGPIO_CODEC_NRESET:
|
||||
egpio |= EGPIO_H3600_CODEC_NRESET;
|
||||
break;
|
||||
case IPAQ_EGPIO_AUDIO_ON:
|
||||
gpio |= GPIO_H3100_AUD_PWR_ON
|
||||
| GPIO_H3100_AUD_ON;
|
||||
break;
|
||||
case IPAQ_EGPIO_QMUTE:
|
||||
gpio |= GPIO_H3100_QMUTE;
|
||||
break;
|
||||
case IPAQ_EGPIO_OPT_NVRAM_ON:
|
||||
egpio |= EGPIO_H3600_OPT_NVRAM_ON;
|
||||
break;
|
||||
case IPAQ_EGPIO_OPT_ON:
|
||||
egpio |= EGPIO_H3600_OPT_ON;
|
||||
break;
|
||||
case IPAQ_EGPIO_CARD_RESET:
|
||||
egpio |= EGPIO_H3600_CARD_RESET;
|
||||
break;
|
||||
case IPAQ_EGPIO_OPT_RESET:
|
||||
egpio |= EGPIO_H3600_OPT_RESET;
|
||||
break;
|
||||
case IPAQ_EGPIO_IR_ON:
|
||||
gpio |= GPIO_H3100_IR_ON;
|
||||
break;
|
||||
case IPAQ_EGPIO_IR_FSEL:
|
||||
gpio |= GPIO_H3100_IR_FSEL;
|
||||
break;
|
||||
case IPAQ_EGPIO_RS232_ON:
|
||||
egpio |= EGPIO_H3600_RS232_ON;
|
||||
break;
|
||||
case IPAQ_EGPIO_VPP_ON:
|
||||
egpio |= EGPIO_H3600_VPP_ON;
|
||||
break;
|
||||
if (gpio_request(H3600_EGPIO_LCD_PCI, "LCD control")) {
|
||||
pr_err("%s: can't request H3XXX_EGPIO_LCD_PCI\n", __func__);
|
||||
goto err2;
|
||||
}
|
||||
if (gpio_request(H3600_EGPIO_LCD_5V_ON, "LCD 5v")) {
|
||||
pr_err("%s: can't request H3XXX_EGPIO_LCD_5V_ON\n", __func__);
|
||||
goto err3;
|
||||
}
|
||||
if (gpio_request(H3600_EGPIO_LVDD_ON, "LCD 9v/-6.5v")) {
|
||||
pr_err("%s: can't request H3600_EGPIO_LVDD_ON\n", __func__);
|
||||
goto err4;
|
||||
}
|
||||
|
||||
if (egpio || gpio) {
|
||||
local_irq_save(flags);
|
||||
if (setp) {
|
||||
h3100_egpio |= egpio;
|
||||
GPSR = gpio;
|
||||
} else {
|
||||
h3100_egpio &= ~egpio;
|
||||
GPCR = gpio;
|
||||
}
|
||||
H3100_EGPIO = h3100_egpio;
|
||||
local_irq_restore(flags);
|
||||
}
|
||||
}
|
||||
gpio_direction_output(H3XXX_EGPIO_LCD_ON, enable);
|
||||
gpio_direction_output(H3600_EGPIO_LCD_PCI, enable);
|
||||
gpio_direction_output(H3600_EGPIO_LCD_5V_ON, enable);
|
||||
gpio_direction_output(H3600_EGPIO_LVDD_ON, enable);
|
||||
|
||||
#define H3100_DIRECT_EGPIO (GPIO_H3100_BT_ON \
|
||||
| GPIO_H3100_GPIO3 \
|
||||
| GPIO_H3100_QMUTE \
|
||||
| GPIO_H3100_LCD_3V_ON \
|
||||
| GPIO_H3100_AUD_ON \
|
||||
| GPIO_H3100_AUD_PWR_ON \
|
||||
| GPIO_H3100_IR_ON \
|
||||
| GPIO_H3100_IR_FSEL)
|
||||
|
||||
static void __init h3100_map_io(void)
|
||||
{
|
||||
h3xxx_map_io();
|
||||
|
||||
/* Initialize h3100-specific values here */
|
||||
GPCR = 0x0fffffff; /* All outputs are set low by default */
|
||||
GPDR = GPIO_H3600_COM_RTS | GPIO_H3600_L3_CLOCK |
|
||||
GPIO_H3600_L3_MODE | GPIO_H3600_L3_DATA |
|
||||
GPIO_H3600_CLK_SET1 | GPIO_H3600_CLK_SET0 |
|
||||
H3100_DIRECT_EGPIO;
|
||||
|
||||
/* Older bootldrs put GPIO2-9 in alternate mode on the
|
||||
assumption that they are used for video */
|
||||
GAFR &= ~H3100_DIRECT_EGPIO;
|
||||
|
||||
H3100_EGPIO = h3100_egpio;
|
||||
assign_h3600_egpio = h3100_control_egpio;
|
||||
}
|
||||
|
||||
MACHINE_START(H3100, "Compaq iPAQ H3100")
|
||||
.phys_io = 0x80000000,
|
||||
.io_pg_offst = ((0xf8000000) >> 18) & 0xfffc,
|
||||
.boot_params = 0xc0000100,
|
||||
.map_io = h3100_map_io,
|
||||
.init_irq = sa1100_init_irq,
|
||||
.timer = &sa1100_timer,
|
||||
.init_machine = h3xxx_mach_init,
|
||||
MACHINE_END
|
||||
|
||||
#endif /* CONFIG_SA1100_H3100 */
|
||||
|
||||
/************************* H3600 *************************/
|
||||
|
||||
#ifdef CONFIG_SA1100_H3600
|
||||
|
||||
#define H3600_EGPIO (*(volatile unsigned int *)H3600_EGPIO_VIRT)
|
||||
static unsigned int h3600_egpio = EGPIO_H3600_RS232_ON;
|
||||
|
||||
static void h3600_control_egpio(enum ipaq_egpio_type x, int setp)
|
||||
{
|
||||
unsigned int egpio = 0;
|
||||
unsigned long flags;
|
||||
|
||||
switch (x) {
|
||||
case IPAQ_EGPIO_LCD_POWER:
|
||||
egpio |= EGPIO_H3600_LCD_ON |
|
||||
EGPIO_H3600_LCD_PCI |
|
||||
EGPIO_H3600_LCD_5V_ON |
|
||||
EGPIO_H3600_LVDD_ON;
|
||||
break;
|
||||
case IPAQ_EGPIO_LCD_ENABLE:
|
||||
break;
|
||||
case IPAQ_EGPIO_CODEC_NRESET:
|
||||
egpio |= EGPIO_H3600_CODEC_NRESET;
|
||||
break;
|
||||
case IPAQ_EGPIO_AUDIO_ON:
|
||||
egpio |= EGPIO_H3600_AUD_AMP_ON |
|
||||
EGPIO_H3600_AUD_PWR_ON;
|
||||
break;
|
||||
case IPAQ_EGPIO_QMUTE:
|
||||
egpio |= EGPIO_H3600_QMUTE;
|
||||
break;
|
||||
case IPAQ_EGPIO_OPT_NVRAM_ON:
|
||||
egpio |= EGPIO_H3600_OPT_NVRAM_ON;
|
||||
break;
|
||||
case IPAQ_EGPIO_OPT_ON:
|
||||
egpio |= EGPIO_H3600_OPT_ON;
|
||||
break;
|
||||
case IPAQ_EGPIO_CARD_RESET:
|
||||
egpio |= EGPIO_H3600_CARD_RESET;
|
||||
break;
|
||||
case IPAQ_EGPIO_OPT_RESET:
|
||||
egpio |= EGPIO_H3600_OPT_RESET;
|
||||
break;
|
||||
case IPAQ_EGPIO_IR_ON:
|
||||
egpio |= EGPIO_H3600_IR_ON;
|
||||
break;
|
||||
case IPAQ_EGPIO_IR_FSEL:
|
||||
egpio |= EGPIO_H3600_IR_FSEL;
|
||||
break;
|
||||
case IPAQ_EGPIO_RS232_ON:
|
||||
egpio |= EGPIO_H3600_RS232_ON;
|
||||
break;
|
||||
case IPAQ_EGPIO_VPP_ON:
|
||||
egpio |= EGPIO_H3600_VPP_ON;
|
||||
break;
|
||||
}
|
||||
|
||||
if (egpio) {
|
||||
local_irq_save(flags);
|
||||
if (setp)
|
||||
h3600_egpio |= egpio;
|
||||
else
|
||||
h3600_egpio &= ~egpio;
|
||||
H3600_EGPIO = h3600_egpio;
|
||||
local_irq_restore(flags);
|
||||
}
|
||||
gpio_free(H3600_EGPIO_LVDD_ON);
|
||||
err4: gpio_free(H3600_EGPIO_LCD_5V_ON);
|
||||
err3: gpio_free(H3600_EGPIO_LCD_PCI);
|
||||
err2: gpio_free(H3XXX_EGPIO_LCD_ON);
|
||||
err1: return;
|
||||
}
|
||||
|
||||
static void __init h3600_map_io(void)
|
||||
{
|
||||
h3xxx_map_io();
|
||||
|
||||
/* Initialize h3600-specific values here */
|
||||
sa1100fb_lcd_power = h3600_lcd_power;
|
||||
}
|
||||
|
||||
GPCR = 0x0fffffff; /* All outputs are set low by default */
|
||||
GPDR = GPIO_H3600_COM_RTS | GPIO_H3600_L3_CLOCK |
|
||||
GPIO_H3600_L3_MODE | GPIO_H3600_L3_DATA |
|
||||
GPIO_H3600_CLK_SET1 | GPIO_H3600_CLK_SET0 |
|
||||
GPIO_LDD15 | GPIO_LDD14 | GPIO_LDD13 | GPIO_LDD12 |
|
||||
GPIO_LDD11 | GPIO_LDD10 | GPIO_LDD9 | GPIO_LDD8;
|
||||
/*
|
||||
* This turns the IRDA power on or off on the Compaq H3600
|
||||
*/
|
||||
static int h3600_irda_set_power(struct device *dev, unsigned int state)
|
||||
{
|
||||
gpio_set_value(H3600_EGPIO_IR_ON, state);
|
||||
return 0;
|
||||
}
|
||||
|
||||
H3600_EGPIO = h3600_egpio; /* Maintains across sleep? */
|
||||
assign_h3600_egpio = h3600_control_egpio;
|
||||
static void h3600_irda_set_speed(struct device *dev, unsigned int speed)
|
||||
{
|
||||
gpio_set_value(H3600_EGPIO_IR_FSEL, !(speed < 4000000));
|
||||
}
|
||||
|
||||
static int h3600_irda_startup(struct device *dev)
|
||||
{
|
||||
int err = gpio_request(H3600_EGPIO_IR_ON, "IrDA power");
|
||||
if (err)
|
||||
goto err1;
|
||||
err = gpio_direction_output(H3600_EGPIO_IR_ON, 0);
|
||||
if (err)
|
||||
goto err2;
|
||||
err = gpio_request(H3600_EGPIO_IR_FSEL, "IrDA fsel");
|
||||
if (err)
|
||||
goto err2;
|
||||
err = gpio_direction_output(H3600_EGPIO_IR_FSEL, 0);
|
||||
if (err)
|
||||
goto err3;
|
||||
return 0;
|
||||
|
||||
err3: gpio_free(H3600_EGPIO_IR_FSEL);
|
||||
err2: gpio_free(H3600_EGPIO_IR_ON);
|
||||
err1: return err;
|
||||
}
|
||||
|
||||
static void h3600_irda_shutdown(struct device *dev)
|
||||
{
|
||||
gpio_free(H3600_EGPIO_IR_ON);
|
||||
gpio_free(H3600_EGPIO_IR_FSEL);
|
||||
}
|
||||
|
||||
static struct irda_platform_data h3600_irda_data = {
|
||||
.set_power = h3600_irda_set_power,
|
||||
.set_speed = h3600_irda_set_speed,
|
||||
.startup = h3600_irda_startup,
|
||||
.shutdown = h3600_irda_shutdown,
|
||||
};
|
||||
|
||||
static struct gpio_default_state h3600_default_gpio[] = {
|
||||
{ H3XXX_GPIO_COM_DCD, GPIO_MODE_IN, "COM DCD" },
|
||||
{ H3XXX_GPIO_COM_CTS, GPIO_MODE_IN, "COM CTS" },
|
||||
{ H3XXX_GPIO_COM_RTS, GPIO_MODE_OUT0, "COM RTS" },
|
||||
};
|
||||
|
||||
static void __init h3600_mach_init(void)
|
||||
{
|
||||
h3xxx_init_gpio(h3600_default_gpio, ARRAY_SIZE(h3600_default_gpio));
|
||||
h3xxx_mach_init();
|
||||
sa11x0_register_irda(&h3600_irda_data);
|
||||
}
|
||||
|
||||
MACHINE_START(H3600, "Compaq iPAQ H3600")
|
||||
@ -425,8 +131,6 @@ MACHINE_START(H3600, "Compaq iPAQ H3600")
|
||||
.map_io = h3600_map_io,
|
||||
.init_irq = sa1100_init_irq,
|
||||
.timer = &sa1100_timer,
|
||||
.init_machine = h3xxx_mach_init,
|
||||
.init_machine = h3600_mach_init,
|
||||
MACHINE_END
|
||||
|
||||
#endif /* CONFIG_SA1100_H3600 */
|
||||
|
||||
|
313
arch/arm/mach-sa1100/h3xxx.c
Normal file
313
arch/arm/mach-sa1100/h3xxx.c
Normal file
@ -0,0 +1,313 @@
|
||||
/*
|
||||
* Support for Compaq iPAQ H3100 and H3600 handheld computers (common code)
|
||||
*
|
||||
* Copyright (c) 2000,1 Compaq Computer Corporation. (Author: Jamey Hicks)
|
||||
* Copyright (c) 2009 Dmitry Artamonow <mad_soft@inbox.ru>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/gpio_keys.h>
|
||||
#include <linux/input.h>
|
||||
#include <linux/mfd/htc-egpio.h>
|
||||
#include <linux/mtd/mtd.h>
|
||||
#include <linux/mtd/partitions.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/serial_core.h>
|
||||
|
||||
#include <asm/mach/flash.h>
|
||||
#include <asm/mach/map.h>
|
||||
#include <asm/mach/serial_sa1100.h>
|
||||
|
||||
#include <mach/h3xxx.h>
|
||||
|
||||
#include "generic.h"
|
||||
|
||||
void h3xxx_init_gpio(struct gpio_default_state *s, size_t n)
|
||||
{
|
||||
while (n--) {
|
||||
const char *name = s->name;
|
||||
int err;
|
||||
|
||||
if (!name)
|
||||
name = "[init]";
|
||||
err = gpio_request(s->gpio, name);
|
||||
if (err) {
|
||||
printk(KERN_ERR "gpio%u: unable to request: %d\n",
|
||||
s->gpio, err);
|
||||
continue;
|
||||
}
|
||||
if (s->mode >= 0) {
|
||||
err = gpio_direction_output(s->gpio, s->mode);
|
||||
} else {
|
||||
err = gpio_direction_input(s->gpio);
|
||||
}
|
||||
if (err) {
|
||||
printk(KERN_ERR "gpio%u: unable to set direction: %d\n",
|
||||
s->gpio, err);
|
||||
continue;
|
||||
}
|
||||
if (!s->name)
|
||||
gpio_free(s->gpio);
|
||||
s++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* H3xxx flash support
|
||||
*/
|
||||
static struct mtd_partition h3xxx_partitions[] = {
|
||||
{
|
||||
.name = "H3XXX boot firmware",
|
||||
.size = 0x00040000,
|
||||
.offset = 0,
|
||||
.mask_flags = MTD_WRITEABLE, /* force read-only */
|
||||
}, {
|
||||
.name = "H3XXX rootfs",
|
||||
.size = MTDPART_SIZ_FULL,
|
||||
.offset = 0x00040000,
|
||||
}
|
||||
};
|
||||
|
||||
static void h3xxx_set_vpp(int vpp)
|
||||
{
|
||||
gpio_set_value(H3XXX_EGPIO_VPP_ON, vpp);
|
||||
}
|
||||
|
||||
static int h3xxx_flash_init(void)
|
||||
{
|
||||
int err = gpio_request(H3XXX_EGPIO_VPP_ON, "Flash Vpp");
|
||||
if (err) {
|
||||
pr_err("%s: can't request H3XXX_EGPIO_VPP_ON\n", __func__);
|
||||
return err;
|
||||
}
|
||||
|
||||
err = gpio_direction_output(H3XXX_EGPIO_VPP_ON, 0);
|
||||
if (err)
|
||||
gpio_free(H3XXX_EGPIO_VPP_ON);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static void h3xxx_flash_exit(void)
|
||||
{
|
||||
gpio_free(H3XXX_EGPIO_VPP_ON);
|
||||
}
|
||||
|
||||
static struct flash_platform_data h3xxx_flash_data = {
|
||||
.map_name = "cfi_probe",
|
||||
.set_vpp = h3xxx_set_vpp,
|
||||
.init = h3xxx_flash_init,
|
||||
.exit = h3xxx_flash_exit,
|
||||
.parts = h3xxx_partitions,
|
||||
.nr_parts = ARRAY_SIZE(h3xxx_partitions),
|
||||
};
|
||||
|
||||
static struct resource h3xxx_flash_resource = {
|
||||
.start = SA1100_CS0_PHYS,
|
||||
.end = SA1100_CS0_PHYS + SZ_32M - 1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* H3xxx uart support
|
||||
*/
|
||||
static void h3xxx_uart_set_mctrl(struct uart_port *port, u_int mctrl)
|
||||
{
|
||||
if (port->mapbase == _Ser3UTCR0) {
|
||||
gpio_set_value(H3XXX_GPIO_COM_RTS, !(mctrl & TIOCM_RTS));
|
||||
}
|
||||
}
|
||||
|
||||
static u_int h3xxx_uart_get_mctrl(struct uart_port *port)
|
||||
{
|
||||
u_int ret = TIOCM_CD | TIOCM_CTS | TIOCM_DSR;
|
||||
|
||||
if (port->mapbase == _Ser3UTCR0) {
|
||||
/*
|
||||
* DCD and CTS bits are inverted in GPLR by RS232 transceiver
|
||||
*/
|
||||
if (gpio_get_value(H3XXX_GPIO_COM_DCD))
|
||||
ret &= ~TIOCM_CD;
|
||||
if (gpio_get_value(H3XXX_GPIO_COM_CTS))
|
||||
ret &= ~TIOCM_CTS;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void h3xxx_uart_pm(struct uart_port *port, u_int state, u_int oldstate)
|
||||
{
|
||||
if (port->mapbase == _Ser3UTCR0) {
|
||||
if (!gpio_request(H3XXX_EGPIO_RS232_ON, "RS232 transceiver")) {
|
||||
gpio_direction_output(H3XXX_EGPIO_RS232_ON, !state);
|
||||
gpio_free(H3XXX_EGPIO_RS232_ON);
|
||||
} else {
|
||||
pr_err("%s: can't request H3XXX_EGPIO_RS232_ON\n",
|
||||
__func__);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Enable/Disable wake up events for this serial port.
|
||||
* Obviously, we only support this on the normal COM port.
|
||||
*/
|
||||
static int h3xxx_uart_set_wake(struct uart_port *port, u_int enable)
|
||||
{
|
||||
int err = -EINVAL;
|
||||
|
||||
if (port->mapbase == _Ser3UTCR0) {
|
||||
if (enable)
|
||||
PWER |= PWER_GPIO23 | PWER_GPIO25; /* DCD and CTS */
|
||||
else
|
||||
PWER &= ~(PWER_GPIO23 | PWER_GPIO25); /* DCD and CTS */
|
||||
err = 0;
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
static struct sa1100_port_fns h3xxx_port_fns __initdata = {
|
||||
.set_mctrl = h3xxx_uart_set_mctrl,
|
||||
.get_mctrl = h3xxx_uart_get_mctrl,
|
||||
.pm = h3xxx_uart_pm,
|
||||
.set_wake = h3xxx_uart_set_wake,
|
||||
};
|
||||
|
||||
/*
|
||||
* EGPIO
|
||||
*/
|
||||
|
||||
static struct resource egpio_resources[] = {
|
||||
[0] = {
|
||||
.start = H3600_EGPIO_PHYS,
|
||||
.end = H3600_EGPIO_PHYS + 0x4 - 1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
};
|
||||
|
||||
static struct htc_egpio_chip egpio_chips[] = {
|
||||
[0] = {
|
||||
.reg_start = 0,
|
||||
.gpio_base = H3XXX_EGPIO_BASE,
|
||||
.num_gpios = 16,
|
||||
.direction = HTC_EGPIO_OUTPUT,
|
||||
.initial_values = 0x0080, /* H3XXX_EGPIO_RS232_ON */
|
||||
},
|
||||
};
|
||||
|
||||
static struct htc_egpio_platform_data egpio_info = {
|
||||
.reg_width = 16,
|
||||
.bus_width = 16,
|
||||
.chip = egpio_chips,
|
||||
.num_chips = ARRAY_SIZE(egpio_chips),
|
||||
};
|
||||
|
||||
static struct platform_device h3xxx_egpio = {
|
||||
.name = "htc-egpio",
|
||||
.id = -1,
|
||||
.resource = egpio_resources,
|
||||
.num_resources = ARRAY_SIZE(egpio_resources),
|
||||
.dev = {
|
||||
.platform_data = &egpio_info,
|
||||
},
|
||||
};
|
||||
|
||||
/*
|
||||
* GPIO keys
|
||||
*/
|
||||
|
||||
static struct gpio_keys_button h3xxx_button_table[] = {
|
||||
{
|
||||
.code = KEY_POWER,
|
||||
.gpio = H3XXX_GPIO_PWR_BUTTON,
|
||||
.desc = "Power Button",
|
||||
.active_low = 1,
|
||||
.type = EV_KEY,
|
||||
.wakeup = 1,
|
||||
}, {
|
||||
.code = KEY_ENTER,
|
||||
.gpio = H3XXX_GPIO_ACTION_BUTTON,
|
||||
.active_low = 1,
|
||||
.desc = "Action button",
|
||||
.type = EV_KEY,
|
||||
.wakeup = 0,
|
||||
},
|
||||
};
|
||||
|
||||
static struct gpio_keys_platform_data h3xxx_keys_data = {
|
||||
.buttons = h3xxx_button_table,
|
||||
.nbuttons = ARRAY_SIZE(h3xxx_button_table),
|
||||
};
|
||||
|
||||
static struct platform_device h3xxx_keys = {
|
||||
.name = "gpio-keys",
|
||||
.id = -1,
|
||||
.dev = {
|
||||
.platform_data = &h3xxx_keys_data,
|
||||
},
|
||||
};
|
||||
|
||||
static struct platform_device *h3xxx_devices[] = {
|
||||
&h3xxx_egpio,
|
||||
&h3xxx_keys,
|
||||
};
|
||||
|
||||
void __init h3xxx_mach_init(void)
|
||||
{
|
||||
sa1100_register_uart_fns(&h3xxx_port_fns);
|
||||
sa11x0_register_mtd(&h3xxx_flash_data, &h3xxx_flash_resource, 1);
|
||||
platform_add_devices(h3xxx_devices, ARRAY_SIZE(h3xxx_devices));
|
||||
}
|
||||
|
||||
static struct map_desc h3600_io_desc[] __initdata = {
|
||||
{ /* static memory bank 2 CS#2 */
|
||||
.virtual = H3600_BANK_2_VIRT,
|
||||
.pfn = __phys_to_pfn(SA1100_CS2_PHYS),
|
||||
.length = 0x02800000,
|
||||
.type = MT_DEVICE
|
||||
}, { /* static memory bank 4 CS#4 */
|
||||
.virtual = H3600_BANK_4_VIRT,
|
||||
.pfn = __phys_to_pfn(SA1100_CS4_PHYS),
|
||||
.length = 0x00800000,
|
||||
.type = MT_DEVICE
|
||||
}, { /* EGPIO 0 CS#5 */
|
||||
.virtual = H3600_EGPIO_VIRT,
|
||||
.pfn = __phys_to_pfn(H3600_EGPIO_PHYS),
|
||||
.length = 0x01000000,
|
||||
.type = MT_DEVICE
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
* Common map_io initialization
|
||||
*/
|
||||
|
||||
void __init h3xxx_map_io(void)
|
||||
{
|
||||
sa1100_map_io();
|
||||
iotable_init(h3600_io_desc, ARRAY_SIZE(h3600_io_desc));
|
||||
|
||||
sa1100_register_uart(0, 3); /* Common serial port */
|
||||
// sa1100_register_uart(1, 1); /* Microcontroller on 3100/3600 */
|
||||
|
||||
/* Ensure those pins are outputs and driving low */
|
||||
PPDR |= PPC_TXD4 | PPC_SCLK | PPC_SFRM;
|
||||
PPSR &= ~(PPC_TXD4 | PPC_SCLK | PPC_SFRM);
|
||||
|
||||
/* Configure suspend conditions */
|
||||
PGSR = 0;
|
||||
PCFR = PCFR_OPDE;
|
||||
PSDR = 0;
|
||||
|
||||
GPCR = 0x0fffffff; /* All outputs are set low by default */
|
||||
GPDR = 0; /* Configure all GPIOs as input */
|
||||
}
|
||||
|
@ -187,7 +187,7 @@ static struct resource hackkit_flash_resource = {
|
||||
|
||||
static void __init hackkit_init(void)
|
||||
{
|
||||
sa11x0_set_flash_data(&hackkit_flash_data, &hackkit_flash_resource, 1);
|
||||
sa11x0_register_mtd(&hackkit_flash_data, &hackkit_flash_resource, 1);
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
|
@ -25,29 +25,39 @@
|
||||
#define COLLIE_GPIO_VPEN (COLLIE_SCOOP_GPIO_BASE + 7)
|
||||
#define COLLIE_SCP_LB_VOL_CHG SCOOP_GPCR_PA19
|
||||
|
||||
#define COLLIE_SCOOP_IO_DIR ( COLLIE_SCP_MUTE_L | COLLIE_SCP_MUTE_R | \
|
||||
#define COLLIE_SCOOP_IO_DIR (COLLIE_SCP_MUTE_L | COLLIE_SCP_MUTE_R | \
|
||||
COLLIE_SCP_5VON | COLLIE_SCP_AMP_ON | \
|
||||
COLLIE_SCP_LB_VOL_CHG )
|
||||
#define COLLIE_SCOOP_IO_OUT ( COLLIE_SCP_MUTE_L | COLLIE_SCP_MUTE_R )
|
||||
COLLIE_SCP_LB_VOL_CHG)
|
||||
#define COLLIE_SCOOP_IO_OUT (COLLIE_SCP_MUTE_L | COLLIE_SCP_MUTE_R)
|
||||
|
||||
/* GPIOs for which the generic definition doesn't say much */
|
||||
/* GPIOs for gpiolib */
|
||||
|
||||
#define COLLIE_GPIO_ON_KEY GPIO_GPIO (0)
|
||||
#define COLLIE_GPIO_AC_IN GPIO_GPIO (1)
|
||||
#define COLLIE_GPIO_SDIO_INT GPIO_GPIO (11)
|
||||
#define COLLIE_GPIO_CF_IRQ GPIO_GPIO (14)
|
||||
#define COLLIE_GPIO_nREMOCON_INT GPIO_GPIO (15)
|
||||
#define COLLIE_GPIO_UCB1x00_RESET GPIO_GPIO (16)
|
||||
#define COLLIE_GPIO_nMIC_ON GPIO_GPIO (17)
|
||||
#define COLLIE_GPIO_nREMOCON_ON GPIO_GPIO (18)
|
||||
#define COLLIE_GPIO_CO GPIO_GPIO (20)
|
||||
#define COLLIE_GPIO_MCP_CLK GPIO_GPIO (21)
|
||||
#define COLLIE_GPIO_CF_CD GPIO_GPIO (22)
|
||||
#define COLLIE_GPIO_UCB1x00_IRQ GPIO_GPIO (23)
|
||||
#define COLLIE_GPIO_WAKEUP GPIO_GPIO (24)
|
||||
#define COLLIE_GPIO_GA_INT GPIO_GPIO (25)
|
||||
#define COLLIE_GPIO_MAIN_BAT_LOW GPIO_GPIO (26)
|
||||
#define COLLIE_GPIO_ON_KEY (0)
|
||||
#define COLLIE_GPIO_AC_IN (1)
|
||||
#define COLLIE_GPIO_SDIO_INT (11)
|
||||
#define COLLIE_GPIO_CF_IRQ (14)
|
||||
#define COLLIE_GPIO_nREMOCON_INT (15)
|
||||
#define COLLIE_GPIO_UCB1x00_RESET (16)
|
||||
#define COLLIE_GPIO_nMIC_ON (17)
|
||||
#define COLLIE_GPIO_nREMOCON_ON (18)
|
||||
#define COLLIE_GPIO_CO (20)
|
||||
#define COLLIE_GPIO_MCP_CLK (21)
|
||||
#define COLLIE_GPIO_CF_CD (22)
|
||||
#define COLLIE_GPIO_UCB1x00_IRQ (23)
|
||||
#define COLLIE_GPIO_WAKEUP (24)
|
||||
#define COLLIE_GPIO_GA_INT (25)
|
||||
#define COLLIE_GPIO_MAIN_BAT_LOW (26)
|
||||
|
||||
/* GPIO definitions for direct register access */
|
||||
|
||||
#define _COLLIE_GPIO_ON_KEY GPIO_GPIO(0)
|
||||
#define _COLLIE_GPIO_AC_IN GPIO_GPIO(1)
|
||||
#define _COLLIE_GPIO_nREMOCON_INT GPIO_GPIO(15)
|
||||
#define _COLLIE_GPIO_UCB1x00_RESET GPIO_GPIO(16)
|
||||
#define _COLLIE_GPIO_nMIC_ON GPIO_GPIO(17)
|
||||
#define _COLLIE_GPIO_nREMOCON_ON GPIO_GPIO(18)
|
||||
#define _COLLIE_GPIO_CO GPIO_GPIO(20)
|
||||
#define _COLLIE_GPIO_WAKEUP GPIO_GPIO(24)
|
||||
/* Interrupts */
|
||||
|
||||
#define COLLIE_IRQ_GPIO_ON_KEY IRQ_GPIO0
|
||||
@ -70,19 +80,20 @@
|
||||
#define COLLIE_LCM_IRQ_GPIO_nSD_WP IRQ_LOCOMO_GPIO14
|
||||
|
||||
/* GPIO's on the TC35143AF (Toshiba Analog Frontend) */
|
||||
#define COLLIE_TC35143_GPIO_VERSION0 UCB_IO_0 /* GPIO0=Version */
|
||||
#define COLLIE_TC35143_GPIO_TBL_CHK UCB_IO_1 /* GPIO1=TBL_CHK */
|
||||
#define COLLIE_TC35143_GPIO_VPEN_ON UCB_IO_2 /* GPIO2=VPNE_ON */
|
||||
#define COLLIE_TC35143_GPIO_IR_ON UCB_IO_3 /* GPIO3=IR_ON */
|
||||
#define COLLIE_TC35143_GPIO_AMP_ON UCB_IO_4 /* GPIO4=AMP_ON */
|
||||
#define COLLIE_TC35143_GPIO_VERSION1 UCB_IO_5 /* GPIO5=Version */
|
||||
#define COLLIE_TC35143_GPIO_FS8KLPF UCB_IO_5 /* GPIO5=fs 8k LPF */
|
||||
#define COLLIE_TC35143_GPIO_BUZZER_BIAS UCB_IO_6 /* GPIO6=BUZZER BIAS */
|
||||
#define COLLIE_TC35143_GPIO_MBAT_ON UCB_IO_7 /* GPIO7=MBAT_ON */
|
||||
#define COLLIE_TC35143_GPIO_BBAT_ON UCB_IO_8 /* GPIO8=BBAT_ON */
|
||||
#define COLLIE_TC35143_GPIO_TMP_ON UCB_IO_9 /* GPIO9=TMP_ON */
|
||||
#define COLLIE_TC35143_GPIO_IN ( UCB_IO_0 | UCB_IO_2 | UCB_IO_5 )
|
||||
#define COLLIE_TC35143_GPIO_OUT ( UCB_IO_1 | UCB_IO_3 | UCB_IO_4 | UCB_IO_6 | \
|
||||
UCB_IO_7 | UCB_IO_8 | UCB_IO_9 )
|
||||
#define COLLIE_TC35143_GPIO_BASE (GPIO_MAX + 13)
|
||||
#define COLLIE_TC35143_GPIO_VERSION0 UCB_IO_0
|
||||
#define COLLIE_TC35143_GPIO_TBL_CHK UCB_IO_1
|
||||
#define COLLIE_TC35143_GPIO_VPEN_ON UCB_IO_2
|
||||
#define COLLIE_TC35143_GPIO_IR_ON UCB_IO_3
|
||||
#define COLLIE_TC35143_GPIO_AMP_ON UCB_IO_4
|
||||
#define COLLIE_TC35143_GPIO_VERSION1 UCB_IO_5
|
||||
#define COLLIE_TC35143_GPIO_FS8KLPF UCB_IO_5
|
||||
#define COLLIE_TC35143_GPIO_BUZZER_BIAS UCB_IO_6
|
||||
#define COLLIE_GPIO_MBAT_ON (COLLIE_TC35143_GPIO_BASE + 7)
|
||||
#define COLLIE_GPIO_BBAT_ON (COLLIE_TC35143_GPIO_BASE + 8)
|
||||
#define COLLIE_GPIO_TMP_ON (COLLIE_TC35143_GPIO_BASE + 9)
|
||||
#define COLLIE_TC35143_GPIO_IN (UCB_IO_0 | UCB_IO_2 | UCB_IO_5)
|
||||
#define COLLIE_TC35143_GPIO_OUT (UCB_IO_1 | UCB_IO_3 | UCB_IO_4 \
|
||||
| UCB_IO_6)
|
||||
|
||||
#endif
|
||||
|
@ -49,20 +49,9 @@ static inline void gpio_set_value(unsigned gpio, int value)
|
||||
|
||||
#define gpio_cansleep __gpio_cansleep
|
||||
|
||||
static inline unsigned gpio_to_irq(unsigned gpio)
|
||||
{
|
||||
if (gpio < 11)
|
||||
return IRQ_GPIO0 + gpio;
|
||||
else
|
||||
return IRQ_GPIO11 - 11 + gpio;
|
||||
}
|
||||
|
||||
static inline unsigned irq_to_gpio(unsigned irq)
|
||||
{
|
||||
if (irq < IRQ_GPIO11_27)
|
||||
return irq - IRQ_GPIO0;
|
||||
else
|
||||
return irq - IRQ_GPIO11 + 11;
|
||||
}
|
||||
#define gpio_to_irq(gpio) ((gpio < 11) ? (IRQ_GPIO0 + gpio) : \
|
||||
(IRQ_GPIO11 - 11 + gpio))
|
||||
#define irq_to_gpio(irq) ((irq < IRQ_GPIO11_27) ? (irq - IRQ_GPIO0) : \
|
||||
(irq - IRQ_GPIO11 + 11))
|
||||
|
||||
#endif
|
||||
|
@ -1,100 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* Definitions for H3600 Handheld Computer
|
||||
*
|
||||
* Copyright 2000 Compaq Computer Corporation.
|
||||
*
|
||||
* Use consistent with the GNU GPL is permitted,
|
||||
* provided that this copyright notice is
|
||||
* preserved in its entirety in all copies and derived works.
|
||||
*
|
||||
* COMPAQ COMPUTER CORPORATION MAKES NO WARRANTIES, EXPRESSED OR IMPLIED,
|
||||
* AS TO THE USEFULNESS OR CORRECTNESS OF THIS CODE OR ITS
|
||||
* FITNESS FOR ANY PARTICULAR PURPOSE.
|
||||
*
|
||||
* Author: Jamey Hicks.
|
||||
*
|
||||
* History:
|
||||
*
|
||||
* 2001-10-?? Andrew Christian Added support for iPAQ H3800
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _INCLUDE_H3600_H_
|
||||
#define _INCLUDE_H3600_H_
|
||||
|
||||
typedef int __bitwise pm_request_t;
|
||||
|
||||
#define PM_SUSPEND ((__force pm_request_t) 1) /* enter D1-D3 */
|
||||
#define PM_RESUME ((__force pm_request_t) 2) /* enter D0 */
|
||||
|
||||
/* generalized support for H3xxx series Compaq Pocket PC's */
|
||||
#define machine_is_h3xxx() (machine_is_h3100() || machine_is_h3600())
|
||||
|
||||
/* Physical memory regions corresponding to chip selects */
|
||||
#define H3600_EGPIO_PHYS (SA1100_CS5_PHYS + 0x01000000)
|
||||
#define H3600_BANK_2_PHYS SA1100_CS2_PHYS
|
||||
#define H3600_BANK_4_PHYS SA1100_CS4_PHYS
|
||||
|
||||
/* Virtual memory regions corresponding to chip selects 2 & 4 (used on sleeves) */
|
||||
#define H3600_EGPIO_VIRT 0xf0000000
|
||||
#define H3600_BANK_2_VIRT 0xf1000000
|
||||
#define H3600_BANK_4_VIRT 0xf3800000
|
||||
|
||||
/*
|
||||
Machine-independent GPIO definitions
|
||||
--- these are common across all current iPAQ platforms
|
||||
*/
|
||||
|
||||
#define GPIO_H3600_NPOWER_BUTTON GPIO_GPIO (0) /* Also known as the "off button" */
|
||||
|
||||
#define GPIO_H3600_PCMCIA_CD1 GPIO_GPIO (10)
|
||||
#define GPIO_H3600_PCMCIA_IRQ1 GPIO_GPIO (11)
|
||||
|
||||
/* UDA1341 L3 Interface */
|
||||
#define GPIO_H3600_L3_DATA GPIO_GPIO (14)
|
||||
#define GPIO_H3600_L3_MODE GPIO_GPIO (15)
|
||||
#define GPIO_H3600_L3_CLOCK GPIO_GPIO (16)
|
||||
|
||||
#define GPIO_H3600_PCMCIA_CD0 GPIO_GPIO (17)
|
||||
#define GPIO_H3600_SYS_CLK GPIO_GPIO (19)
|
||||
#define GPIO_H3600_PCMCIA_IRQ0 GPIO_GPIO (21)
|
||||
|
||||
#define GPIO_H3600_COM_DCD GPIO_GPIO (23)
|
||||
#define GPIO_H3600_OPT_IRQ GPIO_GPIO (24)
|
||||
#define GPIO_H3600_COM_CTS GPIO_GPIO (25)
|
||||
#define GPIO_H3600_COM_RTS GPIO_GPIO (26)
|
||||
|
||||
#define IRQ_GPIO_H3600_NPOWER_BUTTON IRQ_GPIO0
|
||||
#define IRQ_GPIO_H3600_PCMCIA_CD1 IRQ_GPIO10
|
||||
#define IRQ_GPIO_H3600_PCMCIA_IRQ1 IRQ_GPIO11
|
||||
#define IRQ_GPIO_H3600_PCMCIA_CD0 IRQ_GPIO17
|
||||
#define IRQ_GPIO_H3600_PCMCIA_IRQ0 IRQ_GPIO21
|
||||
#define IRQ_GPIO_H3600_COM_DCD IRQ_GPIO23
|
||||
#define IRQ_GPIO_H3600_OPT_IRQ IRQ_GPIO24
|
||||
#define IRQ_GPIO_H3600_COM_CTS IRQ_GPIO25
|
||||
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
enum ipaq_egpio_type {
|
||||
IPAQ_EGPIO_LCD_POWER, /* Power to the LCD panel */
|
||||
IPAQ_EGPIO_CODEC_NRESET, /* Clear to reset the audio codec (remember to return high) */
|
||||
IPAQ_EGPIO_AUDIO_ON, /* Audio power */
|
||||
IPAQ_EGPIO_QMUTE, /* Audio muting */
|
||||
IPAQ_EGPIO_OPT_NVRAM_ON, /* Non-volatile RAM on extension sleeves (SPI interface) */
|
||||
IPAQ_EGPIO_OPT_ON, /* Power to extension sleeves */
|
||||
IPAQ_EGPIO_CARD_RESET, /* Reset PCMCIA cards on extension sleeve (???) */
|
||||
IPAQ_EGPIO_OPT_RESET, /* Reset option pack (???) */
|
||||
IPAQ_EGPIO_IR_ON, /* IR sensor/emitter power */
|
||||
IPAQ_EGPIO_IR_FSEL, /* IR speed selection 1->fast, 0->slow */
|
||||
IPAQ_EGPIO_RS232_ON, /* Maxim RS232 chip power */
|
||||
IPAQ_EGPIO_VPP_ON, /* Turn on power to flash programming */
|
||||
IPAQ_EGPIO_LCD_ENABLE, /* Enable/disable LCD controller */
|
||||
};
|
||||
|
||||
extern void (*assign_h3600_egpio)(enum ipaq_egpio_type x, int level);
|
||||
|
||||
#endif /* ASSEMBLY */
|
||||
|
||||
#endif /* _INCLUDE_H3600_H_ */
|
@ -1,77 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* Definitions for H3600 Handheld Computer
|
||||
*
|
||||
* Copyright 2000 Compaq Computer Corporation.
|
||||
*
|
||||
* Use consistent with the GNU GPL is permitted,
|
||||
* provided that this copyright notice is
|
||||
* preserved in its entirety in all copies and derived works.
|
||||
*
|
||||
* COMPAQ COMPUTER CORPORATION MAKES NO WARRANTIES, EXPRESSED OR IMPLIED,
|
||||
* AS TO THE USEFULNESS OR CORRECTNESS OF THIS CODE OR ITS
|
||||
* FITNESS FOR ANY PARTICULAR PURPOSE.
|
||||
*
|
||||
* Author: Jamey Hicks.
|
||||
*
|
||||
* History:
|
||||
*
|
||||
* 2001-10-?? Andrew Christian Added support for iPAQ H3800
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _INCLUDE_H3600_GPIO_H_
|
||||
#define _INCLUDE_H3600_GPIO_H_
|
||||
|
||||
/*
|
||||
* GPIO lines that are common across ALL iPAQ models are in "h3600.h"
|
||||
* This file contains machine-specific definitions
|
||||
*/
|
||||
|
||||
#define GPIO_H3600_SUSPEND GPIO_GPIO (0)
|
||||
/* GPIO[2:9] used by LCD on H3600/3800, used as GPIO on H3100 */
|
||||
#define GPIO_H3100_BT_ON GPIO_GPIO (2)
|
||||
#define GPIO_H3100_GPIO3 GPIO_GPIO (3)
|
||||
#define GPIO_H3100_QMUTE GPIO_GPIO (4)
|
||||
#define GPIO_H3100_LCD_3V_ON GPIO_GPIO (5)
|
||||
#define GPIO_H3100_AUD_ON GPIO_GPIO (6)
|
||||
#define GPIO_H3100_AUD_PWR_ON GPIO_GPIO (7)
|
||||
#define GPIO_H3100_IR_ON GPIO_GPIO (8)
|
||||
#define GPIO_H3100_IR_FSEL GPIO_GPIO (9)
|
||||
|
||||
/* for H3600, audio sample rate clock generator */
|
||||
#define GPIO_H3600_CLK_SET0 GPIO_GPIO (12)
|
||||
#define GPIO_H3600_CLK_SET1 GPIO_GPIO (13)
|
||||
|
||||
#define GPIO_H3600_ACTION_BUTTON GPIO_GPIO (18)
|
||||
#define GPIO_H3600_SOFT_RESET GPIO_GPIO (20) /* Also known as BATT_FAULT */
|
||||
#define GPIO_H3600_OPT_LOCK GPIO_GPIO (22)
|
||||
#define GPIO_H3600_OPT_DET GPIO_GPIO (27)
|
||||
|
||||
/****************************************************/
|
||||
|
||||
#define IRQ_GPIO_H3600_ACTION_BUTTON IRQ_GPIO18
|
||||
#define IRQ_GPIO_H3600_OPT_DET IRQ_GPIO27
|
||||
|
||||
/* H3100 / 3600 EGPIO pins */
|
||||
#define EGPIO_H3600_VPP_ON (1 << 0)
|
||||
#define EGPIO_H3600_CARD_RESET (1 << 1) /* reset the attached pcmcia/compactflash card. active high. */
|
||||
#define EGPIO_H3600_OPT_RESET (1 << 2) /* reset the attached option pack. active high. */
|
||||
#define EGPIO_H3600_CODEC_NRESET (1 << 3) /* reset the onboard UDA1341. active low. */
|
||||
#define EGPIO_H3600_OPT_NVRAM_ON (1 << 4) /* apply power to optionpack nvram, active high. */
|
||||
#define EGPIO_H3600_OPT_ON (1 << 5) /* full power to option pack. active high. */
|
||||
#define EGPIO_H3600_LCD_ON (1 << 6) /* enable 3.3V to LCD. active high. */
|
||||
#define EGPIO_H3600_RS232_ON (1 << 7) /* UART3 transceiver force on. Active high. */
|
||||
|
||||
/* H3600 only EGPIO pins */
|
||||
#define EGPIO_H3600_LCD_PCI (1 << 8) /* LCD control IC enable. active high. */
|
||||
#define EGPIO_H3600_IR_ON (1 << 9) /* apply power to IR module. active high. */
|
||||
#define EGPIO_H3600_AUD_AMP_ON (1 << 10) /* apply power to audio power amp. active high. */
|
||||
#define EGPIO_H3600_AUD_PWR_ON (1 << 11) /* apply power to reset of audio circuit. active high. */
|
||||
#define EGPIO_H3600_QMUTE (1 << 12) /* mute control for onboard UDA1341. active high. */
|
||||
#define EGPIO_H3600_IR_FSEL (1 << 13) /* IR speed select: 1->fast, 0->slow */
|
||||
#define EGPIO_H3600_LCD_5V_ON (1 << 14) /* enable 5V to LCD. active high. */
|
||||
#define EGPIO_H3600_LVDD_ON (1 << 15) /* enable 9V and -6.5V to LCD. */
|
||||
|
||||
|
||||
#endif /* _INCLUDE_H3600_GPIO_H_ */
|
94
arch/arm/mach-sa1100/include/mach/h3xxx.h
Normal file
94
arch/arm/mach-sa1100/include/mach/h3xxx.h
Normal file
@ -0,0 +1,94 @@
|
||||
/*
|
||||
* Definitions for Compaq iPAQ H3100 and H3600 handheld computers
|
||||
*
|
||||
* (c) 2000 Compaq Computer Corporation. (Author: Jamey Hicks)
|
||||
* (c) 2009 Dmitry Artamonow <mad_soft@inbox.ru>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _INCLUDE_H3XXX_H_
|
||||
#define _INCLUDE_H3XXX_H_
|
||||
|
||||
/* Physical memory regions corresponding to chip selects */
|
||||
#define H3600_EGPIO_PHYS (SA1100_CS5_PHYS + 0x01000000)
|
||||
#define H3600_BANK_2_PHYS SA1100_CS2_PHYS
|
||||
#define H3600_BANK_4_PHYS SA1100_CS4_PHYS
|
||||
|
||||
/* Virtual memory regions corresponding to chip selects 2 & 4 (used on sleeves) */
|
||||
#define H3600_EGPIO_VIRT 0xf0000000
|
||||
#define H3600_BANK_2_VIRT 0xf1000000
|
||||
#define H3600_BANK_4_VIRT 0xf3800000
|
||||
|
||||
/*
|
||||
* gpiolib numbers for all iPAQs
|
||||
*/
|
||||
#define H3XXX_GPIO_PWR_BUTTON 0
|
||||
#define H3XXX_GPIO_PCMCIA_CD1 10
|
||||
#define H3XXX_GPIO_PCMCIA_IRQ1 11
|
||||
#define H3XXX_GPIO_PCMCIA_CD0 17
|
||||
#define H3XXX_GPIO_ACTION_BUTTON 18
|
||||
#define H3XXX_GPIO_SYS_CLK 19
|
||||
#define H3XXX_GPIO_PCMCIA_IRQ0 21
|
||||
#define H3XXX_GPIO_COM_DCD 23
|
||||
#define H3XXX_GPIO_OPTION 24
|
||||
#define H3XXX_GPIO_COM_CTS 25
|
||||
#define H3XXX_GPIO_COM_RTS 26
|
||||
|
||||
/* machine-specific gpios */
|
||||
|
||||
#define H3100_GPIO_BT_ON 2
|
||||
#define H3100_GPIO_QMUTE 4
|
||||
#define H3100_GPIO_LCD_3V_ON 5
|
||||
#define H3100_GPIO_AUD_ON 6
|
||||
#define H3100_GPIO_AUD_PWR_ON 7
|
||||
#define H3100_GPIO_IR_ON 8
|
||||
#define H3100_GPIO_IR_FSEL 9
|
||||
|
||||
#define H3600_GPIO_CLK_SET0 12 /* audio sample rate clock generator */
|
||||
#define H3600_GPIO_CLK_SET1 13
|
||||
#define H3600_GPIO_SOFT_RESET 20 /* also known as BATT_FAULT */
|
||||
#define H3600_GPIO_OPT_LOCK 22
|
||||
#define H3600_GPIO_OPT_DET 27
|
||||
|
||||
|
||||
/* H3100 / 3600 EGPIO pins */
|
||||
#define H3XXX_EGPIO_BASE (GPIO_MAX + 1)
|
||||
|
||||
#define H3XXX_EGPIO_VPP_ON (H3XXX_EGPIO_BASE + 0)
|
||||
#define H3XXX_EGPIO_CARD_RESET (H3XXX_EGPIO_BASE + 1) /* reset the attached pcmcia/compactflash card. active high. */
|
||||
#define H3XXX_EGPIO_OPT_RESET (H3XXX_EGPIO_BASE + 2) /* reset the attached option pack. active high. */
|
||||
#define H3XXX_EGPIO_CODEC_NRESET (H3XXX_EGPIO_BASE + 3) /* reset the onboard UDA1341. active low. */
|
||||
#define H3XXX_EGPIO_OPT_NVRAM_ON (H3XXX_EGPIO_BASE + 4) /* apply power to optionpack nvram, active high. */
|
||||
#define H3XXX_EGPIO_OPT_ON (H3XXX_EGPIO_BASE + 5) /* full power to option pack. active high. */
|
||||
#define H3XXX_EGPIO_LCD_ON (H3XXX_EGPIO_BASE + 6) /* enable 3.3V to LCD. active high. */
|
||||
#define H3XXX_EGPIO_RS232_ON (H3XXX_EGPIO_BASE + 7) /* UART3 transceiver force on. Active high. */
|
||||
|
||||
/* H3600 only EGPIO pins */
|
||||
#define H3600_EGPIO_LCD_PCI (H3XXX_EGPIO_BASE + 8) /* LCD control IC enable. active high. */
|
||||
#define H3600_EGPIO_IR_ON (H3XXX_EGPIO_BASE + 9) /* apply power to IR module. active high. */
|
||||
#define H3600_EGPIO_AUD_AMP_ON (H3XXX_EGPIO_BASE + 10) /* apply power to audio power amp. active high. */
|
||||
#define H3600_EGPIO_AUD_PWR_ON (H3XXX_EGPIO_BASE + 11) /* apply power to reset of audio circuit. active high. */
|
||||
#define H3600_EGPIO_QMUTE (H3XXX_EGPIO_BASE + 12) /* mute control for onboard UDA1341. active high. */
|
||||
#define H3600_EGPIO_IR_FSEL (H3XXX_EGPIO_BASE + 13) /* IR speed select: 1->fast, 0->slow */
|
||||
#define H3600_EGPIO_LCD_5V_ON (H3XXX_EGPIO_BASE + 14) /* enable 5V to LCD. active high. */
|
||||
#define H3600_EGPIO_LVDD_ON (H3XXX_EGPIO_BASE + 15) /* enable 9V and -6.5V to LCD. */
|
||||
|
||||
struct gpio_default_state {
|
||||
int gpio;
|
||||
int mode;
|
||||
const char *name;
|
||||
};
|
||||
|
||||
#define GPIO_MODE_IN -1
|
||||
#define GPIO_MODE_OUT0 0
|
||||
#define GPIO_MODE_OUT1 1
|
||||
|
||||
void h3xxx_init_gpio(struct gpio_default_state *s, size_t n);
|
||||
void __init h3xxx_map_io(void);
|
||||
void __init h3xxx_mach_init(void);
|
||||
|
||||
#endif /* _INCLUDE_H3XXX_H_ */
|
@ -16,6 +16,7 @@ struct mcp_plat_data {
|
||||
u32 mccr0;
|
||||
u32 mccr1;
|
||||
unsigned int sclk_rate;
|
||||
int gpio_base;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -354,7 +354,7 @@ static struct resource jornada720_flash_resource = {
|
||||
|
||||
static void __init jornada720_mach_init(void)
|
||||
{
|
||||
sa11x0_set_flash_data(&jornada720_flash_data, &jornada720_flash_resource, 1);
|
||||
sa11x0_register_mtd(&jornada720_flash_data, &jornada720_flash_resource, 1);
|
||||
}
|
||||
|
||||
MACHINE_START(JORNADA720, "HP Jornada 720")
|
||||
|
@ -28,7 +28,7 @@ static struct mcp_plat_data lart_mcp_data = {
|
||||
|
||||
static void __init lart_init(void)
|
||||
{
|
||||
sa11x0_set_mcp_data(&lart_mcp_data);
|
||||
sa11x0_register_mcp(&lart_mcp_data);
|
||||
}
|
||||
|
||||
static struct map_desc lart_io_desc[] __initdata = {
|
||||
|
@ -109,7 +109,7 @@ static struct flash_platform_data pleb_flash_data = {
|
||||
|
||||
static void __init pleb_init(void)
|
||||
{
|
||||
sa11x0_set_flash_data(&pleb_flash_data, pleb_flash_resources,
|
||||
sa11x0_register_mtd(&pleb_flash_data, pleb_flash_resources,
|
||||
ARRAY_SIZE(pleb_flash_resources));
|
||||
|
||||
|
||||
|
@ -59,8 +59,8 @@ static struct mcp_plat_data shannon_mcp_data = {
|
||||
|
||||
static void __init shannon_init(void)
|
||||
{
|
||||
sa11x0_set_flash_data(&shannon_flash_data, &shannon_flash_resource, 1);
|
||||
sa11x0_set_mcp_data(&shannon_mcp_data);
|
||||
sa11x0_register_mtd(&shannon_flash_data, &shannon_flash_resource, 1);
|
||||
sa11x0_register_mcp(&shannon_mcp_data);
|
||||
}
|
||||
|
||||
static void __init shannon_map_io(void)
|
||||
|
@ -166,9 +166,9 @@ static void __init simpad_map_io(void)
|
||||
PCFR = 0;
|
||||
PSDR = 0;
|
||||
|
||||
sa11x0_set_flash_data(&simpad_flash_data, simpad_flash_resources,
|
||||
sa11x0_register_mtd(&simpad_flash_data, simpad_flash_resources,
|
||||
ARRAY_SIZE(simpad_flash_resources));
|
||||
sa11x0_set_mcp_data(&simpad_mcp_data);
|
||||
sa11x0_register_mcp(&simpad_mcp_data);
|
||||
}
|
||||
|
||||
static void simpad_power_off(void)
|
||||
|
@ -52,7 +52,7 @@
|
||||
#define BUG() \
|
||||
do { \
|
||||
_BUG_OR_WARN(0); \
|
||||
for (;;); \
|
||||
unreachable(); \
|
||||
} while (0)
|
||||
|
||||
#define WARN_ON(condition) \
|
||||
|
@ -4,8 +4,6 @@
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/swiotlb.h>
|
||||
|
||||
extern int swiotlb_force;
|
||||
|
||||
#ifdef CONFIG_SWIOTLB
|
||||
extern int swiotlb;
|
||||
extern void pci_swiotlb_init(void);
|
||||
|
@ -41,7 +41,7 @@ struct dma_map_ops swiotlb_dma_ops = {
|
||||
void __init swiotlb_dma_init(void)
|
||||
{
|
||||
dma_ops = &swiotlb_dma_ops;
|
||||
swiotlb_init();
|
||||
swiotlb_init(1);
|
||||
}
|
||||
|
||||
void __init pci_swiotlb_init(void)
|
||||
@ -51,7 +51,7 @@ void __init pci_swiotlb_init(void)
|
||||
swiotlb = 1;
|
||||
printk(KERN_INFO "PCI-DMA: Re-initialize machine vector.\n");
|
||||
machvec_init("dig");
|
||||
swiotlb_init();
|
||||
swiotlb_init(1);
|
||||
dma_ops = &swiotlb_dma_ops;
|
||||
#else
|
||||
panic("Unable to find Intel IOMMU");
|
||||
|
@ -358,7 +358,14 @@ config SGI_IP22
|
||||
select SWAP_IO_SPACE
|
||||
select SYS_HAS_CPU_R4X00
|
||||
select SYS_HAS_CPU_R5000
|
||||
select SYS_HAS_EARLY_PRINTK
|
||||
#
|
||||
# Disable EARLY_PRINTK for now since it leads to overwritten prom
|
||||
# memory during early boot on some machines.
|
||||
#
|
||||
# See http://www.linux-mips.org/cgi-bin/mesg.cgi?a=linux-mips&i=20091119164009.GA15038%40deprecation.cyrius.com
|
||||
# for a more details discussion
|
||||
#
|
||||
# select SYS_HAS_EARLY_PRINTK
|
||||
select SYS_SUPPORTS_32BIT_KERNEL
|
||||
select SYS_SUPPORTS_64BIT_KERNEL
|
||||
select SYS_SUPPORTS_BIG_ENDIAN
|
||||
@ -410,7 +417,14 @@ config SGI_IP28
|
||||
select SGI_HAS_ZILOG
|
||||
select SWAP_IO_SPACE
|
||||
select SYS_HAS_CPU_R10000
|
||||
select SYS_HAS_EARLY_PRINTK
|
||||
#
|
||||
# Disable EARLY_PRINTK for now since it leads to overwritten prom
|
||||
# memory during early boot on some machines.
|
||||
#
|
||||
# See http://www.linux-mips.org/cgi-bin/mesg.cgi?a=linux-mips&i=20091119164009.GA15038%40deprecation.cyrius.com
|
||||
# for a more details discussion
|
||||
#
|
||||
# select SYS_HAS_EARLY_PRINTK
|
||||
select SYS_SUPPORTS_64BIT_KERNEL
|
||||
select SYS_SUPPORTS_BIG_ENDIAN
|
||||
help
|
||||
@ -1439,6 +1453,7 @@ choice
|
||||
|
||||
config PAGE_SIZE_4KB
|
||||
bool "4kB"
|
||||
depends on !CPU_LOONGSON2
|
||||
help
|
||||
This option select the standard 4kB Linux page size. On some
|
||||
R3000-family processors this is the only available page size. Using
|
||||
@ -1763,7 +1778,7 @@ config SYS_SUPPORTS_SMARTMIPS
|
||||
|
||||
config ARCH_FLATMEM_ENABLE
|
||||
def_bool y
|
||||
depends on !NUMA
|
||||
depends on !NUMA && !CPU_LOONGSON2
|
||||
|
||||
config ARCH_DISCONTIGMEM_ENABLE
|
||||
bool
|
||||
|
@ -11,9 +11,7 @@
|
||||
static inline void __noreturn BUG(void)
|
||||
{
|
||||
__asm__ __volatile__("break %0" : : "i" (BRK_BUG));
|
||||
/* Fool GCC into thinking the function doesn't return. */
|
||||
while (1)
|
||||
;
|
||||
unreachable();
|
||||
}
|
||||
|
||||
#define HAVE_ARCH_BUG
|
||||
|
@ -75,6 +75,7 @@
|
||||
|
||||
#define MADV_MERGEABLE 12 /* KSM may merge identical pages */
|
||||
#define MADV_UNMERGEABLE 13 /* KSM may not merge identical pages */
|
||||
#define MADV_HWPOISON 100 /* poison a page for testing */
|
||||
|
||||
/* compatibility flags */
|
||||
#define MAP_FILE 0
|
||||
|
@ -12,6 +12,7 @@
|
||||
#ifndef _ASM_SYSTEM_H
|
||||
#define _ASM_SYSTEM_H
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/irqflags.h>
|
||||
|
||||
@ -193,10 +194,6 @@ extern __u64 __xchg_u64_unsupported_on_32bit_kernels(volatile __u64 * m, __u64 v
|
||||
#define __xchg_u64 __xchg_u64_unsupported_on_32bit_kernels
|
||||
#endif
|
||||
|
||||
/* This function doesn't exist, so you'll get a linker error
|
||||
if something tries to do an invalid xchg(). */
|
||||
extern void __xchg_called_with_bad_pointer(void);
|
||||
|
||||
static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int size)
|
||||
{
|
||||
switch (size) {
|
||||
@ -205,11 +202,17 @@ static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int siz
|
||||
case 8:
|
||||
return __xchg_u64(ptr, x);
|
||||
}
|
||||
__xchg_called_with_bad_pointer();
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
#define xchg(ptr, x) ((__typeof__(*(ptr)))__xchg((unsigned long)(x), (ptr), sizeof(*(ptr))))
|
||||
#define xchg(ptr, x) \
|
||||
({ \
|
||||
BUILD_BUG_ON(sizeof(*(ptr)) & ~0xc); \
|
||||
\
|
||||
((__typeof__(*(ptr))) \
|
||||
__xchg((unsigned long)(x), (ptr), sizeof(*(ptr)))); \
|
||||
})
|
||||
|
||||
extern void set_handler(unsigned long offset, void *addr, unsigned long len);
|
||||
extern void set_uncached_handler(unsigned long offset, void *addr, unsigned long len);
|
||||
|
@ -306,6 +306,7 @@ static inline int mips_atomic_set(struct pt_regs *regs,
|
||||
|
||||
if (cpu_has_llsc && R10000_LLSC_WAR) {
|
||||
__asm__ __volatile__ (
|
||||
" .set mips3 \n"
|
||||
" li %[err], 0 \n"
|
||||
"1: ll %[old], (%[addr]) \n"
|
||||
" move %[tmp], %[new] \n"
|
||||
@ -320,6 +321,7 @@ static inline int mips_atomic_set(struct pt_regs *regs,
|
||||
" "STR(PTR)" 1b, 4b \n"
|
||||
" "STR(PTR)" 2b, 4b \n"
|
||||
" .previous \n"
|
||||
" .set mips0 \n"
|
||||
: [old] "=&r" (old),
|
||||
[err] "=&r" (err),
|
||||
[tmp] "=&r" (tmp)
|
||||
@ -329,6 +331,7 @@ static inline int mips_atomic_set(struct pt_regs *regs,
|
||||
: "memory");
|
||||
} else if (cpu_has_llsc) {
|
||||
__asm__ __volatile__ (
|
||||
" .set mips3 \n"
|
||||
" li %[err], 0 \n"
|
||||
"1: ll %[old], (%[addr]) \n"
|
||||
" move %[tmp], %[new] \n"
|
||||
@ -347,6 +350,7 @@ static inline int mips_atomic_set(struct pt_regs *regs,
|
||||
" "STR(PTR)" 1b, 5b \n"
|
||||
" "STR(PTR)" 2b, 5b \n"
|
||||
" .previous \n"
|
||||
" .set mips0 \n"
|
||||
: [old] "=&r" (old),
|
||||
[err] "=&r" (err),
|
||||
[tmp] "=&r" (tmp)
|
||||
|
@ -110,7 +110,6 @@ static struct korina_device korina_dev0_data = {
|
||||
static struct platform_device korina_dev0 = {
|
||||
.id = -1,
|
||||
.name = "korina",
|
||||
.dev.driver_data = &korina_dev0_data,
|
||||
.resource = korina_dev0_res,
|
||||
.num_resources = ARRAY_SIZE(korina_dev0_res),
|
||||
};
|
||||
@ -332,6 +331,8 @@ static int __init plat_setup_devices(void)
|
||||
/* set the uart clock to the current cpu frequency */
|
||||
rb532_uart_res[0].uartclk = idt_cpu_freq;
|
||||
|
||||
dev_set_drvdata(&korina_dev0.dev, &korina_dev0_data);
|
||||
|
||||
return platform_add_devices(rb532_devs, ARRAY_SIZE(rb532_devs));
|
||||
}
|
||||
|
||||
|
@ -46,7 +46,7 @@ config DEBUG_STACK_USAGE
|
||||
|
||||
config HCALL_STATS
|
||||
bool "Hypervisor call instrumentation"
|
||||
depends on PPC_PSERIES && DEBUG_FS
|
||||
depends on PPC_PSERIES && DEBUG_FS && TRACEPOINTS
|
||||
help
|
||||
Adds code to keep track of the number of hypervisor calls made and
|
||||
the amount of time spent in hypervisor calls. Wall time spent in
|
||||
|
@ -1683,7 +1683,7 @@ CONFIG_HAVE_ARCH_KGDB=y
|
||||
CONFIG_DEBUG_STACKOVERFLOW=y
|
||||
# CONFIG_DEBUG_STACK_USAGE is not set
|
||||
# CONFIG_DEBUG_PAGEALLOC is not set
|
||||
CONFIG_HCALL_STATS=y
|
||||
# CONFIG_HCALL_STATS is not set
|
||||
# CONFIG_CODE_PATCHING_SELFTEST is not set
|
||||
# CONFIG_FTR_FIXUP_SELFTEST is not set
|
||||
# CONFIG_MSI_BITMAP_SELFTEST is not set
|
||||
|
@ -19,6 +19,7 @@
|
||||
#define _ASM_POWERPC_EMULATED_OPS_H
|
||||
|
||||
#include <asm/atomic.h>
|
||||
#include <linux/perf_event.h>
|
||||
|
||||
|
||||
#ifdef CONFIG_PPC_EMULATED_STATS
|
||||
@ -57,7 +58,7 @@ extern u32 ppc_warn_emulated;
|
||||
|
||||
extern void ppc_warn_emulated_print(const char *type);
|
||||
|
||||
#define PPC_WARN_EMULATED(type) \
|
||||
#define __PPC_WARN_EMULATED(type) \
|
||||
do { \
|
||||
atomic_inc(&ppc_emulated.type.val); \
|
||||
if (ppc_warn_emulated) \
|
||||
@ -66,8 +67,22 @@ extern void ppc_warn_emulated_print(const char *type);
|
||||
|
||||
#else /* !CONFIG_PPC_EMULATED_STATS */
|
||||
|
||||
#define PPC_WARN_EMULATED(type) do { } while (0)
|
||||
#define __PPC_WARN_EMULATED(type) do { } while (0)
|
||||
|
||||
#endif /* !CONFIG_PPC_EMULATED_STATS */
|
||||
|
||||
#define PPC_WARN_EMULATED(type, regs) \
|
||||
do { \
|
||||
perf_sw_event(PERF_COUNT_SW_EMULATION_FAULTS, \
|
||||
1, 0, regs, 0); \
|
||||
__PPC_WARN_EMULATED(type); \
|
||||
} while (0)
|
||||
|
||||
#define PPC_WARN_ALIGNMENT(type, regs) \
|
||||
do { \
|
||||
perf_sw_event(PERF_COUNT_SW_ALIGNMENT_FAULTS, \
|
||||
1, 0, regs, regs->dar); \
|
||||
__PPC_WARN_EMULATED(type); \
|
||||
} while (0)
|
||||
|
||||
#endif /* _ASM_POWERPC_EMULATED_OPS_H */
|
||||
|
@ -274,6 +274,8 @@ struct hcall_stats {
|
||||
unsigned long num_calls; /* number of calls (on this CPU) */
|
||||
unsigned long tb_total; /* total wall time (mftb) of calls. */
|
||||
unsigned long purr_total; /* total cpu time (PURR) of calls. */
|
||||
unsigned long tb_start;
|
||||
unsigned long purr_start;
|
||||
};
|
||||
#define HCALL_STAT_ARRAY_SIZE ((MAX_HCALL_OPCODE >> 2) + 1)
|
||||
|
||||
|
@ -489,6 +489,8 @@
|
||||
#define SPRN_MMCR1 798
|
||||
#define SPRN_MMCRA 0x312
|
||||
#define MMCRA_SDSYNC 0x80000000UL /* SDAR synced with SIAR */
|
||||
#define MMCRA_SDAR_DCACHE_MISS 0x40000000UL
|
||||
#define MMCRA_SDAR_ERAT_MISS 0x20000000UL
|
||||
#define MMCRA_SIHV 0x10000000UL /* state of MSR HV when SIAR set */
|
||||
#define MMCRA_SIPR 0x08000000UL /* state of MSR PR when SIAR set */
|
||||
#define MMCRA_SLOT 0x07000000UL /* SLOT bits (37-39) */
|
||||
|
133
arch/powerpc/include/asm/trace.h
Normal file
133
arch/powerpc/include/asm/trace.h
Normal file
@ -0,0 +1,133 @@
|
||||
#undef TRACE_SYSTEM
|
||||
#define TRACE_SYSTEM powerpc
|
||||
|
||||
#if !defined(_TRACE_POWERPC_H) || defined(TRACE_HEADER_MULTI_READ)
|
||||
#define _TRACE_POWERPC_H
|
||||
|
||||
#include <linux/tracepoint.h>
|
||||
|
||||
struct pt_regs;
|
||||
|
||||
TRACE_EVENT(irq_entry,
|
||||
|
||||
TP_PROTO(struct pt_regs *regs),
|
||||
|
||||
TP_ARGS(regs),
|
||||
|
||||
TP_STRUCT__entry(
|
||||
__field(struct pt_regs *, regs)
|
||||
),
|
||||
|
||||
TP_fast_assign(
|
||||
__entry->regs = regs;
|
||||
),
|
||||
|
||||
TP_printk("pt_regs=%p", __entry->regs)
|
||||
);
|
||||
|
||||
TRACE_EVENT(irq_exit,
|
||||
|
||||
TP_PROTO(struct pt_regs *regs),
|
||||
|
||||
TP_ARGS(regs),
|
||||
|
||||
TP_STRUCT__entry(
|
||||
__field(struct pt_regs *, regs)
|
||||
),
|
||||
|
||||
TP_fast_assign(
|
||||
__entry->regs = regs;
|
||||
),
|
||||
|
||||
TP_printk("pt_regs=%p", __entry->regs)
|
||||
);
|
||||
|
||||
TRACE_EVENT(timer_interrupt_entry,
|
||||
|
||||
TP_PROTO(struct pt_regs *regs),
|
||||
|
||||
TP_ARGS(regs),
|
||||
|
||||
TP_STRUCT__entry(
|
||||
__field(struct pt_regs *, regs)
|
||||
),
|
||||
|
||||
TP_fast_assign(
|
||||
__entry->regs = regs;
|
||||
),
|
||||
|
||||
TP_printk("pt_regs=%p", __entry->regs)
|
||||
);
|
||||
|
||||
TRACE_EVENT(timer_interrupt_exit,
|
||||
|
||||
TP_PROTO(struct pt_regs *regs),
|
||||
|
||||
TP_ARGS(regs),
|
||||
|
||||
TP_STRUCT__entry(
|
||||
__field(struct pt_regs *, regs)
|
||||
),
|
||||
|
||||
TP_fast_assign(
|
||||
__entry->regs = regs;
|
||||
),
|
||||
|
||||
TP_printk("pt_regs=%p", __entry->regs)
|
||||
);
|
||||
|
||||
#ifdef CONFIG_PPC_PSERIES
|
||||
extern void hcall_tracepoint_regfunc(void);
|
||||
extern void hcall_tracepoint_unregfunc(void);
|
||||
|
||||
TRACE_EVENT_FN(hcall_entry,
|
||||
|
||||
TP_PROTO(unsigned long opcode, unsigned long *args),
|
||||
|
||||
TP_ARGS(opcode, args),
|
||||
|
||||
TP_STRUCT__entry(
|
||||
__field(unsigned long, opcode)
|
||||
),
|
||||
|
||||
TP_fast_assign(
|
||||
__entry->opcode = opcode;
|
||||
),
|
||||
|
||||
TP_printk("opcode=%lu", __entry->opcode),
|
||||
|
||||
hcall_tracepoint_regfunc, hcall_tracepoint_unregfunc
|
||||
);
|
||||
|
||||
TRACE_EVENT_FN(hcall_exit,
|
||||
|
||||
TP_PROTO(unsigned long opcode, unsigned long retval,
|
||||
unsigned long *retbuf),
|
||||
|
||||
TP_ARGS(opcode, retval, retbuf),
|
||||
|
||||
TP_STRUCT__entry(
|
||||
__field(unsigned long, opcode)
|
||||
__field(unsigned long, retval)
|
||||
),
|
||||
|
||||
TP_fast_assign(
|
||||
__entry->opcode = opcode;
|
||||
__entry->retval = retval;
|
||||
),
|
||||
|
||||
TP_printk("opcode=%lu retval=%lu", __entry->opcode, __entry->retval),
|
||||
|
||||
hcall_tracepoint_regfunc, hcall_tracepoint_unregfunc
|
||||
);
|
||||
#endif
|
||||
|
||||
#endif /* _TRACE_POWERPC_H */
|
||||
|
||||
#undef TRACE_INCLUDE_PATH
|
||||
#undef TRACE_INCLUDE_FILE
|
||||
|
||||
#define TRACE_INCLUDE_PATH asm
|
||||
#define TRACE_INCLUDE_FILE trace
|
||||
|
||||
#include <trace/define_trace.h>
|
@ -732,7 +732,7 @@ int fix_alignment(struct pt_regs *regs)
|
||||
|
||||
#ifdef CONFIG_SPE
|
||||
if ((instr >> 26) == 0x4) {
|
||||
PPC_WARN_EMULATED(spe);
|
||||
PPC_WARN_ALIGNMENT(spe, regs);
|
||||
return emulate_spe(regs, reg, instr);
|
||||
}
|
||||
#endif
|
||||
@ -786,7 +786,7 @@ int fix_alignment(struct pt_regs *regs)
|
||||
flags |= SPLT;
|
||||
nb = 8;
|
||||
}
|
||||
PPC_WARN_EMULATED(vsx);
|
||||
PPC_WARN_ALIGNMENT(vsx, regs);
|
||||
return emulate_vsx(addr, reg, areg, regs, flags, nb);
|
||||
}
|
||||
#endif
|
||||
@ -794,7 +794,7 @@ int fix_alignment(struct pt_regs *regs)
|
||||
* the exception of DCBZ which is handled as a special case here
|
||||
*/
|
||||
if (instr == DCBZ) {
|
||||
PPC_WARN_EMULATED(dcbz);
|
||||
PPC_WARN_ALIGNMENT(dcbz, regs);
|
||||
return emulate_dcbz(regs, addr);
|
||||
}
|
||||
if (unlikely(nb == 0))
|
||||
@ -804,7 +804,7 @@ int fix_alignment(struct pt_regs *regs)
|
||||
* function
|
||||
*/
|
||||
if (flags & M) {
|
||||
PPC_WARN_EMULATED(multiple);
|
||||
PPC_WARN_ALIGNMENT(multiple, regs);
|
||||
return emulate_multiple(regs, addr, reg, nb,
|
||||
flags, instr, swiz);
|
||||
}
|
||||
@ -825,11 +825,11 @@ int fix_alignment(struct pt_regs *regs)
|
||||
|
||||
/* Special case for 16-byte FP loads and stores */
|
||||
if (nb == 16) {
|
||||
PPC_WARN_EMULATED(fp_pair);
|
||||
PPC_WARN_ALIGNMENT(fp_pair, regs);
|
||||
return emulate_fp_pair(addr, reg, flags);
|
||||
}
|
||||
|
||||
PPC_WARN_EMULATED(unaligned);
|
||||
PPC_WARN_ALIGNMENT(unaligned, regs);
|
||||
|
||||
/* If we are loading, get the data from user space, else
|
||||
* get it from register values
|
||||
|
@ -551,7 +551,7 @@ restore:
|
||||
BEGIN_FW_FTR_SECTION
|
||||
ld r5,SOFTE(r1)
|
||||
FW_FTR_SECTION_ELSE
|
||||
b iseries_check_pending_irqs
|
||||
b .Liseries_check_pending_irqs
|
||||
ALT_FW_FTR_SECTION_END_IFCLR(FW_FEATURE_ISERIES)
|
||||
2:
|
||||
TRACE_AND_RESTORE_IRQ(r5);
|
||||
@ -623,7 +623,7 @@ ALT_FW_FTR_SECTION_END_IFCLR(FW_FEATURE_ISERIES)
|
||||
|
||||
#endif /* CONFIG_PPC_BOOK3E */
|
||||
|
||||
iseries_check_pending_irqs:
|
||||
.Liseries_check_pending_irqs:
|
||||
#ifdef CONFIG_PPC_ISERIES
|
||||
ld r5,SOFTE(r1)
|
||||
cmpdi 0,r5,0
|
||||
|
@ -185,12 +185,15 @@ END_FTR_SECTION_IFSET(CPU_FTR_REAL_LE)
|
||||
* prolog code of the PerformanceMonitor one. A little
|
||||
* trickery is thus necessary
|
||||
*/
|
||||
performance_monitor_pSeries_1:
|
||||
. = 0xf00
|
||||
b performance_monitor_pSeries
|
||||
|
||||
altivec_unavailable_pSeries_1:
|
||||
. = 0xf20
|
||||
b altivec_unavailable_pSeries
|
||||
|
||||
vsx_unavailable_pSeries_1:
|
||||
. = 0xf40
|
||||
b vsx_unavailable_pSeries
|
||||
|
||||
|
@ -70,6 +70,8 @@
|
||||
#include <asm/firmware.h>
|
||||
#include <asm/lv1call.h>
|
||||
#endif
|
||||
#define CREATE_TRACE_POINTS
|
||||
#include <asm/trace.h>
|
||||
|
||||
int __irq_offset_value;
|
||||
static int ppc_spurious_interrupts;
|
||||
@ -325,6 +327,8 @@ void do_IRQ(struct pt_regs *regs)
|
||||
struct pt_regs *old_regs = set_irq_regs(regs);
|
||||
unsigned int irq;
|
||||
|
||||
trace_irq_entry(regs);
|
||||
|
||||
irq_enter();
|
||||
|
||||
check_stack_overflow();
|
||||
@ -348,6 +352,8 @@ void do_IRQ(struct pt_regs *regs)
|
||||
timer_interrupt(regs);
|
||||
}
|
||||
#endif
|
||||
|
||||
trace_irq_exit(regs);
|
||||
}
|
||||
|
||||
void __init init_IRQ(void)
|
||||
|
@ -1165,7 +1165,7 @@ static void record_and_restart(struct perf_event *event, unsigned long val,
|
||||
*/
|
||||
if (record) {
|
||||
struct perf_sample_data data = {
|
||||
.addr = 0,
|
||||
.addr = ~0ULL,
|
||||
.period = event->hw.last_period,
|
||||
};
|
||||
|
||||
|
@ -72,10 +72,6 @@
|
||||
#define MMCR1_PMCSEL_SH(n) (MMCR1_PMC1SEL_SH - (n) * 8)
|
||||
#define MMCR1_PMCSEL_MSK 0x7f
|
||||
|
||||
/*
|
||||
* Bits in MMCRA
|
||||
*/
|
||||
|
||||
/*
|
||||
* Layout of constraint bits:
|
||||
* 6666555555555544444444443333333333222222222211111111110000000000
|
||||
|
@ -72,10 +72,6 @@
|
||||
#define MMCR1_PMCSEL_SH(n) (MMCR1_PMC1SEL_SH - (n) * 8)
|
||||
#define MMCR1_PMCSEL_MSK 0x7f
|
||||
|
||||
/*
|
||||
* Bits in MMCRA
|
||||
*/
|
||||
|
||||
/*
|
||||
* Layout of constraint bits:
|
||||
* 6666555555555544444444443333333333222222222211111111110000000000
|
||||
@ -390,7 +386,7 @@ static int power5_compute_mmcr(u64 event[], int n_ev,
|
||||
unsigned int hwc[], unsigned long mmcr[])
|
||||
{
|
||||
unsigned long mmcr1 = 0;
|
||||
unsigned long mmcra = 0;
|
||||
unsigned long mmcra = MMCRA_SDAR_DCACHE_MISS | MMCRA_SDAR_ERAT_MISS;
|
||||
unsigned int pmc, unit, byte, psel;
|
||||
unsigned int ttm, grp;
|
||||
int i, isbus, bit, grsel;
|
||||
|
@ -178,7 +178,7 @@ static int p6_compute_mmcr(u64 event[], int n_ev,
|
||||
unsigned int hwc[], unsigned long mmcr[])
|
||||
{
|
||||
unsigned long mmcr1 = 0;
|
||||
unsigned long mmcra = 0;
|
||||
unsigned long mmcra = MMCRA_SDAR_DCACHE_MISS | MMCRA_SDAR_ERAT_MISS;
|
||||
int i;
|
||||
unsigned int pmc, ev, b, u, s, psel;
|
||||
unsigned int ttmset = 0;
|
||||
|
@ -50,10 +50,6 @@
|
||||
#define MMCR1_PMCSEL_SH(n) (MMCR1_PMC1SEL_SH - (n) * 8)
|
||||
#define MMCR1_PMCSEL_MSK 0xff
|
||||
|
||||
/*
|
||||
* Bits in MMCRA
|
||||
*/
|
||||
|
||||
/*
|
||||
* Layout of constraint bits:
|
||||
* 6666555555555544444444443333333333222222222211111111110000000000
|
||||
@ -230,7 +226,7 @@ static int power7_compute_mmcr(u64 event[], int n_ev,
|
||||
unsigned int hwc[], unsigned long mmcr[])
|
||||
{
|
||||
unsigned long mmcr1 = 0;
|
||||
unsigned long mmcra = 0;
|
||||
unsigned long mmcra = MMCRA_SDAR_DCACHE_MISS | MMCRA_SDAR_ERAT_MISS;
|
||||
unsigned int pmc, unit, combine, l2sel, psel;
|
||||
unsigned int pmc_inuse = 0;
|
||||
int i;
|
||||
|
@ -83,10 +83,6 @@ static short mmcr1_adder_bits[8] = {
|
||||
MMCR1_PMC8_ADDER_SEL_SH
|
||||
};
|
||||
|
||||
/*
|
||||
* Bits in MMCRA
|
||||
*/
|
||||
|
||||
/*
|
||||
* Layout of constraint bits:
|
||||
* 6666555555555544444444443333333333222222222211111111110000000000
|
||||
|
@ -660,6 +660,7 @@ late_initcall(check_cache_coherency);
|
||||
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
struct dentry *powerpc_debugfs_root;
|
||||
EXPORT_SYMBOL(powerpc_debugfs_root);
|
||||
|
||||
static int powerpc_debugfs_init(void)
|
||||
{
|
||||
|
@ -345,7 +345,7 @@ void __init setup_arch(char **cmdline_p)
|
||||
|
||||
#ifdef CONFIG_SWIOTLB
|
||||
if (ppc_swiotlb_enable)
|
||||
swiotlb_init();
|
||||
swiotlb_init(1);
|
||||
#endif
|
||||
|
||||
paging_init();
|
||||
|
@ -550,7 +550,7 @@ void __init setup_arch(char **cmdline_p)
|
||||
|
||||
#ifdef CONFIG_SWIOTLB
|
||||
if (ppc_swiotlb_enable)
|
||||
swiotlb_init();
|
||||
swiotlb_init(1);
|
||||
#endif
|
||||
|
||||
paging_init();
|
||||
|
@ -54,6 +54,7 @@
|
||||
#include <linux/irq.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/perf_event.h>
|
||||
#include <asm/trace.h>
|
||||
|
||||
#include <asm/io.h>
|
||||
#include <asm/processor.h>
|
||||
@ -571,6 +572,8 @@ void timer_interrupt(struct pt_regs * regs)
|
||||
struct clock_event_device *evt = &decrementer->event;
|
||||
u64 now;
|
||||
|
||||
trace_timer_interrupt_entry(regs);
|
||||
|
||||
/* Ensure a positive value is written to the decrementer, or else
|
||||
* some CPUs will continuue to take decrementer exceptions */
|
||||
set_dec(DECREMENTER_MAX);
|
||||
@ -590,6 +593,7 @@ void timer_interrupt(struct pt_regs * regs)
|
||||
now = decrementer->next_tb - now;
|
||||
if (now <= DECREMENTER_MAX)
|
||||
set_dec((int)now);
|
||||
trace_timer_interrupt_exit(regs);
|
||||
return;
|
||||
}
|
||||
old_regs = set_irq_regs(regs);
|
||||
@ -620,6 +624,8 @@ void timer_interrupt(struct pt_regs * regs)
|
||||
|
||||
irq_exit();
|
||||
set_irq_regs(old_regs);
|
||||
|
||||
trace_timer_interrupt_exit(regs);
|
||||
}
|
||||
|
||||
void wakeup_decrementer(void)
|
||||
|
@ -759,7 +759,7 @@ static int emulate_instruction(struct pt_regs *regs)
|
||||
|
||||
/* Emulate the mfspr rD, PVR. */
|
||||
if ((instword & PPC_INST_MFSPR_PVR_MASK) == PPC_INST_MFSPR_PVR) {
|
||||
PPC_WARN_EMULATED(mfpvr);
|
||||
PPC_WARN_EMULATED(mfpvr, regs);
|
||||
rd = (instword >> 21) & 0x1f;
|
||||
regs->gpr[rd] = mfspr(SPRN_PVR);
|
||||
return 0;
|
||||
@ -767,7 +767,7 @@ static int emulate_instruction(struct pt_regs *regs)
|
||||
|
||||
/* Emulating the dcba insn is just a no-op. */
|
||||
if ((instword & PPC_INST_DCBA_MASK) == PPC_INST_DCBA) {
|
||||
PPC_WARN_EMULATED(dcba);
|
||||
PPC_WARN_EMULATED(dcba, regs);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -776,7 +776,7 @@ static int emulate_instruction(struct pt_regs *regs)
|
||||
int shift = (instword >> 21) & 0x1c;
|
||||
unsigned long msk = 0xf0000000UL >> shift;
|
||||
|
||||
PPC_WARN_EMULATED(mcrxr);
|
||||
PPC_WARN_EMULATED(mcrxr, regs);
|
||||
regs->ccr = (regs->ccr & ~msk) | ((regs->xer >> shift) & msk);
|
||||
regs->xer &= ~0xf0000000UL;
|
||||
return 0;
|
||||
@ -784,19 +784,19 @@ static int emulate_instruction(struct pt_regs *regs)
|
||||
|
||||
/* Emulate load/store string insn. */
|
||||
if ((instword & PPC_INST_STRING_GEN_MASK) == PPC_INST_STRING) {
|
||||
PPC_WARN_EMULATED(string);
|
||||
PPC_WARN_EMULATED(string, regs);
|
||||
return emulate_string_inst(regs, instword);
|
||||
}
|
||||
|
||||
/* Emulate the popcntb (Population Count Bytes) instruction. */
|
||||
if ((instword & PPC_INST_POPCNTB_MASK) == PPC_INST_POPCNTB) {
|
||||
PPC_WARN_EMULATED(popcntb);
|
||||
PPC_WARN_EMULATED(popcntb, regs);
|
||||
return emulate_popcntb_inst(regs, instword);
|
||||
}
|
||||
|
||||
/* Emulate isel (Integer Select) instruction */
|
||||
if ((instword & PPC_INST_ISEL_MASK) == PPC_INST_ISEL) {
|
||||
PPC_WARN_EMULATED(isel);
|
||||
PPC_WARN_EMULATED(isel, regs);
|
||||
return emulate_isel(regs, instword);
|
||||
}
|
||||
|
||||
@ -995,7 +995,7 @@ void SoftwareEmulation(struct pt_regs *regs)
|
||||
#ifdef CONFIG_MATH_EMULATION
|
||||
errcode = do_mathemu(regs);
|
||||
if (errcode >= 0)
|
||||
PPC_WARN_EMULATED(math);
|
||||
PPC_WARN_EMULATED(math, regs);
|
||||
|
||||
switch (errcode) {
|
||||
case 0:
|
||||
@ -1018,7 +1018,7 @@ void SoftwareEmulation(struct pt_regs *regs)
|
||||
#elif defined(CONFIG_8XX_MINIMAL_FPEMU)
|
||||
errcode = Soft_emulate_8xx(regs);
|
||||
if (errcode >= 0)
|
||||
PPC_WARN_EMULATED(8xx);
|
||||
PPC_WARN_EMULATED(8xx, regs);
|
||||
|
||||
switch (errcode) {
|
||||
case 0:
|
||||
@ -1129,7 +1129,7 @@ void altivec_assist_exception(struct pt_regs *regs)
|
||||
|
||||
flush_altivec_to_thread(current);
|
||||
|
||||
PPC_WARN_EMULATED(altivec);
|
||||
PPC_WARN_EMULATED(altivec, regs);
|
||||
err = emulate_altivec(regs);
|
||||
if (err == 0) {
|
||||
regs->nip += 4; /* skip emulated instruction */
|
||||
|
@ -26,11 +26,11 @@ BEGIN_FTR_SECTION
|
||||
srd r8,r5,r11
|
||||
|
||||
mtctr r8
|
||||
setup:
|
||||
.Lsetup:
|
||||
dcbt r9,r4
|
||||
dcbz r9,r3
|
||||
add r9,r9,r12
|
||||
bdnz setup
|
||||
bdnz .Lsetup
|
||||
END_FTR_SECTION_IFSET(CPU_FTR_CP_USE_DCBTZ)
|
||||
addi r3,r3,-8
|
||||
srdi r8,r5,7 /* page is copied in 128 byte strides */
|
||||
|
@ -14,68 +14,94 @@
|
||||
|
||||
#define STK_PARM(i) (48 + ((i)-3)*8)
|
||||
|
||||
#ifdef CONFIG_HCALL_STATS
|
||||
#ifdef CONFIG_TRACEPOINTS
|
||||
|
||||
.section ".toc","aw"
|
||||
|
||||
.globl hcall_tracepoint_refcount
|
||||
hcall_tracepoint_refcount:
|
||||
.llong 0
|
||||
|
||||
.section ".text"
|
||||
|
||||
/*
|
||||
* precall must preserve all registers. use unused STK_PARM()
|
||||
* areas to save snapshots and opcode.
|
||||
* areas to save snapshots and opcode. We branch around this
|
||||
* in early init (eg when populating the MMU hashtable) by using an
|
||||
* unconditional cpu feature.
|
||||
*/
|
||||
#define HCALL_INST_PRECALL \
|
||||
std r3,STK_PARM(r3)(r1); /* save opcode */ \
|
||||
mftb r0; /* get timebase and */ \
|
||||
std r0,STK_PARM(r5)(r1); /* save for later */ \
|
||||
#define HCALL_INST_PRECALL(FIRST_REG) \
|
||||
BEGIN_FTR_SECTION; \
|
||||
mfspr r0,SPRN_PURR; /* get PURR and */ \
|
||||
std r0,STK_PARM(r6)(r1); /* save for later */ \
|
||||
END_FTR_SECTION_IFSET(CPU_FTR_PURR);
|
||||
|
||||
b 1f; \
|
||||
END_FTR_SECTION(0, 1); \
|
||||
ld r12,hcall_tracepoint_refcount@toc(r2); \
|
||||
cmpdi r12,0; \
|
||||
beq+ 1f; \
|
||||
mflr r0; \
|
||||
std r3,STK_PARM(r3)(r1); \
|
||||
std r4,STK_PARM(r4)(r1); \
|
||||
std r5,STK_PARM(r5)(r1); \
|
||||
std r6,STK_PARM(r6)(r1); \
|
||||
std r7,STK_PARM(r7)(r1); \
|
||||
std r8,STK_PARM(r8)(r1); \
|
||||
std r9,STK_PARM(r9)(r1); \
|
||||
std r10,STK_PARM(r10)(r1); \
|
||||
std r0,16(r1); \
|
||||
addi r4,r1,STK_PARM(FIRST_REG); \
|
||||
stdu r1,-STACK_FRAME_OVERHEAD(r1); \
|
||||
bl .__trace_hcall_entry; \
|
||||
addi r1,r1,STACK_FRAME_OVERHEAD; \
|
||||
ld r0,16(r1); \
|
||||
ld r3,STK_PARM(r3)(r1); \
|
||||
ld r4,STK_PARM(r4)(r1); \
|
||||
ld r5,STK_PARM(r5)(r1); \
|
||||
ld r6,STK_PARM(r6)(r1); \
|
||||
ld r7,STK_PARM(r7)(r1); \
|
||||
ld r8,STK_PARM(r8)(r1); \
|
||||
ld r9,STK_PARM(r9)(r1); \
|
||||
ld r10,STK_PARM(r10)(r1); \
|
||||
mtlr r0; \
|
||||
1:
|
||||
|
||||
/*
|
||||
* postcall is performed immediately before function return which
|
||||
* allows liberal use of volatile registers. We branch around this
|
||||
* in early init (eg when populating the MMU hashtable) by using an
|
||||
* unconditional cpu feature.
|
||||
*/
|
||||
#define HCALL_INST_POSTCALL \
|
||||
#define __HCALL_INST_POSTCALL \
|
||||
BEGIN_FTR_SECTION; \
|
||||
b 1f; \
|
||||
END_FTR_SECTION(0, 1); \
|
||||
ld r4,STK_PARM(r3)(r1); /* validate opcode */ \
|
||||
cmpldi cr7,r4,MAX_HCALL_OPCODE; \
|
||||
bgt- cr7,1f; \
|
||||
\
|
||||
/* get time and PURR snapshots after hcall */ \
|
||||
mftb r7; /* timebase after */ \
|
||||
BEGIN_FTR_SECTION; \
|
||||
mfspr r8,SPRN_PURR; /* PURR after */ \
|
||||
ld r6,STK_PARM(r6)(r1); /* PURR before */ \
|
||||
subf r6,r6,r8; /* delta */ \
|
||||
END_FTR_SECTION_IFSET(CPU_FTR_PURR); \
|
||||
ld r5,STK_PARM(r5)(r1); /* timebase before */ \
|
||||
subf r5,r5,r7; /* time delta */ \
|
||||
\
|
||||
/* calculate address of stat structure r4 = opcode */ \
|
||||
srdi r4,r4,2; /* index into array */ \
|
||||
mulli r4,r4,HCALL_STAT_SIZE; \
|
||||
LOAD_REG_ADDR(r7, per_cpu__hcall_stats); \
|
||||
add r4,r4,r7; \
|
||||
ld r7,PACA_DATA_OFFSET(r13); /* per cpu offset */ \
|
||||
add r4,r4,r7; \
|
||||
\
|
||||
/* update stats */ \
|
||||
ld r7,HCALL_STAT_CALLS(r4); /* count */ \
|
||||
addi r7,r7,1; \
|
||||
std r7,HCALL_STAT_CALLS(r4); \
|
||||
ld r7,HCALL_STAT_TB(r4); /* timebase */ \
|
||||
add r7,r7,r5; \
|
||||
std r7,HCALL_STAT_TB(r4); \
|
||||
BEGIN_FTR_SECTION; \
|
||||
ld r7,HCALL_STAT_PURR(r4); /* PURR */ \
|
||||
add r7,r7,r6; \
|
||||
std r7,HCALL_STAT_PURR(r4); \
|
||||
END_FTR_SECTION_IFSET(CPU_FTR_PURR); \
|
||||
ld r12,hcall_tracepoint_refcount@toc(r2); \
|
||||
cmpdi r12,0; \
|
||||
beq+ 1f; \
|
||||
mflr r0; \
|
||||
ld r6,STK_PARM(r3)(r1); \
|
||||
std r3,STK_PARM(r3)(r1); \
|
||||
mr r4,r3; \
|
||||
mr r3,r6; \
|
||||
std r0,16(r1); \
|
||||
stdu r1,-STACK_FRAME_OVERHEAD(r1); \
|
||||
bl .__trace_hcall_exit; \
|
||||
addi r1,r1,STACK_FRAME_OVERHEAD; \
|
||||
ld r0,16(r1); \
|
||||
ld r3,STK_PARM(r3)(r1); \
|
||||
mtlr r0; \
|
||||
1:
|
||||
|
||||
#define HCALL_INST_POSTCALL_NORETS \
|
||||
li r5,0; \
|
||||
__HCALL_INST_POSTCALL
|
||||
|
||||
#define HCALL_INST_POSTCALL(BUFREG) \
|
||||
mr r5,BUFREG; \
|
||||
__HCALL_INST_POSTCALL
|
||||
|
||||
#else
|
||||
#define HCALL_INST_PRECALL
|
||||
#define HCALL_INST_POSTCALL
|
||||
#define HCALL_INST_PRECALL(FIRST_ARG)
|
||||
#define HCALL_INST_POSTCALL_NORETS
|
||||
#define HCALL_INST_POSTCALL(BUFREG)
|
||||
#endif
|
||||
|
||||
.text
|
||||
@ -86,11 +112,11 @@ _GLOBAL(plpar_hcall_norets)
|
||||
mfcr r0
|
||||
stw r0,8(r1)
|
||||
|
||||
HCALL_INST_PRECALL
|
||||
HCALL_INST_PRECALL(r4)
|
||||
|
||||
HVSC /* invoke the hypervisor */
|
||||
|
||||
HCALL_INST_POSTCALL
|
||||
HCALL_INST_POSTCALL_NORETS
|
||||
|
||||
lwz r0,8(r1)
|
||||
mtcrf 0xff,r0
|
||||
@ -102,7 +128,7 @@ _GLOBAL(plpar_hcall)
|
||||
mfcr r0
|
||||
stw r0,8(r1)
|
||||
|
||||
HCALL_INST_PRECALL
|
||||
HCALL_INST_PRECALL(r5)
|
||||
|
||||
std r4,STK_PARM(r4)(r1) /* Save ret buffer */
|
||||
|
||||
@ -121,7 +147,7 @@ _GLOBAL(plpar_hcall)
|
||||
std r6, 16(r12)
|
||||
std r7, 24(r12)
|
||||
|
||||
HCALL_INST_POSTCALL
|
||||
HCALL_INST_POSTCALL(r12)
|
||||
|
||||
lwz r0,8(r1)
|
||||
mtcrf 0xff,r0
|
||||
@ -168,7 +194,7 @@ _GLOBAL(plpar_hcall9)
|
||||
mfcr r0
|
||||
stw r0,8(r1)
|
||||
|
||||
HCALL_INST_PRECALL
|
||||
HCALL_INST_PRECALL(r5)
|
||||
|
||||
std r4,STK_PARM(r4)(r1) /* Save ret buffer */
|
||||
|
||||
@ -196,7 +222,7 @@ _GLOBAL(plpar_hcall9)
|
||||
std r11,56(r12)
|
||||
std r0, 64(r12)
|
||||
|
||||
HCALL_INST_POSTCALL
|
||||
HCALL_INST_POSTCALL(r12)
|
||||
|
||||
lwz r0,8(r1)
|
||||
mtcrf 0xff,r0
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include <asm/hvcall.h>
|
||||
#include <asm/firmware.h>
|
||||
#include <asm/cputable.h>
|
||||
#include <asm/trace.h>
|
||||
|
||||
DEFINE_PER_CPU(struct hcall_stats[HCALL_STAT_ARRAY_SIZE], hcall_stats);
|
||||
|
||||
@ -100,6 +101,35 @@ static const struct file_operations hcall_inst_seq_fops = {
|
||||
#define HCALL_ROOT_DIR "hcall_inst"
|
||||
#define CPU_NAME_BUF_SIZE 32
|
||||
|
||||
|
||||
static void probe_hcall_entry(unsigned long opcode, unsigned long *args)
|
||||
{
|
||||
struct hcall_stats *h;
|
||||
|
||||
if (opcode > MAX_HCALL_OPCODE)
|
||||
return;
|
||||
|
||||
h = &get_cpu_var(hcall_stats)[opcode / 4];
|
||||
h->tb_start = mftb();
|
||||
h->purr_start = mfspr(SPRN_PURR);
|
||||
}
|
||||
|
||||
static void probe_hcall_exit(unsigned long opcode, unsigned long retval,
|
||||
unsigned long *retbuf)
|
||||
{
|
||||
struct hcall_stats *h;
|
||||
|
||||
if (opcode > MAX_HCALL_OPCODE)
|
||||
return;
|
||||
|
||||
h = &__get_cpu_var(hcall_stats)[opcode / 4];
|
||||
h->num_calls++;
|
||||
h->tb_total = mftb() - h->tb_start;
|
||||
h->purr_total = mfspr(SPRN_PURR) - h->purr_start;
|
||||
|
||||
put_cpu_var(hcall_stats);
|
||||
}
|
||||
|
||||
static int __init hcall_inst_init(void)
|
||||
{
|
||||
struct dentry *hcall_root;
|
||||
@ -110,6 +140,14 @@ static int __init hcall_inst_init(void)
|
||||
if (!firmware_has_feature(FW_FEATURE_LPAR))
|
||||
return 0;
|
||||
|
||||
if (register_trace_hcall_entry(probe_hcall_entry))
|
||||
return -EINVAL;
|
||||
|
||||
if (register_trace_hcall_exit(probe_hcall_exit)) {
|
||||
unregister_trace_hcall_entry(probe_hcall_entry);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
hcall_root = debugfs_create_dir(HCALL_ROOT_DIR, NULL);
|
||||
if (!hcall_root)
|
||||
return -ENOMEM;
|
||||
|
@ -39,6 +39,7 @@
|
||||
#include <asm/cputable.h>
|
||||
#include <asm/udbg.h>
|
||||
#include <asm/smp.h>
|
||||
#include <asm/trace.h>
|
||||
|
||||
#include "plpar_wrappers.h"
|
||||
#include "pseries.h"
|
||||
@ -661,3 +662,35 @@ void arch_free_page(struct page *page, int order)
|
||||
EXPORT_SYMBOL(arch_free_page);
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_TRACEPOINTS
|
||||
/*
|
||||
* We optimise our hcall path by placing hcall_tracepoint_refcount
|
||||
* directly in the TOC so we can check if the hcall tracepoints are
|
||||
* enabled via a single load.
|
||||
*/
|
||||
|
||||
/* NB: reg/unreg are called while guarded with the tracepoints_mutex */
|
||||
extern long hcall_tracepoint_refcount;
|
||||
|
||||
void hcall_tracepoint_regfunc(void)
|
||||
{
|
||||
hcall_tracepoint_refcount++;
|
||||
}
|
||||
|
||||
void hcall_tracepoint_unregfunc(void)
|
||||
{
|
||||
hcall_tracepoint_refcount--;
|
||||
}
|
||||
|
||||
void __trace_hcall_entry(unsigned long opcode, unsigned long *args)
|
||||
{
|
||||
trace_hcall_entry(opcode, args);
|
||||
}
|
||||
|
||||
void __trace_hcall_exit(long opcode, unsigned long retval,
|
||||
unsigned long *retbuf)
|
||||
{
|
||||
trace_hcall_exit(opcode, retval, retbuf);
|
||||
}
|
||||
#endif
|
||||
|
@ -95,6 +95,34 @@ config S390
|
||||
select HAVE_ARCH_TRACEHOOK
|
||||
select INIT_ALL_POSSIBLE
|
||||
select HAVE_PERF_EVENTS
|
||||
select ARCH_INLINE_SPIN_TRYLOCK
|
||||
select ARCH_INLINE_SPIN_TRYLOCK_BH
|
||||
select ARCH_INLINE_SPIN_LOCK
|
||||
select ARCH_INLINE_SPIN_LOCK_BH
|
||||
select ARCH_INLINE_SPIN_LOCK_IRQ
|
||||
select ARCH_INLINE_SPIN_LOCK_IRQSAVE
|
||||
select ARCH_INLINE_SPIN_UNLOCK
|
||||
select ARCH_INLINE_SPIN_UNLOCK_BH
|
||||
select ARCH_INLINE_SPIN_UNLOCK_IRQ
|
||||
select ARCH_INLINE_SPIN_UNLOCK_IRQRESTORE
|
||||
select ARCH_INLINE_READ_TRYLOCK
|
||||
select ARCH_INLINE_READ_LOCK
|
||||
select ARCH_INLINE_READ_LOCK_BH
|
||||
select ARCH_INLINE_READ_LOCK_IRQ
|
||||
select ARCH_INLINE_READ_LOCK_IRQSAVE
|
||||
select ARCH_INLINE_READ_UNLOCK
|
||||
select ARCH_INLINE_READ_UNLOCK_BH
|
||||
select ARCH_INLINE_READ_UNLOCK_IRQ
|
||||
select ARCH_INLINE_READ_UNLOCK_IRQRESTORE
|
||||
select ARCH_INLINE_WRITE_TRYLOCK
|
||||
select ARCH_INLINE_WRITE_LOCK
|
||||
select ARCH_INLINE_WRITE_LOCK_BH
|
||||
select ARCH_INLINE_WRITE_LOCK_IRQ
|
||||
select ARCH_INLINE_WRITE_LOCK_IRQSAVE
|
||||
select ARCH_INLINE_WRITE_UNLOCK
|
||||
select ARCH_INLINE_WRITE_UNLOCK_BH
|
||||
select ARCH_INLINE_WRITE_UNLOCK_IRQ
|
||||
select ARCH_INLINE_WRITE_UNLOCK_IRQRESTORE
|
||||
|
||||
config SCHED_OMIT_FRAME_POINTER
|
||||
bool
|
||||
|
@ -49,7 +49,7 @@
|
||||
|
||||
#define BUG() do { \
|
||||
__EMIT_BUG(0); \
|
||||
for (;;); \
|
||||
unreachable(); \
|
||||
} while (0)
|
||||
|
||||
#define WARN_ON(x) ({ \
|
||||
|
@ -191,33 +191,4 @@ static inline int __raw_write_trylock(raw_rwlock_t *rw)
|
||||
#define _raw_read_relax(lock) cpu_relax()
|
||||
#define _raw_write_relax(lock) cpu_relax()
|
||||
|
||||
#define __always_inline__spin_lock
|
||||
#define __always_inline__read_lock
|
||||
#define __always_inline__write_lock
|
||||
#define __always_inline__spin_lock_bh
|
||||
#define __always_inline__read_lock_bh
|
||||
#define __always_inline__write_lock_bh
|
||||
#define __always_inline__spin_lock_irq
|
||||
#define __always_inline__read_lock_irq
|
||||
#define __always_inline__write_lock_irq
|
||||
#define __always_inline__spin_lock_irqsave
|
||||
#define __always_inline__read_lock_irqsave
|
||||
#define __always_inline__write_lock_irqsave
|
||||
#define __always_inline__spin_trylock
|
||||
#define __always_inline__read_trylock
|
||||
#define __always_inline__write_trylock
|
||||
#define __always_inline__spin_trylock_bh
|
||||
#define __always_inline__spin_unlock
|
||||
#define __always_inline__read_unlock
|
||||
#define __always_inline__write_unlock
|
||||
#define __always_inline__spin_unlock_bh
|
||||
#define __always_inline__read_unlock_bh
|
||||
#define __always_inline__write_unlock_bh
|
||||
#define __always_inline__spin_unlock_irq
|
||||
#define __always_inline__read_unlock_irq
|
||||
#define __always_inline__write_unlock_irq
|
||||
#define __always_inline__spin_unlock_irqrestore
|
||||
#define __always_inline__read_unlock_irqrestore
|
||||
#define __always_inline__write_unlock_irqrestore
|
||||
|
||||
#endif /* __ASM_SPINLOCK_H */
|
||||
|
@ -203,73 +203,10 @@ out:
|
||||
|
||||
#ifdef CONFIG_FTRACE_SYSCALLS
|
||||
|
||||
extern unsigned long __start_syscalls_metadata[];
|
||||
extern unsigned long __stop_syscalls_metadata[];
|
||||
extern unsigned int sys_call_table[];
|
||||
|
||||
static struct syscall_metadata **syscalls_metadata;
|
||||
|
||||
struct syscall_metadata *syscall_nr_to_meta(int nr)
|
||||
unsigned long __init arch_syscall_addr(int nr)
|
||||
{
|
||||
if (!syscalls_metadata || nr >= NR_syscalls || nr < 0)
|
||||
return NULL;
|
||||
|
||||
return syscalls_metadata[nr];
|
||||
return (unsigned long)sys_call_table[nr];
|
||||
}
|
||||
|
||||
int syscall_name_to_nr(char *name)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!syscalls_metadata)
|
||||
return -1;
|
||||
for (i = 0; i < NR_syscalls; i++)
|
||||
if (syscalls_metadata[i])
|
||||
if (!strcmp(syscalls_metadata[i]->name, name))
|
||||
return i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
void set_syscall_enter_id(int num, int id)
|
||||
{
|
||||
syscalls_metadata[num]->enter_id = id;
|
||||
}
|
||||
|
||||
void set_syscall_exit_id(int num, int id)
|
||||
{
|
||||
syscalls_metadata[num]->exit_id = id;
|
||||
}
|
||||
|
||||
static struct syscall_metadata *find_syscall_meta(unsigned long syscall)
|
||||
{
|
||||
struct syscall_metadata *start;
|
||||
struct syscall_metadata *stop;
|
||||
char str[KSYM_SYMBOL_LEN];
|
||||
|
||||
start = (struct syscall_metadata *)__start_syscalls_metadata;
|
||||
stop = (struct syscall_metadata *)__stop_syscalls_metadata;
|
||||
kallsyms_lookup(syscall, NULL, NULL, NULL, str);
|
||||
|
||||
for ( ; start < stop; start++) {
|
||||
if (start->name && !strcmp(start->name + 3, str + 3))
|
||||
return start;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int __init arch_init_ftrace_syscalls(void)
|
||||
{
|
||||
struct syscall_metadata *meta;
|
||||
int i;
|
||||
syscalls_metadata = kzalloc(sizeof(*syscalls_metadata) * NR_syscalls,
|
||||
GFP_KERNEL);
|
||||
if (!syscalls_metadata)
|
||||
return -ENOMEM;
|
||||
for (i = 0; i < NR_syscalls; i++) {
|
||||
meta = find_syscall_meta((unsigned long)sys_call_table[i]);
|
||||
syscalls_metadata[i] = meta;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
arch_initcall(arch_init_ftrace_syscalls);
|
||||
#endif
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user