Merge remote-tracking branch 'invisiblek/cafkorg' into cm-11.0

This commit is contained in:
Dan Pasanen 2014-08-19 19:23:10 -05:00
commit ed8fa659c4
2788 changed files with 43035 additions and 20557 deletions

View File

@ -51,12 +51,6 @@ current_snap
The current snapshot for which the device is mapped.
create_snap
Create a snapshot:
$ echo <snap-name> > /sys/bus/rbd/devices/<dev-id>/snap_create
snap_*
A directory per each snapshot

View File

@ -218,16 +218,16 @@ The development process
Linux kernel development process currently consists of a few different
main kernel "branches" and lots of different subsystem-specific kernel
branches. These different branches are:
- main 2.6.x kernel tree
- 2.6.x.y -stable kernel tree
- 2.6.x -git kernel patches
- main 3.x kernel tree
- 3.x.y -stable kernel tree
- 3.x -git kernel patches
- subsystem specific kernel trees and patches
- the 2.6.x -next kernel tree for integration tests
- the 3.x -next kernel tree for integration tests
2.6.x kernel tree
3.x kernel tree
-----------------
2.6.x kernels are maintained by Linus Torvalds, and can be found on
kernel.org in the pub/linux/kernel/v2.6/ directory. Its development
3.x kernels are maintained by Linus Torvalds, and can be found on
kernel.org in the pub/linux/kernel/v3.x/ directory. Its development
process is as follows:
- As soon as a new kernel is released a two weeks window is open,
during this period of time maintainers can submit big diffs to
@ -262,20 +262,20 @@ mailing list about kernel releases:
released according to perceived bug status, not according to a
preconceived timeline."
2.6.x.y -stable kernel tree
3.x.y -stable kernel tree
---------------------------
Kernels with 4-part versions are -stable kernels. They contain
Kernels with 3-part versions are -stable kernels. They contain
relatively small and critical fixes for security problems or significant
regressions discovered in a given 2.6.x kernel.
regressions discovered in a given 3.x kernel.
This is the recommended branch for users who want the most recent stable
kernel and are not interested in helping test development/experimental
versions.
If no 2.6.x.y kernel is available, then the highest numbered 2.6.x
If no 3.x.y kernel is available, then the highest numbered 3.x
kernel is the current stable kernel.
2.6.x.y are maintained by the "stable" team <stable@vger.kernel.org>, and
3.x.y are maintained by the "stable" team <stable@vger.kernel.org>, and
are released as needs dictate. The normal release period is approximately
two weeks, but it can be longer if there are no pressing problems. A
security-related problem, instead, can cause a release to happen almost
@ -285,7 +285,7 @@ The file Documentation/stable_kernel_rules.txt in the kernel tree
documents what kinds of changes are acceptable for the -stable tree, and
how the release process works.
2.6.x -git patches
3.x -git patches
------------------
These are daily snapshots of Linus' kernel tree which are managed in a
git repository (hence the name.) These patches are usually released
@ -317,13 +317,13 @@ revisions to it, and maintainers can mark patches as under review,
accepted, or rejected. Most of these patchwork sites are listed at
http://patchwork.kernel.org/.
2.6.x -next kernel tree for integration tests
3.x -next kernel tree for integration tests
---------------------------------------------
Before updates from subsystem trees are merged into the mainline 2.6.x
Before updates from subsystem trees are merged into the mainline 3.x
tree, they need to be integration-tested. For this purpose, a special
testing repository exists into which virtually all subsystem trees are
pulled on an almost daily basis:
http://git.kernel.org/?p=linux/kernel/git/sfr/linux-next.git
http://git.kernel.org/?p=linux/kernel/git/next/linux-next.git
http://linux.f-seidel.de/linux-next/pmwiki/
This way, the -next kernel gives a summary outlook onto what will be

View File

@ -466,6 +466,10 @@ Note:
5.3 swappiness
Similar to /proc/sys/vm/swappiness, but affecting a hierarchy of groups only.
Please note that unlike the global swappiness, memcg knob set to 0
really prevents from any swapping even if there is a swap storage
available. This might lead to memcg OOM killer if there are no file
pages to reclaim.
Following cgroups' swappiness can't be changed.
- root cgroup (uses /proc/sys/vm/swappiness).

View File

@ -7,39 +7,39 @@ This target is read-only.
Construction Parameters
=======================
<version> <dev> <hash_dev> <hash_start>
<version> <dev> <hash_dev>
<data_block_size> <hash_block_size>
<num_data_blocks> <hash_start_block>
<algorithm> <digest> <salt>
<version>
This is the version number of the on-disk format.
This is the type of the on-disk hash format.
0 is the original format used in the Chromium OS.
The salt is appended when hashing, digests are stored continuously and
the rest of the block is padded with zeros.
The salt is appended when hashing, digests are stored continuously and
the rest of the block is padded with zeros.
1 is the current format that should be used for new devices.
The salt is prepended when hashing and each digest is
padded with zeros to the power of two.
The salt is prepended when hashing and each digest is
padded with zeros to the power of two.
<dev>
This is the device containing the data the integrity of which needs to be
This is the device containing data, the integrity of which needs to be
checked. It may be specified as a path, like /dev/sdaX, or a device number,
<major>:<minor>.
<hash_dev>
This is the device that that supplies the hash tree data. It may be
This is the device that supplies the hash tree data. It may be
specified similarly to the device path and may be the same device. If the
same device is used, the hash_start should be outside of the dm-verity
configured device size.
same device is used, the hash_start should be outside the configured
dm-verity device.
<data_block_size>
The block size on a data device. Each block corresponds to one digest on
the hash device.
The block size on a data device in bytes.
Each block corresponds to one digest on the hash device.
<hash_block_size>
The size of a hash block.
The size of a hash block in bytes.
<num_data_blocks>
The number of data blocks on the data device. Additional blocks are
@ -65,7 +65,7 @@ Construction Parameters
Theory of operation
===================
dm-verity is meant to be setup as part of a verified boot path. This
dm-verity is meant to be set up as part of a verified boot path. This
may be anything ranging from a boot using tboot or trustedgrub to just
booting from a known-good device (like a USB drive or CD).
@ -73,20 +73,20 @@ When a dm-verity device is configured, it is expected that the caller
has been authenticated in some way (cryptographic signatures, etc).
After instantiation, all hashes will be verified on-demand during
disk access. If they cannot be verified up to the root node of the
tree, the root hash, then the I/O will fail. This should identify
tree, the root hash, then the I/O will fail. This should detect
tampering with any data on the device and the hash data.
Cryptographic hashes are used to assert the integrity of the device on a
per-block basis. This allows for a lightweight hash computation on first read
into the page cache. Block hashes are stored linearly-aligned to the nearest
block the size of a page.
per-block basis. This allows for a lightweight hash computation on first read
into the page cache. Block hashes are stored linearly, aligned to the nearest
block size.
Hash Tree
---------
Each node in the tree is a cryptographic hash. If it is a leaf node, the hash
is of some block data on disk. If it is an intermediary node, then the hash is
of a number of child nodes.
of some data block on disk is calculated. If it is an intermediary node,
the hash of a number of child nodes is calculated.
Each entry in the tree is a collection of neighboring nodes that fit in one
block. The number is determined based on block_size and the size of the
@ -110,63 +110,23 @@ alg = sha256, num_blocks = 32768, block_size = 4096
On-disk format
==============
Below is the recommended on-disk format. The verity kernel code does not
read the on-disk header. It only reads the hash blocks which directly
follow the header. It is expected that a user-space tool will verify the
integrity of the verity_header and then call dmsetup with the correct
parameters. Alternatively, the header can be omitted and the dmsetup
parameters can be passed via the kernel command-line in a rooted chain
of trust where the command-line is verified.
The verity kernel code does not read the verity metadata on-disk header.
It only reads the hash blocks which directly follow the header.
It is expected that a user-space tool will verify the integrity of the
verity header.
The on-disk format is especially useful in cases where the hash blocks
are on a separate partition. The magic number allows easy identification
of the partition contents. Alternatively, the hash blocks can be stored
in the same partition as the data to be verified. In such a configuration
the filesystem on the partition would be sized a little smaller than
the full-partition, leaving room for the hash blocks.
struct superblock {
uint8_t signature[8]
"verity\0\0";
uint8_t version;
1 - current format
uint8_t data_block_bits;
log2(data block size)
uint8_t hash_block_bits;
log2(hash block size)
uint8_t pad1[1];
zero padding
uint16_t salt_size;
big-endian salt size
uint8_t pad2[2];
zero padding
uint32_t data_blocks_hi;
big-endian high 32 bits of the 64-bit number of data blocks
uint32_t data_blocks_lo;
big-endian low 32 bits of the 64-bit number of data blocks
uint8_t algorithm[16];
cryptographic algorithm
uint8_t salt[384];
salt (the salt size is specified above)
uint8_t pad3[88];
zero padding to 512-byte boundary
}
Alternatively, the header can be omitted and the dmsetup parameters can
be passed via the kernel command-line in a rooted chain of trust where
the command-line is verified.
Directly following the header (and with sector number padded to the next hash
block boundary) are the hash blocks which are stored a depth at a time
(starting from the root), sorted in order of increasing index.
The full specification of kernel parameters and on-disk metadata format
is available at the cryptsetup project's wiki page
http://code.google.com/p/cryptsetup/wiki/DMVerity
Status
======
V (for Valid) is returned if every check performed so far was valid.
@ -174,21 +134,22 @@ If any check failed, C (for Corruption) is returned.
Example
=======
Setup a device:
dmsetup create vroot --table \
"0 2097152 "\
"verity 1 /dev/sda1 /dev/sda2 4096 4096 2097152 1 "\
Set up a device:
# dmsetup create vroot --readonly --table \
"0 2097152 verity 1 /dev/sda1 /dev/sda2 4096 4096 262144 1 sha256 "\
"4392712ba01368efdf14b05c76f9e4df0d53664630b5d48632ed17a137f39076 "\
"1234000000000000000000000000000000000000000000000000000000000000"
A command line tool veritysetup is available to compute or verify
the hash tree or activate the kernel driver. This is available from
the LVM2 upstream repository and may be supplied as a package called
device-mapper-verity-tools:
git://sources.redhat.com/git/lvm2
http://sourceware.org/git/?p=lvm2.git
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/verity?cvsroot=lvm2
the hash tree or activate the kernel device. This is available from
the cryptsetup upstream repository http://code.google.com/p/cryptsetup/
(as a libcryptsetup extension).
veritysetup -a vroot /dev/sda1 /dev/sda2 \
4392712ba01368efdf14b05c76f9e4df0d53664630b5d48632ed17a137f39076
Create hash on the device:
# veritysetup format /dev/sda1 /dev/sda2
...
Root hash: 4392712ba01368efdf14b05c76f9e4df0d53664630b5d48632ed17a137f39076
Activate the device:
# veritysetup create vroot /dev/sda1 /dev/sda2 \
4392712ba01368efdf14b05c76f9e4df0d53664630b5d48632ed17a137f39076

View File

@ -8,7 +8,7 @@ PIT Timer required properties:
shared across all System Controller members.
TC/TCLIB Timer required properties:
- compatible: Should be "atmel,<chip>-pit".
- compatible: Should be "atmel,<chip>-tcb".
<chip> can be "at91rm9200" or "at91sam9x5"
- reg: Should contain registers location and length
- interrupts: Should contain all interrupts for the TC block

View File

@ -10,8 +10,8 @@ Required properties:
Optional properties:
- fsl,card-wired : Indicate the card is wired to host permanently
- fsl,cd-internal : Indicate to use controller internal card detection
- fsl,wp-internal : Indicate to use controller internal write protection
- fsl,cd-controller : Indicate to use controller internal card detection
- fsl,wp-controller : Indicate to use controller internal write protection
- cd-gpios : Specify GPIOs for card detection
- wp-gpios : Specify GPIOs for write protection
@ -21,8 +21,8 @@ esdhc@70004000 {
compatible = "fsl,imx51-esdhc";
reg = <0x70004000 0x4000>;
interrupts = <1>;
fsl,cd-internal;
fsl,wp-internal;
fsl,cd-controller;
fsl,wp-controller;
};
esdhc@70008000 {

View File

@ -10,6 +10,9 @@ Required properties:
- "ns16850"
- "nvidia,tegra20-uart"
- "ibm,qpace-nwp-serial"
- "altr,16550-FIFO32"
- "altr,16550-FIFO64"
- "altr,16550-FIFO128"
- "serial" if the port type is unknown.
- reg : offset and length of the register set for the device.
- interrupts : should contain uart interrupt.

View File

@ -115,7 +115,7 @@ sub tda10045 {
sub tda10046 {
my $sourcefile = "TT_PCI_2.19h_28_11_2006.zip";
my $url = "http://www.tt-download.com/download/updates/219/$sourcefile";
my $url = "http://technotrend.com.ua/download/software/219/$sourcefile";
my $hash = "6a7e1e2f2644b162ff0502367553c72d";
my $outfile = "dvb-fe-tda10046.fw";
my $tmpdir = tempdir(DIR => "/tmp", CLEANUP => 1);

View File

@ -6,7 +6,9 @@ Supported chips:
Prefix: 'coretemp'
CPUID: family 0x6, models 0xe (Pentium M DC), 0xf (Core 2 DC 65nm),
0x16 (Core 2 SC 65nm), 0x17 (Penryn 45nm),
0x1a (Nehalem), 0x1c (Atom), 0x1e (Lynnfield)
0x1a (Nehalem), 0x1c (Atom), 0x1e (Lynnfield),
0x26 (Tunnel Creek Atom), 0x27 (Medfield Atom),
0x36 (Cedar Trail Atom)
Datasheet: Intel 64 and IA-32 Architectures Software Developer's Manual
Volume 3A: System Programming Guide
http://softwarecommunity.intel.com/Wiki/Mobility/720.htm
@ -65,6 +67,11 @@ Process Processor TjMax(C)
U3400 105
P4505/P4500 90
32nm Atom Processors
Z2460 90
D2700/2550/2500 100
N2850/2800/2650/2600 100
45nm Xeon Processors 5400 Quad-Core
X5492, X5482, X5472, X5470, X5460, X5450 85
E5472, E5462, E5450/40/30/20/10/05 85
@ -85,6 +92,9 @@ Process Processor TjMax(C)
N475/470/455/450 100
N280/270 90
330/230 125
E680/660/640/620 90
E680T/660T/640T/620T 110
CE4170/4150/4110 110
45nm Core2 Processors
Solo ULV SU3500/3300 100

View File

@ -21,6 +21,8 @@ Supported adapters:
* Intel DH89xxCC (PCH)
* Intel Panther Point (PCH)
* Intel Lynx Point (PCH)
* Intel Lynx Point-LP (PCH)
* Intel Avoton (SOC)
Datasheets: Publicly available at the Intel website
On Intel Patsburg and later chipsets, both the normal host SMBus controller

View File

@ -8,7 +8,7 @@ Supported adapters:
Datasheet: Only available via NDA from ServerWorks
* ATI IXP200, IXP300, IXP400, SB600, SB700 and SB800 southbridges
Datasheet: Not publicly available
* AMD Hudson-2
* AMD Hudson-2, CZ
Datasheet: Not publicly available
* Standard Microsystems (SMSC) SLC90E66 (Victory66) southbridge
Datasheet: Publicly available at the SMSC website http://www.smsc.com

View File

@ -315,7 +315,7 @@ Andrew Morton が Linux-kernel メーリングリストにカーネルリリー
もし、2.6.x.y カーネルが存在しない場合には、番号が一番大きい 2.6.x が
最新の安定版カーネルです。
2.6.x.y は "stable" チーム <stable@kernel.org> でメンテされており、必
2.6.x.y は "stable" チーム <stable@vger.kernel.org> でメンテされており、必
要に応じてリリースされます。通常のリリース期間は 2週間毎ですが、差し迫っ
た問題がなければもう少し長くなることもあります。セキュリティ関連の問題
の場合はこれに対してだいたいの場合、すぐにリリースがされます。

View File

@ -50,16 +50,16 @@ linux-2.6.29/Documentation/stable_kernel_rules.txt
-stable ツリーにパッチを送付する手続き-
- 上記の規則に従っているかを確認した後に、stable@kernel.org にパッチ
- 上記の規則に従っているかを確認した後に、stable@vger.kernel.org にパッチ
を送る。
- 送信者はパッチがキューに受け付けられた際には ACK を、却下された場合
には NAK を受け取る。この反応は開発者たちのスケジュールによって、数
日かかる場合がある。
- もし受け取られたら、パッチは他の開発者たちと関連するサブシステムの
メンテナーによるレビューのために -stable キューに追加される。
- パッチに stable@kernel.org のアドレスが付加されているときには、それ
- パッチに stable@vger.kernel.org のアドレスが付加されているときには、それ
が Linus のツリーに入る時に自動的に stable チームに email される。
- セキュリティパッチはこのエイリアス (stable@kernel.org) に送られるべ
- セキュリティパッチはこのエイリアス (stable@vger.kernel.org) に送られるべ
きではなく、代わりに security@kernel.org のアドレスに送られる。
レビューサイクル-

View File

@ -566,6 +566,8 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
UART at the specified I/O port or MMIO address,
switching to the matching ttyS device later. The
options are the same as for ttyS, above.
hvc<n> Use the hypervisor console device <n>. This is for
both Xen and PowerPC hypervisors.
If the device connected to the port is not a TTY but a braille
device, prepend "brl," before the device type, for instance
@ -751,6 +753,7 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
earlyprintk= [X86,SH,BLACKFIN]
earlyprintk=vga
earlyprintk=xen
earlyprintk=serial[,ttySn[,baudrate]]
earlyprintk=ttySn[,baudrate]
earlyprintk=dbgp[debugController#]
@ -768,6 +771,8 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
The VGA output is eventually overwritten by the real
console.
The xen output can only be used by Xen PV guests.
ekgdboc= [X86,KGDB] Allow early kernel console debugging
ekgdboc=kbd
@ -777,6 +782,12 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
edd= [EDD]
Format: {"off" | "on" | "skip[mbr]"}
efi_no_storage_paranoia [EFI; X86]
Using this parameter you can use more than 50% of
your efi variable storage. Use this parameter only if
you are really sure that your UEFI does sane gc and
fulfills the spec otherwise your board may brick.
eisa_irq_edge= [PARISC,HW]
See header of drivers/parisc/eisa.c.
@ -991,6 +1002,20 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
i8k.restricted [HW] Allow controlling fans only if SYS_ADMIN
capability is set.
i915.invert_brightness=
[DRM] Invert the sense of the variable that is used to
set the brightness of the panel backlight. Normally a
brightness value of 0 indicates backlight switched off,
and the maximum of the brightness value sets the backlight
to maximum brightness. If this parameter is set to 0
(default) and the machine requires it, or this parameter
is set to 1, a brightness value of 0 sets the backlight
to maximum brightness, and the maximum of the brightness
value switches the backlight off.
-1 -- never invert brightness
0 -- machine default
1 -- force brightness inversion
icn= [HW,ISDN]
Format: <io>[,<membase>[,<icn_id>[,<icn_id2>]]]

View File

@ -537,6 +537,11 @@ tcp_thin_dupack - BOOLEAN
Documentation/networking/tcp-thin.txt
Default: 0
tcp_challenge_ack_limit - INTEGER
Limits number of Challenge ACK sent per second, as recommended
in RFC 5961 (Improving TCP's Robustness to Blind In-Window Attacks)
Default: 100
UDP variables:
udp_mem - vector of 3 INTEGERs: min, pressure, max

View File

@ -21,10 +21,11 @@ ALC267/268
==========
N/A
ALC269
ALC269/270/275/276/280/282
======
laptop-amic Laptops with analog-mic input
laptop-dmic Laptops with digital-mic input
lenovo-dock Enables docking station I/O for some Lenovos
ALC662/663/272
==============
@ -46,6 +47,7 @@ ALC882/883/885/888/889
acer-aspire-4930g Acer Aspire 4930G/5930G/6530G/6930G/7730G
acer-aspire-8930g Acer Aspire 8330G/6935G
acer-aspire Acer Aspire others
no-primary-hp VAIO Z workaround (for fixed speaker DAC)
ALC861/660
==========

View File

@ -1,4 +1,4 @@
Everything you ever wanted to know about Linux 2.6 -stable releases.
Everything you ever wanted to know about Linux -stable releases.
Rules on what kind of patches are accepted, and which ones are not, into the
"-stable" tree:
@ -12,6 +12,12 @@ Rules on what kind of patches are accepted, and which ones are not, into the
marked CONFIG_BROKEN), an oops, a hang, data corruption, a real
security issue, or some "oh, that's not good" issue. In short, something
critical.
- Serious issues as reported by a user of a distribution kernel may also
be considered if they fix a notable performance or interactivity issue.
As these fixes are not as obvious and have a higher risk of a subtle
regression they should only be submitted by a distribution kernel
maintainer and include an addendum linking to a bugzilla entry if it
exists and additional information on the user-visible impact.
- New device IDs and quirks are also accepted.
- No "theoretical race condition" issues, unless an explanation of how the
race can be exploited is also provided.
@ -36,10 +42,10 @@ Procedure for submitting patches to the -stable tree:
cherry-picked than this can be specified in the following format in
the sign-off area:
Cc: <stable@vger.kernel.org> # .32.x: a1f84a3: sched: Check for idle
Cc: <stable@vger.kernel.org> # .32.x: 1b9508f: sched: Rate-limit newidle
Cc: <stable@vger.kernel.org> # .32.x: fd21073: sched: Fix affinity logic
Cc: <stable@vger.kernel.org> # .32.x
Cc: <stable@vger.kernel.org> # 3.3.x: a1f84a3: sched: Check for idle
Cc: <stable@vger.kernel.org> # 3.3.x: 1b9508f: sched: Rate-limit newidle
Cc: <stable@vger.kernel.org> # 3.3.x: fd21073: sched: Fix affinity logic
Cc: <stable@vger.kernel.org> # 3.3.x
Signed-off-by: Ingo Molnar <mingo@elte.hu>
The tag sequence has the meaning of:
@ -73,6 +79,15 @@ Review cycle:
security kernel team, and not go through the normal review cycle.
Contact the kernel security team for more details on this procedure.
Trees:
- The queues of patches, for both completed versions and in progress
versions can be found at:
http://git.kernel.org/?p=linux/kernel/git/stable/stable-queue.git
- The finalized and tagged releases of all stable kernels can be found
in separate branches per version at:
http://git.kernel.org/?p=linux/kernel/git/stable/linux-stable.git
Review committee:

View File

@ -298,13 +298,24 @@ Default value is "/sbin/hotplug".
kptr_restrict:
This toggle indicates whether restrictions are placed on
exposing kernel addresses via /proc and other interfaces. When
kptr_restrict is set to (0), there are no restrictions. When
kptr_restrict is set to (1), the default, kernel pointers
printed using the %pK format specifier will be replaced with 0's
unless the user has CAP_SYSLOG. When kptr_restrict is set to
(2), kernel pointers printed using %pK will be replaced with 0's
regardless of privileges.
exposing kernel addresses via /proc and other interfaces.
When kptr_restrict is set to (0), the default, there are no restrictions.
When kptr_restrict is set to (1), kernel pointers printed using the %pK
format specifier will be replaced with 0's unless the user has CAP_SYSLOG
and effective user and group ids are equal to the real ids. This is
because %pK checks are done at read() time rather than open() time, so
if permissions are elevated between the open() and the read() (e.g via
a setuid binary) then %pK will not leak kernel pointers to unprivileged
users. Note, this is a temporary solution only. The correct long-term
solution is to do the permission checks at open() time. Consider removing
world read permissions from files that use %pK, and using dmesg_restrict
to protect against uses of %pK in dmesg(8) if leaking kernel pointer
values to unprivileged users is a concern.
When kptr_restrict is set to (2), kernel pointers printed using
%pK will be replaced with 0's regardless of privileges.
==============================================================

View File

@ -12,6 +12,8 @@ ffffc90000000000 - ffffe8ffffffffff (=45 bits) vmalloc/ioremap space
ffffe90000000000 - ffffe9ffffffffff (=40 bits) hole
ffffea0000000000 - ffffeaffffffffff (=40 bits) virtual memory map (1TB)
... unused hole ...
ffffff0000000000 - ffffff7fffffffff (=39 bits) %esp fixup stacks
... unused hole ...
ffffffff80000000 - ffffffffa0000000 (=512 MB) kernel text mapping, from phys 0
ffffffffa0000000 - fffffffffff00000 (=1536 MB) module mapping space

View File

@ -237,7 +237,7 @@ kernel.org网站的pub/linux/kernel/v2.6/目录下找到它。它的开发遵循
如果没有2.6.x.y版本内核存在那么最新的2.6.x版本内核就相当于是当前的稳定
版内核。
2.6.x.y版本由“稳定版”小组邮件地址<stable@kernel.org>)维护,一般隔周发
2.6.x.y版本由“稳定版”小组邮件地址<stable@vger.kernel.org>)维护,一般隔周发
布新版本。
内核源码中的Documentation/stable_kernel_rules.txt文件具体描述了可被稳定

View File

@ -42,7 +42,7 @@ Documentation/stable_kernel_rules.txt 的中文翻译
向稳定版代码树提交补丁的过程:
- 在确认了补丁符合以上的规则后将补丁发送到stable@kernel.org。
- 在确认了补丁符合以上的规则后将补丁发送到stable@vger.kernel.org。
- 如果补丁被接受到队列里发送者会收到一个ACK回复如果没有被接受
到的是NAK回复。回复需要几天的时间这取决于开发者的时间安排。
- 被接受的补丁会被加到稳定版本队列里,等待其他开发者的审查。

View File

@ -2627,7 +2627,7 @@ S: Maintained
F: drivers/net/ethernet/i825xx/eexpress.*
ETHERNET BRIDGE
M: Stephen Hemminger <shemminger@vyatta.com>
M: Stephen Hemminger <stephen@networkplumber.org>
L: bridge@lists.linux-foundation.org
L: netdev@vger.kernel.org
W: http://www.linuxfoundation.org/en/Net:Bridge
@ -4323,7 +4323,7 @@ S: Maintained
MARVELL GIGABIT ETHERNET DRIVERS (skge/sky2)
M: Mirko Lindner <mlindner@marvell.com>
M: Stephen Hemminger <shemminger@vyatta.com>
M: Stephen Hemminger <stephen@networkplumber.org>
L: netdev@vger.kernel.org
S: Maintained
F: drivers/net/ethernet/marvell/sk*
@ -4574,7 +4574,7 @@ S: Supported
F: drivers/infiniband/hw/nes/
NETEM NETWORK EMULATOR
M: Stephen Hemminger <shemminger@vyatta.com>
M: Stephen Hemminger <stephen@networkplumber.org>
L: netem@lists.linux-foundation.org
S: Maintained
F: net/sched/sch_netem.c
@ -5577,7 +5577,7 @@ F: Documentation/blockdev/ramdisk.txt
F: drivers/block/brd.c
RANDOM NUMBER DRIVER
M: Matt Mackall <mpm@selenic.com>
M: Theodore Ts'o" <tytso@mit.edu>
S: Maintained
F: drivers/char/random.c
@ -6401,6 +6401,7 @@ STABLE BRANCH
M: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
L: stable@vger.kernel.org
S: Supported
F: Documentation/stable_kernel_rules.txt
STAGING SUBSYSTEM
M: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

View File

@ -1,6 +1,6 @@
VERSION = 3
PATCHLEVEL = 4
SUBLEVEL = 0
SUBLEVEL = 103
EXTRAVERSION =
NAME = Saber-toothed Squirrel
@ -597,6 +597,8 @@ KBUILD_CFLAGS += -fomit-frame-pointer
endif
endif
KBUILD_CFLAGS += $(call cc-option, -fno-var-tracking-assignments)
ifdef CONFIG_DEBUG_INFO
KBUILD_CFLAGS += -g
KBUILD_AFLAGS += -gdwarf-2
@ -885,6 +887,7 @@ endef
# Generate .S file with all kernel symbols
quiet_cmd_kallsyms = KSYM $@
cmd_kallsyms = $(NM) -n $< | $(KALLSYMS) \
--page-offset=$(CONFIG_PAGE_OFFSET) \
$(if $(CONFIG_KALLSYMS_ALL),--all-symbols) > $@
.tmp_kallsyms1.o .tmp_kallsyms2.o .tmp_kallsyms3.o: %.o: %.S scripts FORCE

View File

@ -12,7 +12,7 @@ NM := $(NM) -B
LDFLAGS_vmlinux := -static -N #-relax
CHECKFLAGS += -D__alpha__ -m64
cflags-y := -pipe -mno-fp-regs -ffixed-8 -msmall-data
cflags-y := -pipe -mno-fp-regs -ffixed-8
cflags-y += $(call cc-option, -fno-jump-tables)
cpuflags-$(CONFIG_ALPHA_EV4) := -mcpu=ev4

View File

@ -14,8 +14,8 @@
*/
#define ATOMIC_INIT(i) ( (atomic_t) { (i) } )
#define ATOMIC64_INIT(i) ( (atomic64_t) { (i) } )
#define ATOMIC_INIT(i) { (i) }
#define ATOMIC64_INIT(i) { (i) }
#define atomic_read(v) (*(volatile int *)&(v)->counter)
#define atomic64_read(v) (*(volatile long *)&(v)->counter)

View File

@ -1,7 +1,9 @@
#ifndef __ASM_ALPHA_FPU_H
#define __ASM_ALPHA_FPU_H
#ifdef __KERNEL__
#include <asm/special_insns.h>
#endif
/*
* Alpha floating-point control register defines:

View File

@ -76,9 +76,11 @@
/* Instruct lower device to use last 4-bytes of skb data as FCS */
#define SO_NOFCS 43
#ifdef __KERNEL__
/* O_NONBLOCK clashes with the bits used for socket types. Therefore we
* have to define SOCK_NONBLOCK to a different value here.
*/
#define SOCK_NONBLOCK 0x40000000
#endif /* __KERNEL__ */
#endif /* _ASM_SOCKET_H */

View File

@ -28,6 +28,7 @@
#include <linux/tty.h>
#include <linux/console.h>
#include <linux/slab.h>
#include <linux/rcupdate.h>
#include <asm/reg.h>
#include <asm/uaccess.h>
@ -54,8 +55,11 @@ cpu_idle(void)
/* FIXME -- EV6 and LCA45 know how to power down
the CPU. */
rcu_idle_enter();
while (!need_resched())
cpu_relax();
rcu_idle_exit();
schedule();
}
}

View File

@ -188,6 +188,10 @@ nautilus_machine_check(unsigned long vector, unsigned long la_ptr)
extern void free_reserved_mem(void *, void *);
extern void pcibios_claim_one_bus(struct pci_bus *);
static struct resource irongate_io = {
.name = "Irongate PCI IO",
.flags = IORESOURCE_IO,
};
static struct resource irongate_mem = {
.name = "Irongate PCI MEM",
.flags = IORESOURCE_MEM,
@ -209,6 +213,7 @@ nautilus_init_pci(void)
irongate = pci_get_bus_and_slot(0, 0);
bus->self = irongate;
bus->resource[0] = &irongate_io;
bus->resource[1] = &irongate_mem;
pci_bus_size_bridges(bus);

View File

@ -1,7 +1,6 @@
config ARM
bool
default y
select HAVE_AOUT
select HAVE_DMA_API_DEBUG
select HAVE_IDE if PCI || ISA || PCMCIA
select HAVE_DMA_CONTIGUOUS if (CPU_V6 || CPU_V6K || CPU_V7)
@ -607,7 +606,7 @@ config ARCH_IXP4XX
select ARCH_HAS_DMA_SET_COHERENT_MASK
select CLKSRC_MMIO
select CPU_XSCALE
select GENERIC_GPIO
select ARCH_REQUIRE_GPIOLIB
select GENERIC_CLOCKEVENTS
select MIGHT_HAVE_PCI
select NEED_MACH_IO_H
@ -630,6 +629,7 @@ config ARCH_KIRKWOOD
bool "Marvell Kirkwood"
select CPU_FEROCEON
select PCI
select PCI_QUIRKS
select ARCH_REQUIRE_GPIOLIB
select GENERIC_CLOCKEVENTS
select NEED_MACH_IO_H
@ -1496,6 +1496,16 @@ config KSAPI
Scorpion processor supported hardware performance counters on a per
thread basis or AXI counters on an overall system basis.
config ARM_ERRATA_775420
bool "ARM errata: A data cache maintenance operation which aborts, might lead to deadlock"
depends on CPU_V7
help
This option enables the workaround for the 775420 Cortex-A9 (r2p2,
r2p6,r2p8,r2p10,r3p0) erratum. In case a date cache maintenance
operation aborts with MMU exception, it might cause the processor
to deadlock. This workaround puts DSB before executing ISB if
an abort may occur on cache maintenance.
endmenu
source "arch/arm/common/Kconfig"
@ -2314,6 +2324,7 @@ source "drivers/cpufreq/Kconfig"
config CPU_FREQ_IMX
tristate "CPUfreq driver for i.MX CPUs"
depends on ARCH_MXC && CPU_FREQ
select CPU_FREQ_TABLE
help
This enables the CPUfreq driver for i.MX CPUs.

View File

@ -295,10 +295,10 @@ zImage Image xipImage bootpImage uImage: vmlinux
zinstall uinstall install: vmlinux
$(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $@
%.dtb:
%.dtb: scripts
$(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $(boot)/$@
dtbs:
dtbs: scripts
$(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $(boot)/$@
# We use MRPROPER_FILES and CLEAN_FILES now

View File

@ -771,6 +771,7 @@ __armv7_mmu_cache_on:
mcrne p15, 0, r0, c8, c7, 0 @ flush I,D TLBs
#endif
mrc p15, 0, r0, c1, c0, 0 @ read control reg
bic r0, r0, #1 << 28 @ clear SCTLR.TRE
orr r0, r0, #0x5000 @ I-cache enable, RR cache replacement
orr r0, r0, #0x003c @ write buffer
#ifdef CONFIG_MMU

View File

@ -29,8 +29,8 @@
aips@70000000 { /* aips-1 */
spba@70000000 {
esdhc@70004000 { /* ESDHC1 */
fsl,cd-internal;
fsl,wp-internal;
fsl,cd-controller;
fsl,wp-controller;
status = "okay";
};

View File

@ -70,10 +70,30 @@
interrupt-parent = <&gpio2>;
interrupts = <31>;
reg-io-width = <4>;
/*
* VDD33A and VDDVARIO of LAN9220 are supplied by
* SW4_3V3 of LTC3589. Before the regulator driver
* for this PMIC is available, we use a fixed dummy
* 3V3 regulator to get LAN9220 driver probing work.
*/
vdd33a-supply = <&reg_3p3v>;
vddvario-supply = <&reg_3p3v>;
smsc,irq-push-pull;
};
};
regulators {
compatible = "simple-bus";
reg_3p3v: 3p3v {
compatible = "regulator-fixed";
regulator-name = "3P3V";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
regulator-always-on;
};
};
gpio-keys {
compatible = "gpio-keys";

View File

@ -64,7 +64,7 @@
status = "disable";
};
sdhci@78000400 {
sdhci@78000600 {
support-8bit;
};
};

View File

@ -173,7 +173,6 @@ CONFIG_MMC=y
# CONFIG_MMC_BLOCK_BOUNCE is not set
CONFIG_SDIO_UART=m
CONFIG_MMC_ATMELMCI=y
CONFIG_MMC_ATMELMCI_DMA=y
CONFIG_LEDS_ATMEL_PWM=y
CONFIG_LEDS_GPIO=y
CONFIG_LEDS_TRIGGER_TIMER=y

View File

@ -267,6 +267,7 @@ CONFIG_BT_HCIUART_ATH3K=y
CONFIG_MSM_BT_POWER=y
CONFIG_CFG80211=y
CONFIG_CFG80211_INTERNAL_REGDB=y
CONFIG_NL80211_TESTMODE=y
# CONFIG_CFG80211_WEXT is not set
CONFIG_RFKILL=y
CONFIG_GENLOCK=y

View File

@ -32,7 +32,6 @@ CONFIG_NO_HZ=y
CONFIG_HIGH_RES_TIMERS=y
CONFIG_PREEMPT_VOLUNTARY=y
CONFIG_AEABI=y
CONFIG_DEFAULT_MMAP_MIN_ADDR=65536
CONFIG_AUTO_ZRELADDR=y
CONFIG_FPE_NWFPE=y
CONFIG_NET=y

View File

@ -1,45 +0,0 @@
/* a.out coredump register dumper
*
* Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
* Written by David Howells (dhowells@redhat.com)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public Licence
* as published by the Free Software Foundation; either version
* 2 of the Licence, or (at your option) any later version.
*/
#ifndef _ASM_A_OUT_CORE_H
#define _ASM_A_OUT_CORE_H
#ifdef __KERNEL__
#include <linux/user.h>
#include <linux/elfcore.h>
/*
* fill in the user structure for an a.out core dump
*/
static inline void aout_dump_thread(struct pt_regs *regs, struct user *dump)
{
struct task_struct *tsk = current;
dump->magic = CMAGIC;
dump->start_code = tsk->mm->start_code;
dump->start_stack = regs->ARM_sp & ~(PAGE_SIZE - 1);
dump->u_tsize = (tsk->mm->end_code - tsk->mm->start_code) >> PAGE_SHIFT;
dump->u_dsize = (tsk->mm->brk - tsk->mm->start_data + PAGE_SIZE - 1) >> PAGE_SHIFT;
dump->u_ssize = 0;
memset(dump->u_debugreg, 0, sizeof(dump->u_debugreg));
if (dump->start_stack < 0x04000000)
dump->u_ssize = (0x04000000 - dump->start_stack) >> PAGE_SHIFT;
dump->regs = *regs;
dump->u_fpvalid = dump_fpu (regs, &dump->u_fp);
}
#endif /* __KERNEL__ */
#endif /* _ASM_A_OUT_CORE_H */

View File

@ -1,34 +0,0 @@
#ifndef __ARM_A_OUT_H__
#define __ARM_A_OUT_H__
#include <linux/personality.h>
#include <linux/types.h>
struct exec
{
__u32 a_info; /* Use macros N_MAGIC, etc for access */
__u32 a_text; /* length of text, in bytes */
__u32 a_data; /* length of data, in bytes */
__u32 a_bss; /* length of uninitialized data area for file, in bytes */
__u32 a_syms; /* length of symbol table data in file, in bytes */
__u32 a_entry; /* start address */
__u32 a_trsize; /* length of relocation info for text, in bytes */
__u32 a_drsize; /* length of relocation info for data, in bytes */
};
/*
* This is always the same
*/
#define N_TXTADDR(a) (0x00008000)
#define N_TRSIZE(a) ((a).a_trsize)
#define N_DRSIZE(a) ((a).a_drsize)
#define N_SYMSIZE(a) ((a).a_syms)
#define M_ARM 103
#ifndef LIBRARY_START_TEXT
#define LIBRARY_START_TEXT (0x00c00000)
#endif
#endif /* __A_OUT_GNU_H__ */

View File

@ -233,6 +233,7 @@ extern void copy_to_user_page(struct vm_area_struct *, struct page *,
static inline void __flush_icache_all(void)
{
__flush_icache_preferred();
dsb();
}
/*
@ -251,7 +252,9 @@ static inline void vivt_flush_cache_mm(struct mm_struct *mm)
static inline void
vivt_flush_cache_range(struct vm_area_struct *vma, unsigned long start, unsigned long end)
{
if (cpumask_test_cpu(smp_processor_id(), mm_cpumask(vma->vm_mm)))
struct mm_struct *mm = vma->vm_mm;
if (!mm || cpumask_test_cpu(smp_processor_id(), mm_cpumask(mm)))
__cpuc_flush_user_range(start & PAGE_MASK, PAGE_ALIGN(end),
vma->vm_flags);
}
@ -259,7 +262,9 @@ vivt_flush_cache_range(struct vm_area_struct *vma, unsigned long start, unsigned
static inline void
vivt_flush_cache_page(struct vm_area_struct *vma, unsigned long user_addr, unsigned long pfn)
{
if (cpumask_test_cpu(smp_processor_id(), mm_cpumask(vma->vm_mm))) {
struct mm_struct *mm = vma->vm_mm;
if (!mm || cpumask_test_cpu(smp_processor_id(), mm_cpumask(mm))) {
unsigned long addr = user_addr & PAGE_MASK;
__cpuc_flush_user_range(addr, addr + PAGE_SIZE, vma->vm_flags);
}
@ -337,9 +342,7 @@ static inline void flush_anon_page(struct vm_area_struct *vma,
}
#define ARCH_HAS_FLUSH_KERNEL_DCACHE_PAGE
static inline void flush_kernel_dcache_page(struct page *page)
{
}
extern void flush_kernel_dcache_page(struct page *);
#define flush_dcache_mmap_lock(mapping) \
spin_lock_irq(&(mapping)->tree_lock)

View File

@ -156,7 +156,7 @@
/* Select the best insn combination to perform the */ \
/* actual __m * __n / (__p << 64) operation. */ \
if (!__c) { \
asm ( "umull %Q0, %R0, %1, %Q2\n\t" \
asm ( "umull %Q0, %R0, %Q1, %Q2\n\t" \
"mov %Q0, #0" \
: "=&r" (__res) \
: "r" (__m), "r" (__n) \

View File

@ -18,11 +18,12 @@
#define HWCAP_THUMBEE (1 << 11)
#define HWCAP_NEON (1 << 12)
#define HWCAP_VFPv3 (1 << 13)
#define HWCAP_VFPv3D16 (1 << 14)
#define HWCAP_VFPv3D16 (1 << 14) /* also set for VFPv4-D16 */
#define HWCAP_TLS (1 << 15)
#define HWCAP_VFPv4 (1 << 16)
#define HWCAP_IDIVA (1 << 17)
#define HWCAP_IDIVT (1 << 18)
#define HWCAP_VFPD32 (1 << 19) /* set if VFP has 32 regs (not 16) */
#define HWCAP_IDIV (HWCAP_IDIVA | HWCAP_IDIVT)
#if defined(__KERNEL__)

View File

@ -5,19 +5,16 @@
typedef struct {
#ifdef CONFIG_CPU_HAS_ASID
unsigned int id;
raw_spinlock_t id_lock;
u64 id;
#endif
unsigned int kvm_seq;
unsigned long sigpage;
} mm_context_t;
#ifdef CONFIG_CPU_HAS_ASID
#define ASID(mm) ((mm)->context.id & 255)
/* init_mm.context.id_lock should be initialized. */
#define INIT_MM_CONTEXT(name) \
.context.id_lock = __RAW_SPIN_LOCK_UNLOCKED(name.context.id_lock),
#define ASID_BITS 8
#define ASID_MASK ((~0ULL) << ASID_BITS)
#define ASID(mm) ((mm)->context.id & ~ASID_MASK)
#else
#define ASID(mm) (0)
#endif

View File

@ -24,50 +24,12 @@ void __check_kvm_seq(struct mm_struct *mm);
#ifdef CONFIG_CPU_HAS_ASID
/*
* On ARMv6, we have the following structure in the Context ID:
*
* 31 7 0
* +-------------------------+-----------+
* | process ID | ASID |
* +-------------------------+-----------+
* | context ID |
* +-------------------------------------+
*
* The ASID is used to tag entries in the CPU caches and TLBs.
* The context ID is used by debuggers and trace logic, and
* should be unique within all running processes.
*/
#define ASID_BITS 8
#define ASID_MASK ((~0) << ASID_BITS)
#define ASID_FIRST_VERSION (1 << ASID_BITS)
extern unsigned int cpu_last_asid;
#ifdef CONFIG_SMP
DECLARE_PER_CPU(struct mm_struct *, current_mm);
#endif
void __init_new_context(struct task_struct *tsk, struct mm_struct *mm);
void __new_context(struct mm_struct *mm);
static inline void check_context(struct mm_struct *mm)
{
/*
* This code is executed with interrupts enabled. Therefore,
* mm->context.id cannot be updated to the latest ASID version
* on a different CPU (and condition below not triggered)
* without first getting an IPI to reset the context. The
* alternative is to take a read_lock on mm->context.id_lock
* (after changing its type to rwlock_t).
*/
if (unlikely((mm->context.id ^ cpu_last_asid) >> ASID_BITS))
__new_context(mm);
if (unlikely(mm->context.kvm_seq != init_mm.context.kvm_seq))
__check_kvm_seq(mm);
}
#define init_new_context(tsk,mm) (__init_new_context(tsk,mm),0)
void check_and_switch_context(struct mm_struct *mm, struct task_struct *tsk);
#define init_new_context(tsk,mm) ({ mm->context.id = 0; })
#else
@ -84,7 +46,7 @@ static inline void check_context(struct mm_struct *mm)
#endif
#define destroy_context(mm) do { } while(0)
#define activate_mm(prev,next) switch_mm(prev, next, NULL)
/*
* This is called when "tsk" is about to enter lazy TLB mode.
*
@ -123,8 +85,7 @@ switch_mm(struct mm_struct *prev, struct mm_struct *next,
struct mm_struct **crt_mm = &per_cpu(current_mm, cpu);
*crt_mm = next;
#endif
check_context(next);
cpu_switch_mm(next->pgd, next);
check_and_switch_context(next, tsk);
if (cache_is_vivt())
cpumask_clear_cpu(cpu, mm_cpumask(prev));
}
@ -132,6 +93,5 @@ switch_mm(struct mm_struct *prev, struct mm_struct *next,
}
#define deactivate_mm(tsk,mm) do { } while (0)
#define activate_mm(prev,next) switch_mm(prev, next, NULL)
#endif

View File

@ -37,10 +37,10 @@ struct outer_cache_fns {
void (*resume)(void);
};
#ifdef CONFIG_OUTER_CACHE
extern struct outer_cache_fns outer_cache;
#ifdef CONFIG_OUTER_CACHE
static inline void outer_inv_range(phys_addr_t start, phys_addr_t end)
{
if (outer_cache.inv_range)

View File

@ -60,6 +60,15 @@ extern void __pgd_error(const char *file, int line, pgd_t);
*/
#define FIRST_USER_ADDRESS PAGE_SIZE
/*
* Use TASK_SIZE as the ceiling argument for free_pgtables() and
* free_pgd_range() to avoid freeing the modules pmd when LPAE is enabled (pmd
* page shared between user and kernel).
*/
#ifdef CONFIG_ARM_LPAE
#define USER_PGTABLES_CEILING TASK_SIZE
#endif
/*
* The pgprot_* and protection_map entries will be fixed up in runtime
* to include the cachable and bufferable bits based on memory policy,
@ -209,25 +218,6 @@ static inline pte_t *pmd_page_vaddr(pmd_t pmd)
#define pte_clear(mm,addr,ptep) set_pte_ext(ptep, __pte(0), 0)
#if __LINUX_ARM_ARCH__ < 6
static inline void __sync_icache_dcache(pte_t pteval)
{
}
#else
extern void __sync_icache_dcache(pte_t pteval);
#endif
static inline void set_pte_at(struct mm_struct *mm, unsigned long addr,
pte_t *ptep, pte_t pteval)
{
if (addr >= TASK_SIZE)
set_pte_ext(ptep, pteval, 0);
else {
__sync_icache_dcache(pteval);
set_pte_ext(ptep, pteval, PTE_EXT_NG);
}
}
#define pte_none(pte) (!pte_val(pte))
#define pte_present(pte) (pte_val(pte) & L_PTE_PRESENT)
#define pte_write(pte) (!(pte_val(pte) & L_PTE_RDONLY))
@ -240,6 +230,27 @@ static inline void set_pte_at(struct mm_struct *mm, unsigned long addr,
((pte_val(pte) & (L_PTE_PRESENT | L_PTE_USER)) == \
(L_PTE_PRESENT | L_PTE_USER))
#if __LINUX_ARM_ARCH__ < 6
static inline void __sync_icache_dcache(pte_t pteval)
{
}
#else
extern void __sync_icache_dcache(pte_t pteval);
#endif
static inline void set_pte_at(struct mm_struct *mm, unsigned long addr,
pte_t *ptep, pte_t pteval)
{
unsigned long ext = 0;
if (addr < TASK_SIZE && pte_present_user(pteval)) {
__sync_icache_dcache(pteval);
ext |= PTE_EXT_NG;
}
set_pte_ext(ptep, pteval, ext);
}
#define PTE_BIT_FUNC(fn,op) \
static inline pte_t pte_##fn(pte_t pte) { pte_val(pte) op; return pte; }
@ -267,13 +278,13 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
*
* 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
* 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
* <--------------- offset --------------------> <- type --> 0 0 0
* <--------------- offset ----------------------> < type -> 0 0 0
*
* This gives us up to 63 swap files and 32GB per swap file. Note that
* This gives us up to 31 swap files and 64GB per swap file. Note that
* the offset field is always non-zero.
*/
#define __SWP_TYPE_SHIFT 3
#define __SWP_TYPE_BITS 6
#define __SWP_TYPE_BITS 5
#define __SWP_TYPE_MASK ((1 << __SWP_TYPE_BITS) - 1)
#define __SWP_OFFSET_SHIFT (__SWP_TYPE_BITS + __SWP_TYPE_SHIFT)

View File

@ -137,6 +137,8 @@ struct arm_pmu {
struct pmu_hw_events *(*get_hw_events)(void);
int (*test_set_event_constraints)(struct perf_event *event);
int (*clear_event_constraints)(struct perf_event *event);
void (*save_pm_registers)(void *hcpu);
void (*restore_pm_registers)(void *hcpu);
};
#define to_arm_pmu(p) (container_of(p, struct arm_pmu, pmu))

View File

@ -56,7 +56,6 @@ struct thread_struct {
#define start_thread(regs,pc,sp) \
({ \
unsigned long *stack = (unsigned long *)sp; \
memset(regs->uregs, 0, sizeof(regs->uregs)); \
if (current->personality & ADDR_LIMIT_32BIT) \
regs->ARM_cpsr = USR_MODE; \
@ -67,9 +66,6 @@ struct thread_struct {
regs->ARM_cpsr |= PSR_ENDSTATE; \
regs->ARM_pc = pc & ~1; /* pc */ \
regs->ARM_sp = sp; /* sp */ \
regs->ARM_r2 = stack[2]; /* r2 (envp) */ \
regs->ARM_r1 = stack[1]; /* r1 (argv) */ \
regs->ARM_r0 = stack[0]; /* r0 (argc) */ \
nommu_start_thread(regs); \
})

View File

@ -127,6 +127,7 @@ struct sigaction {
__sigrestore_t sa_restorer;
sigset_t sa_mask; /* mask last for extensibility */
};
#define __ARCH_HAS_SA_RESTORER
struct k_sigaction {
struct sigaction sa;

View File

@ -158,8 +158,9 @@ extern int __put_user_8(void *, unsigned long long);
#define put_user(x,p) \
({ \
unsigned long __limit = current_thread_info()->addr_limit - 1; \
const typeof(*(p)) __user *__tmp_p = (p); \
register const typeof(*(p)) __r2 asm("r2") = (x); \
register const typeof(*(p)) __user *__p asm("r0") = (p);\
register const typeof(*(p)) __user *__p asm("r0") = __tmp_p; \
register unsigned long __l asm("r1") = __limit; \
register int __e asm("r0"); \
switch (sizeof(*(__p))) { \

View File

@ -27,9 +27,9 @@
#if __LINUX_ARM_ARCH__ <= 6
ldr \tmp, =elf_hwcap @ may not have MVFR regs
ldr \tmp, [\tmp, #0]
tst \tmp, #HWCAP_VFPv3D16
ldceq p11, cr0, [\base],#32*4 @ FLDMIAD \base!, {d16-d31}
addne \base, \base, #32*4 @ step over unused register space
tst \tmp, #HWCAP_VFPD32
ldcnel p11, cr0, [\base],#32*4 @ FLDMIAD \base!, {d16-d31}
addeq \base, \base, #32*4 @ step over unused register space
#else
VFPFMRX \tmp, MVFR0 @ Media and VFP Feature Register 0
and \tmp, \tmp, #MVFR0_A_SIMD_MASK @ A_SIMD field
@ -51,9 +51,9 @@
#if __LINUX_ARM_ARCH__ <= 6
ldr \tmp, =elf_hwcap @ may not have MVFR regs
ldr \tmp, [\tmp, #0]
tst \tmp, #HWCAP_VFPv3D16
stceq p11, cr0, [\base],#32*4 @ FSTMIAD \base!, {d16-d31}
addne \base, \base, #32*4 @ step over unused register space
tst \tmp, #HWCAP_VFPD32
stcnel p11, cr0, [\base],#32*4 @ FSTMIAD \base!, {d16-d31}
addeq \base, \base, #32*4 @ step over unused register space
#else
VFPFMRX \tmp, MVFR0 @ Media and VFP Feature Register 0
and \tmp, \tmp, #MVFR0_A_SIMD_MASK @ A_SIMD field

View File

@ -39,7 +39,7 @@ ssize_t copy_oldmem_page(unsigned long pfn, char *buf,
if (!csize)
return 0;
vaddr = ioremap(pfn << PAGE_SHIFT, PAGE_SIZE);
vaddr = ioremap(__pfn_to_phys(pfn), PAGE_SIZE);
if (!vaddr)
return -ENOMEM;

View File

@ -244,6 +244,19 @@ svc_preempt:
b 1b
#endif
__und_fault:
@ Correct the PC such that it is pointing at the instruction
@ which caused the fault. If the faulting instruction was ARM
@ the PC will be pointing at the next instruction, and have to
@ subtract 4. Otherwise, it is Thumb, and the PC will be
@ pointing at the second half of the Thumb instruction. We
@ have to subtract 2.
ldr r2, [r0, #S_PC]
sub r2, r2, r1
str r2, [r0, #S_PC]
b do_undefinstr
ENDPROC(__und_fault)
.align 5
__und_svc:
#ifdef CONFIG_KPROBES
@ -261,25 +274,32 @@ __und_svc:
@
@ r0 - instruction
@
#ifndef CONFIG_THUMB2_KERNEL
#ifndef CONFIG_THUMB2_KERNEL
ldr r0, [r4, #-4]
#else
mov r1, #2
ldrh r0, [r4, #-2] @ Thumb instruction at LR - 2
cmp r0, #0xe800 @ 32-bit instruction if xx >= 0
ldrhhs r9, [r4] @ bottom 16 bits
orrhs r0, r9, r0, lsl #16
blo __und_svc_fault
ldrh r9, [r4] @ bottom 16 bits
add r4, r4, #2
str r4, [sp, #S_PC]
orr r0, r9, r0, lsl #16
#endif
adr r9, BSYM(1f)
adr r9, BSYM(__und_svc_finish)
mov r2, r4
bl call_fpe
mov r1, #4 @ PC correction to apply
__und_svc_fault:
mov r0, sp @ struct pt_regs *regs
bl do_undefinstr
bl __und_fault
@
@ IRQs off again before pulling preserved data off the stack
@
1: disable_irq_notrace
__und_svc_finish:
disable_irq_notrace
@
@ restore SPSR and restart the instruction
@ -423,25 +443,33 @@ __und_usr:
mov r2, r4
mov r3, r5
@ r2 = regs->ARM_pc, which is either 2 or 4 bytes ahead of the
@ faulting instruction depending on Thumb mode.
@ r3 = regs->ARM_cpsr
@
@ fall through to the emulation code, which returns using r9 if
@ it has emulated the instruction, or the more conventional lr
@ if we are to treat this as a real undefined instruction
@
@ r0 - instruction
@ The emulation code returns using r9 if it has emulated the
@ instruction, or the more conventional lr if we are to treat
@ this as a real undefined instruction
@
adr r9, BSYM(ret_from_exception)
adr lr, BSYM(__und_usr_unknown)
tst r3, #PSR_T_BIT @ Thumb mode?
itet eq @ explicit IT needed for the 1f label
subeq r4, r2, #4 @ ARM instr at LR - 4
subne r4, r2, #2 @ Thumb instr at LR - 2
1: ldreqt r0, [r4]
bne __und_usr_thumb
sub r4, r2, #4 @ ARM instr at LR - 4
1: ldrt r0, [r4]
#ifdef CONFIG_CPU_ENDIAN_BE8
reveq r0, r0 @ little endian instruction
rev r0, r0 @ little endian instruction
#endif
beq call_fpe
@ r0 = 32-bit ARM instruction which caused the exception
@ r2 = PC value for the following instruction (:= regs->ARM_pc)
@ r4 = PC value for the faulting instruction
@ lr = 32-bit undefined instruction function
adr lr, BSYM(__und_usr_fault_32)
b call_fpe
__und_usr_thumb:
@ Thumb instruction
sub r4, r2, #2 @ First half of thumb instr at LR - 2
#if CONFIG_ARM_THUMB && __LINUX_ARM_ARCH__ >= 6 && CONFIG_CPU_V7
/*
* Thumb-2 instruction handling. Note that because pre-v6 and >= v6 platforms
@ -455,7 +483,7 @@ __und_usr:
ldr r5, .LCcpu_architecture
ldr r5, [r5]
cmp r5, #CPU_ARCH_ARMv7
blo __und_usr_unknown
blo __und_usr_fault_16 @ 16bit undefined instruction
/*
* The following code won't get run unless the running CPU really is v7, so
* coding round the lack of ldrht on older arches is pointless. Temporarily
@ -463,15 +491,18 @@ __und_usr:
*/
.arch armv6t2
#endif
2:
ARM( ldrht r5, [r4], #2 )
THUMB( ldrht r5, [r4] )
THUMB( add r4, r4, #2 )
2: ldrht r5, [r4]
cmp r5, #0xe800 @ 32bit instruction if xx != 0
blo __und_usr_unknown
3: ldrht r0, [r4]
blo __und_usr_fault_16 @ 16bit undefined instruction
3: ldrht r0, [r2]
add r2, r2, #2 @ r2 is PC + 2, make it PC + 4
str r2, [sp, #S_PC] @ it's a 2x16bit instr, update
orr r0, r0, r5, lsl #16
adr lr, BSYM(__und_usr_fault_32)
@ r0 = the two 16-bit Thumb instructions which caused the exception
@ r2 = PC value for the following Thumb instruction (:= regs->ARM_pc)
@ r4 = PC value for the first 16-bit Thumb instruction
@ lr = 32bit undefined instruction function
#if __LINUX_ARM_ARCH__ < 7
/* If the target arch was overridden, change it back: */
@ -482,17 +513,13 @@ __und_usr:
#endif
#endif /* __LINUX_ARM_ARCH__ < 7 */
#else /* !(CONFIG_ARM_THUMB && __LINUX_ARM_ARCH__ >= 6 && CONFIG_CPU_V7) */
b __und_usr_unknown
b __und_usr_fault_16
#endif
UNWIND(.fnend )
UNWIND(.fnend)
ENDPROC(__und_usr)
@
@ fallthrough to call_fpe
@
/*
* The out of line fixup for the ldrt above.
* The out of line fixup for the ldrt instructions above.
*/
.pushsection .fixup, "ax"
4: mov pc, r9
@ -523,11 +550,12 @@ ENDPROC(__und_usr)
* NEON handler code.
*
* Emulators may wish to make use of the following registers:
* r0 = instruction opcode.
* r2 = PC+4
* r0 = instruction opcode (32-bit ARM or two 16-bit Thumb)
* r2 = PC value to resume execution after successful emulation
* r9 = normal "successful" return address
* r10 = this threads thread_info structure.
* r10 = this threads thread_info structure
* lr = unrecognised instruction return address
* IRQs disabled, FIQs enabled.
*/
@
@ Fall-through from Thumb-2 __und_usr
@ -662,12 +690,17 @@ ENTRY(no_fp)
mov pc, lr
ENDPROC(no_fp)
__und_usr_unknown:
enable_irq
__und_usr_fault_32:
mov r1, #4
b 1f
__und_usr_fault_16:
mov r1, #2
1: enable_irq
mov r0, sp
adr lr, BSYM(ret_from_exception)
b do_undefinstr
ENDPROC(__und_usr_unknown)
b __und_fault
ENDPROC(__und_usr_fault_32)
ENDPROC(__und_usr_fault_16)
.align 5
__pabt_usr:

View File

@ -254,6 +254,7 @@ __create_page_tables:
/*
* Then map boot params address in r2 or the first 1MB (2MB with LPAE)
* of ram if boot params address is not specified.
* We map 2 sections in case the ATAGs/DTB crosses a section boundary.
*/
mov r0, r2, lsr #SECTION_SHIFT
movs r0, r0, lsl #SECTION_SHIFT
@ -262,6 +263,8 @@ __create_page_tables:
add r3, r3, #PAGE_OFFSET
add r3, r4, r3, lsr #(SECTION_SHIFT - PMD_ORDER)
orr r6, r7, r0
str r6, [r3], #1 << PMD_ORDER
add r6, r6, #1 << SECTION_SHIFT
str r6, [r3]
#ifdef CONFIG_DEBUG_LL

View File

@ -159,6 +159,12 @@ static int debug_arch_supported(void)
arch >= ARM_DEBUG_ARCH_V7_1;
}
/* Can we determine the watchpoint access type from the fsr? */
static int debug_exception_updates_fsr(void)
{
return 0;
}
/* Determine number of WRP registers available. */
static int get_num_wrp_resources(void)
{
@ -631,18 +637,35 @@ int arch_validate_hwbkpt_settings(struct perf_event *bp)
info->address &= ~alignment_mask;
info->ctrl.len <<= offset;
/*
* Currently we rely on an overflow handler to take
* care of single-stepping the breakpoint when it fires.
* In the case of userspace breakpoints on a core with V7 debug,
* we can use the mismatch feature as a poor-man's hardware
* single-step, but this only works for per-task breakpoints.
*/
if (!bp->overflow_handler && (arch_check_bp_in_kernelspace(bp) ||
!core_has_mismatch_brps() || !bp->hw.bp_target)) {
pr_warning("overflow handler required but none found\n");
ret = -EINVAL;
if (!bp->overflow_handler) {
/*
* Mismatch breakpoints are required for single-stepping
* breakpoints.
*/
if (!core_has_mismatch_brps())
return -EINVAL;
/* We don't allow mismatch breakpoints in kernel space. */
if (arch_check_bp_in_kernelspace(bp))
return -EPERM;
/*
* Per-cpu breakpoints are not supported by our stepping
* mechanism.
*/
if (!bp->hw.bp_target)
return -EINVAL;
/*
* We only support specific access types if the fsr
* reports them.
*/
if (!debug_exception_updates_fsr() &&
(info->ctrl.type == ARM_BREAKPOINT_LOAD ||
info->ctrl.type == ARM_BREAKPOINT_STORE))
return -EINVAL;
}
out:
return ret;
}
@ -718,10 +741,12 @@ static void watchpoint_handler(unsigned long addr, unsigned int fsr,
goto unlock;
/* Check that the access type matches. */
access = (fsr & ARM_FSR_ACCESS_MASK) ? HW_BREAKPOINT_W :
HW_BREAKPOINT_R;
if (!(access & hw_breakpoint_type(wp)))
goto unlock;
if (debug_exception_updates_fsr()) {
access = (fsr & ARM_FSR_ACCESS_MASK) ?
HW_BREAKPOINT_W : HW_BREAKPOINT_R;
if (!(access & hw_breakpoint_type(wp)))
goto unlock;
}
/* We have a winner. */
info->trigger = addr;

View File

@ -153,3 +153,10 @@ void machine_kexec(struct kimage *image)
soft_restart(reboot_code_buffer_phys);
}
void arch_crash_save_vmcoreinfo(void)
{
#ifdef CONFIG_ARM_LPAE
VMCOREINFO_CONFIG(ARM_LPAE);
#endif
}

View File

@ -194,6 +194,9 @@ armpmu_event_update(struct perf_event *event,
struct arm_pmu *armpmu = to_arm_pmu(event->pmu);
u64 delta, prev_raw_count, new_raw_count;
if (event->state <= PERF_EVENT_STATE_OFF)
return 0;
again:
prev_raw_count = local64_read(&hwc->prev_count);
new_raw_count = armpmu->read_counter(idx);
@ -349,6 +352,9 @@ validate_event(struct pmu_hw_events *hw_events,
if (event->pmu != leader_pmu || event->state <= PERF_EVENT_STATE_OFF)
return 1;
if (event->state == PERF_EVENT_STATE_OFF && !event->attr.enable_on_exec)
return 1;
return armpmu->get_event_idx(hw_events, &fake_event) >= 0;
}
@ -661,6 +667,7 @@ static void armpmu_init(struct arm_pmu *armpmu)
armpmu->pmu.start = armpmu_start;
armpmu->pmu.stop = armpmu_stop;
armpmu->pmu.read = armpmu_read;
armpmu->pmu.events_across_hotplug = 1;
}
int armpmu_register(struct arm_pmu *armpmu, char *name, int type)
@ -776,62 +783,6 @@ void disable_irq_callback(void *info)
disable_percpu_irq(irq);
}
/*
* PMU hardware loses all context when a CPU goes offline.
* When a CPU is hotplugged back in, since some hardware registers are
* UNKNOWN at reset, the PMU must be explicitly reset to avoid reading
* junk values out of them.
*/
static int __cpuinit pmu_cpu_notify(struct notifier_block *b,
unsigned long action, void *hcpu)
{
int irq;
if (cpu_has_active_perf((int)hcpu)) {
switch ((action & ~CPU_TASKS_FROZEN)) {
case CPU_DOWN_PREPARE:
/*
* If this is on a multicore CPU, we need
* to disarm the PMU IRQ before disappearing.
*/
if (cpu_pmu &&
cpu_pmu->plat_device->dev.platform_data) {
irq = platform_get_irq(cpu_pmu->plat_device, 0);
smp_call_function_single((int)hcpu,
disable_irq_callback, &irq, 1);
}
return NOTIFY_DONE;
case CPU_UP_PREPARE:
/*
* If this is on a multicore CPU, we need
* to arm the PMU IRQ before appearing.
*/
if (cpu_pmu &&
cpu_pmu->plat_device->dev.platform_data) {
irq = platform_get_irq(cpu_pmu->plat_device, 0);
smp_call_function_single((int)hcpu,
enable_irq_callback, &irq, 1);
}
return NOTIFY_DONE;
case CPU_STARTING:
if (cpu_pmu && cpu_pmu->reset) {
cpu_pmu->reset(NULL);
return NOTIFY_OK;
}
default:
return NOTIFY_DONE;
}
}
if ((action & ~CPU_TASKS_FROZEN) != CPU_STARTING)
return NOTIFY_DONE;
return NOTIFY_OK;
}
static void armpmu_update_counters(void)
{
struct pmu_hw_events *hw_events;
@ -852,6 +803,80 @@ static void armpmu_update_counters(void)
}
}
/*
* PMU hardware loses all context when a CPU goes offline.
* When a CPU is hotplugged back in, since some hardware registers are
* UNKNOWN at reset, the PMU must be explicitly reset to avoid reading
* junk values out of them.
*/
static int __cpuinit pmu_cpu_notify(struct notifier_block *b,
unsigned long action, void *hcpu)
{
int irq;
struct pmu *pmu;
int cpu = (int)hcpu;
switch ((action & ~CPU_TASKS_FROZEN)) {
case CPU_DOWN_PREPARE:
if (cpu_pmu && cpu_pmu->save_pm_registers)
smp_call_function_single(cpu,
cpu_pmu->save_pm_registers,
hcpu, 1);
break;
case CPU_STARTING:
if (cpu_pmu && cpu_pmu->reset)
cpu_pmu->reset(NULL);
if (cpu_pmu && cpu_pmu->restore_pm_registers)
smp_call_function_single(cpu,
cpu_pmu->restore_pm_registers,
hcpu, 1);
}
if (cpu_has_active_perf((int)hcpu)) {
switch ((action & ~CPU_TASKS_FROZEN)) {
case CPU_DOWN_PREPARE:
armpmu_update_counters();
/*
* If this is on a multicore CPU, we need
* to disarm the PMU IRQ before disappearing.
*/
if (cpu_pmu &&
cpu_pmu->plat_device->dev.platform_data) {
irq = platform_get_irq(cpu_pmu->plat_device, 0);
smp_call_function_single((int)hcpu,
disable_irq_callback, &irq, 1);
}
return NOTIFY_DONE;
case CPU_STARTING:
/*
* If this is on a multicore CPU, we need
* to arm the PMU IRQ before appearing.
*/
if (cpu_pmu &&
cpu_pmu->plat_device->dev.platform_data) {
irq = platform_get_irq(cpu_pmu->plat_device, 0);
enable_irq_callback(&irq);
}
if (cpu_pmu) {
__get_cpu_var(from_idle) = 1;
pmu = &cpu_pmu->pmu;
pmu->pmu_enable(pmu);
return NOTIFY_OK;
}
default:
return NOTIFY_DONE;
}
}
if ((action & ~CPU_TASKS_FROZEN) != CPU_STARTING)
return NOTIFY_DONE;
return NOTIFY_OK;
}
static struct notifier_block __cpuinitdata pmu_cpu_notifier = {
.notifier_call = pmu_cpu_notify,
};
@ -863,6 +888,8 @@ static int perf_cpu_pm_notifier(struct notifier_block *self, unsigned long cmd,
struct pmu *pmu;
switch (cmd) {
case CPU_PM_ENTER:
if (cpu_pmu && cpu_pmu->save_pm_registers)
cpu_pmu->save_pm_registers((void *)smp_processor_id());
if (cpu_has_active_perf((int)v)) {
armpmu_update_counters();
pmu = &cpu_pmu->pmu;
@ -872,6 +899,9 @@ static int perf_cpu_pm_notifier(struct notifier_block *self, unsigned long cmd,
case CPU_PM_ENTER_FAILED:
case CPU_PM_EXIT:
if (cpu_pmu && cpu_pmu->restore_pm_registers)
cpu_pmu->restore_pm_registers(
(void *)smp_processor_id());
if (cpu_has_active_perf((int)v) && cpu_pmu->reset) {
/*
* Flip this bit so armpmu_enable knows it needs
@ -1027,6 +1057,7 @@ perf_callchain_user(struct perf_callchain_entry *entry, struct pt_regs *regs)
struct frame_tail __user *tail;
perf_callchain_store(entry, regs->ARM_pc);
tail = (struct frame_tail __user *)regs->ARM_fp - 1;
while ((entry->nr < PERF_MAX_STACK_DEPTH) &&

View File

@ -454,37 +454,29 @@ static void krait_pmu_enable_event(struct hw_perf_event *hwc, int idx, int cpu)
/* Disable counter */
armv7_pmnc_disable_counter(idx);
/*
* Set event (if destined for PMNx counters)
* We don't need to set the event if it's a cycle count
*/
if (idx != ARMV7_IDX_CYCLE_COUNTER) {
val = hwc->config_base;
val &= KRAIT_EVENT_MASK;
val = hwc->config_base;
val &= KRAIT_EVENT_MASK;
if (val < 0x40) {
armv7_pmnc_write_evtsel(idx, hwc->config_base);
} else {
event = get_krait_evtinfo(val, &evtinfo);
/* set event for ARM-architected events, and filter for CC */
if ((val < 0x40) || (idx == ARMV7_IDX_CYCLE_COUNTER)) {
armv7_pmnc_write_evtsel(idx, hwc->config_base);
} else {
event = get_krait_evtinfo(val, &evtinfo);
if (event == -EINVAL)
goto krait_out;
if (event == -EINVAL)
goto krait_out;
/* Restore Mode-exclusion bits */
event |= (hwc->config_base & KRAIT_MODE_EXCL_MASK);
/* Restore Mode-exclusion bits */
event |= (hwc->config_base & KRAIT_MODE_EXCL_MASK);
/*
* Set event (if destined for PMNx counters)
* We don't need to set the event if it's a cycle count
*/
armv7_pmnc_write_evtsel(idx, event);
val = 0x0;
asm volatile("mcr p15, 0, %0, c9, c15, 0" : :
"r" (val));
val = evtinfo.group_setval;
gr = evtinfo.groupcode;
krait_evt_setup(gr, val, evtinfo.armv7_evt_type);
}
/* Set event (if destined for PMNx counters) */
armv7_pmnc_write_evtsel(idx, event);
val = 0x0;
asm volatile("mcr p15, 0, %0, c9, c15, 0" : :
"r" (val));
val = evtinfo.group_setval;
gr = evtinfo.groupcode;
krait_evt_setup(gr, val, evtinfo.armv7_evt_type);
}
/* Enable interrupt for this counter */
@ -572,6 +564,33 @@ static int msm_clear_ev_constraint(struct perf_event *event)
return 1;
}
static DEFINE_PER_CPU(u32, krait_pm_pmactlr);
static void krait_save_pm_registers(void *hcpu)
{
u32 val;
u32 cpu = (int)hcpu;
/* Read PMACTLR */
asm volatile("mrc p15, 0, %0, c9, c15, 5" : "=r" (val));
per_cpu(krait_pm_pmactlr, cpu) = val;
armv7pmu_save_pm_registers(hcpu);
}
static void krait_restore_pm_registers(void *hcpu)
{
u32 val;
u32 cpu = (int)hcpu;
val = per_cpu(krait_pm_pmactlr, cpu);
if (val != 0)
/* Restore PMACTLR */
asm volatile("mcr p15, 0, %0, c9, c15, 5" : : "r" (val));
armv7pmu_restore_pm_registers(hcpu);
}
static struct arm_pmu krait_pmu = {
.handle_irq = armv7pmu_handle_irq,
.enable = krait_pmu_enable_event,
@ -585,6 +604,8 @@ static struct arm_pmu krait_pmu = {
.test_set_event_constraints = msm_test_set_ev_constraint,
.clear_event_constraints = msm_clear_ev_constraint,
.max_period = (1LLU << 32) - 1,
.save_pm_registers = krait_save_pm_registers,
.restore_pm_registers = krait_restore_pm_registers,
};
/* NRCCG format for perf RAW codes. */

View File

@ -775,7 +775,7 @@ static unsigned armv7_a7_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
/*
* PMXEVTYPER: Event selection reg
*/
#define ARMV7_EVTYPE_MASK 0xc00000ff /* Mask for writable bits */
#define ARMV7_EVTYPE_MASK 0xc80000ff /* Mask for writable bits */
#define ARMV7_EVTYPE_EVENT 0xff /* Mask for EVENT bits */
/*
@ -1238,6 +1238,29 @@ static int armv7_a7_map_event(struct perf_event *event)
&armv7_a7_perf_cache_map, 0xFF);
}
static DEFINE_PER_CPU(u32, armv7_pm_pmuserenr);
static void armv7pmu_save_pm_registers(void *hcpu)
{
u32 val;
u32 cpu = (int)hcpu;
/* Read PMUSERENR */
asm volatile("mrc p15, 0, %0, c9, c14, 0" : "=r" (val));
per_cpu(armv7_pm_pmuserenr, cpu) = val;
}
static void armv7pmu_restore_pm_registers(void *hcpu)
{
u32 val;
u32 cpu = (int)hcpu;
val = per_cpu(armv7_pm_pmuserenr, cpu);
if (val != 0)
/* Restore PMUSERENR */
asm volatile("mcr p15, 0, %0, c9, c14, 0" : : "r" (val));
}
static struct arm_pmu armv7pmu = {
.handle_irq = armv7pmu_handle_irq,
.enable = armv7pmu_enable_event,
@ -1249,6 +1272,8 @@ static struct arm_pmu armv7pmu = {
.stop = armv7pmu_stop,
.reset = armv7pmu_reset,
.max_period = (1LLU << 32) - 1,
.save_pm_registers = armv7pmu_save_pm_registers,
.restore_pm_registers = armv7pmu_restore_pm_registers,
};
static u32 __init armv7_read_num_pmnc_events(void)

View File

@ -323,6 +323,7 @@ void machine_shutdown(void)
void machine_halt(void)
{
machine_shutdown();
local_irq_disable();
while (1);
}
@ -348,6 +349,7 @@ void machine_restart(char *cmd)
/* Whoops - the platform was unable to reboot. Tell the user! */
printk("Reboot failed -- System halted\n");
local_irq_disable();
while (1);
}
@ -654,6 +656,7 @@ EXPORT_SYMBOL(kernel_thread);
unsigned long get_wchan(struct task_struct *p)
{
struct stackframe frame;
unsigned long stack_page;
int count = 0;
if (!p || p == current || p->state == TASK_RUNNING)
return 0;
@ -662,9 +665,11 @@ unsigned long get_wchan(struct task_struct *p)
frame.sp = thread_saved_sp(p);
frame.lr = 0; /* recovered from the stack */
frame.pc = thread_saved_pc(p);
stack_page = (unsigned long)task_stack_page(p);
do {
int ret = unwind_frame(&frame);
if (ret < 0)
if (frame.sp < stack_page ||
frame.sp >= stack_page + THREAD_SIZE ||
unwind_frame(&frame) < 0)
return 0;
if (!in_sched_functions(frame.pc))
return frame.pc;

View File

@ -316,18 +316,24 @@ static void __cpuinit smp_store_cpu_info(unsigned int cpuid)
asmlinkage void __cpuinit secondary_start_kernel(void)
{
struct mm_struct *mm = &init_mm;
unsigned int cpu = smp_processor_id();
unsigned int cpu;
/*
* The identity mapping is uncached (strongly ordered), so
* switch away from it before attempting any exclusive accesses.
*/
cpu_switch_mm(mm->pgd, mm);
enter_lazy_tlb(mm, current);
local_flush_tlb_all();
/*
* All kernel threads share the same mm context; grab a
* reference and switch to it.
*/
cpu = smp_processor_id();
atomic_inc(&mm->mm_count);
current->active_mm = mm;
cpumask_set_cpu(cpu, mm_cpumask(mm));
cpu_switch_mm(mm->pgd, mm);
enter_lazy_tlb(mm, current);
local_flush_tlb_all();
pr_debug("CPU%u: Booted secondary processor\n", cpu);

View File

@ -31,7 +31,7 @@ int notrace unwind_frame(struct stackframe *frame)
high = ALIGN(low, THREAD_SIZE);
/* check current frame pointer is within bounds */
if (fp < (low + 12) || fp + 4 >= high)
if (fp < low + 12 || fp > high - 4)
return -EINVAL;
/* restore the registers from the stack frame */
@ -83,13 +83,16 @@ static int save_trace(struct stackframe *frame, void *d)
return trace->nr_entries >= trace->max_entries;
}
void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace)
/* This must be noinline to so that our skip calculation works correctly */
static noinline void __save_stack_trace(struct task_struct *tsk,
struct stack_trace *trace, unsigned int nosched)
{
struct stack_trace_data data;
struct stackframe frame;
data.trace = trace;
data.skip = trace->skip;
data.no_sched_functions = nosched;
if (tsk != current) {
#ifdef CONFIG_SMP
@ -102,7 +105,6 @@ void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace)
trace->entries[trace->nr_entries++] = ULONG_MAX;
return;
#else
data.no_sched_functions = 1;
frame.fp = thread_saved_fp(tsk);
frame.sp = thread_saved_sp(tsk);
frame.lr = 0; /* recovered from the stack */
@ -111,11 +113,12 @@ void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace)
} else {
register unsigned long current_sp asm ("sp");
data.no_sched_functions = 0;
/* We don't want this function nor the caller */
data.skip += 2;
frame.fp = (unsigned long)__builtin_frame_address(0);
frame.sp = current_sp;
frame.lr = (unsigned long)__builtin_return_address(0);
frame.pc = (unsigned long)save_stack_trace_tsk;
frame.pc = (unsigned long)__save_stack_trace;
}
walk_stackframe(&frame, save_trace, &data);
@ -123,9 +126,14 @@ void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace)
trace->entries[trace->nr_entries++] = ULONG_MAX;
}
void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace)
{
__save_stack_trace(tsk, trace, 1);
}
void save_stack_trace(struct stack_trace *trace)
{
save_stack_trace_tsk(current, trace);
__save_stack_trace(current, trace, 0);
}
EXPORT_SYMBOL_GPL(save_stack_trace);
#endif

View File

@ -109,10 +109,12 @@ static void set_segfault(struct pt_regs *regs, unsigned long addr)
{
siginfo_t info;
down_read(&current->mm->mmap_sem);
if (find_vma(current->mm, addr) == NULL)
info.si_code = SEGV_MAPERR;
else
info.si_code = SEGV_ACCERR;
up_read(&current->mm->mmap_sem);
info.si_signo = SIGSEGV;
info.si_errno = 0;

View File

@ -13,6 +13,7 @@
#include <linux/cpu.h>
#include <linux/cpumask.h>
#include <linux/export.h>
#include <linux/init.h>
#include <linux/percpu.h>
#include <linux/node.h>
@ -42,6 +43,7 @@
#define MPIDR_LEVEL2_SHIFT 16
struct cputopo_arm cpu_topology[NR_CPUS];
EXPORT_SYMBOL_GPL(cpu_topology);
const struct cpumask *cpu_coregroup_mask(int cpu)
{

View File

@ -42,7 +42,13 @@
#include <trace/events/exception.h>
static const char *handler[]= { "prefetch abort", "data abort", "address exception", "interrupt" };
static const char *handler[]= {
"prefetch abort",
"data abort",
"address exception",
"interrupt",
"undefined instruction",
};
#ifdef CONFIG_LGE_CRASH_HANDLER
static int first_call_chain = 0;
@ -408,18 +414,10 @@ static int call_undef_hook(struct pt_regs *regs, unsigned int instr)
asmlinkage void __exception do_undefinstr(struct pt_regs *regs)
{
unsigned int correction = thumb_mode(regs) ? 2 : 4;
unsigned int instr;
siginfo_t info;
void __user *pc;
/*
* According to the ARM ARM, PC is 2 or 4 bytes ahead,
* depending whether we're in Thumb mode or not.
* Correct this offset.
*/
regs->ARM_pc -= correction;
pc = (void __user *)instruction_pointer(regs);
if (processor_mode(regs) == SVC_MODE) {
@ -434,15 +432,17 @@ asmlinkage void __exception do_undefinstr(struct pt_regs *regs)
#endif
instr = *(u32 *) pc;
} else if (thumb_mode(regs)) {
get_user(instr, (u16 __user *)pc);
if (get_user(instr, (u16 __user *)pc))
goto die_sig;
if (is_wide_instruction(instr)) {
unsigned int instr2;
get_user(instr2, (u16 __user *)pc+1);
if (get_user(instr2, (u16 __user *)pc+1))
goto die_sig;
instr <<= 16;
instr |= instr2;
}
} else {
get_user(instr, (u32 __user *)pc);
} else if (get_user(instr, (u32 __user *)pc)) {
goto die_sig;
}
if (call_undef_hook(regs, instr) == 0)
@ -450,6 +450,7 @@ asmlinkage void __exception do_undefinstr(struct pt_regs *regs)
trace_undef_instr(regs, (void *)pc);
die_sig:
#ifdef CONFIG_DEBUG_USER
if (user_debug & UDBG_UNDEFINED) {
printk(KERN_INFO "%s (%d): undefined instruction: pc=%p\n",

View File

@ -463,7 +463,7 @@ static struct i2c_gpio_platform_data pdata = {
static struct platform_device at91rm9200_twi_device = {
.name = "i2c-gpio",
.id = -1,
.id = 0,
.dev.platform_data = &pdata,
};

View File

@ -468,7 +468,7 @@ static struct i2c_gpio_platform_data pdata = {
static struct platform_device at91sam9260_twi_device = {
.name = "i2c-gpio",
.id = -1,
.id = 0,
.dev.platform_data = &pdata,
};

View File

@ -285,7 +285,7 @@ static struct i2c_gpio_platform_data pdata = {
static struct platform_device at91sam9261_twi_device = {
.name = "i2c-gpio",
.id = -1,
.id = 0,
.dev.platform_data = &pdata,
};

View File

@ -542,7 +542,7 @@ static struct i2c_gpio_platform_data pdata = {
static struct platform_device at91sam9263_twi_device = {
.name = "i2c-gpio",
.id = -1,
.id = 0,
.dev.platform_data = &pdata,
};

View File

@ -314,7 +314,7 @@ static struct i2c_gpio_platform_data pdata = {
static struct platform_device at91sam9rl_twi_device = {
.name = "i2c-gpio",
.id = -1,
.id = 0,
.dev.platform_data = &pdata,
};

View File

@ -101,7 +101,7 @@ static void sam9_smc_cs_read(void __iomem *base,
/* Pulse register */
val = __raw_readl(base + AT91_SMC_PULSE);
config->nwe_setup = val & AT91_SMC_NWEPULSE;
config->nwe_pulse = val & AT91_SMC_NWEPULSE;
config->ncs_write_pulse = (val & AT91_SMC_NCS_WRPULSE) >> 8;
config->nrd_pulse = (val & AT91_SMC_NRDPULSE) >> 16;
config->ncs_read_pulse = (val & AT91_SMC_NCS_RDPULSE) >> 24;

View File

@ -104,6 +104,8 @@ static void __init soc_detect(u32 dbgu_base)
switch (socid) {
case ARCH_ID_AT91RM9200:
at91_soc_initdata.type = AT91_SOC_RM9200;
if (at91_soc_initdata.subtype == AT91_SOC_SUBTYPE_NONE)
at91_soc_initdata.subtype = AT91_SOC_RM9200_BGA;
at91_boot_soc = at91rm9200_soc;
break;
@ -146,7 +148,7 @@ static void __init soc_detect(u32 dbgu_base)
}
/* at91sam9g10 */
if ((cidr & ~AT91_CIDR_EXT) == ARCH_ID_AT91SAM9G10) {
if ((socid & ~AT91_CIDR_EXT) == ARCH_ID_AT91SAM9G10) {
at91_soc_initdata.type = AT91_SOC_SAM9G10;
at91_boot_soc = at91sam9261_soc;
}
@ -324,7 +326,7 @@ static void at91_dt_rstc(void)
of_id = of_match_node(rstc_ids, np);
if (!of_id)
panic("AT91: rtsc no restart function availlable\n");
panic("AT91: rtsc no restart function available\n");
arm_pm_restart = of_id->data;

View File

@ -22,19 +22,9 @@
static struct map_desc cns3xxx_io_desc[] __initdata = {
{
.virtual = CNS3XXX_TC11MP_TWD_BASE_VIRT,
.pfn = __phys_to_pfn(CNS3XXX_TC11MP_TWD_BASE),
.length = SZ_4K,
.type = MT_DEVICE,
}, {
.virtual = CNS3XXX_TC11MP_GIC_CPU_BASE_VIRT,
.pfn = __phys_to_pfn(CNS3XXX_TC11MP_GIC_CPU_BASE),
.length = SZ_4K,
.type = MT_DEVICE,
}, {
.virtual = CNS3XXX_TC11MP_GIC_DIST_BASE_VIRT,
.pfn = __phys_to_pfn(CNS3XXX_TC11MP_GIC_DIST_BASE),
.length = SZ_4K,
.virtual = CNS3XXX_TC11MP_SCU_BASE_VIRT,
.pfn = __phys_to_pfn(CNS3XXX_TC11MP_SCU_BASE),
.length = SZ_8K,
.type = MT_DEVICE,
}, {
.virtual = CNS3XXX_TIMER1_2_3_BASE_VIRT,

View File

@ -94,10 +94,10 @@
#define RTC_INTR_STS_OFFSET 0x34
#define CNS3XXX_MISC_BASE 0x76000000 /* Misc Control */
#define CNS3XXX_MISC_BASE_VIRT 0xFFF07000 /* Misc Control */
#define CNS3XXX_MISC_BASE_VIRT 0xFB000000 /* Misc Control */
#define CNS3XXX_PM_BASE 0x77000000 /* Power Management Control */
#define CNS3XXX_PM_BASE_VIRT 0xFFF08000
#define CNS3XXX_PM_BASE_VIRT 0xFB001000
#define PM_CLK_GATE_OFFSET 0x00
#define PM_SOFT_RST_OFFSET 0x04
@ -109,7 +109,7 @@
#define PM_PLL_HM_PD_OFFSET 0x1C
#define CNS3XXX_UART0_BASE 0x78000000 /* UART 0 */
#define CNS3XXX_UART0_BASE_VIRT 0xFFF09000
#define CNS3XXX_UART0_BASE_VIRT 0xFB002000
#define CNS3XXX_UART1_BASE 0x78400000 /* UART 1 */
#define CNS3XXX_UART1_BASE_VIRT 0xFFF0A000
@ -130,7 +130,7 @@
#define CNS3XXX_I2S_BASE_VIRT 0xFFF10000
#define CNS3XXX_TIMER1_2_3_BASE 0x7C800000 /* Timer */
#define CNS3XXX_TIMER1_2_3_BASE_VIRT 0xFFF10800
#define CNS3XXX_TIMER1_2_3_BASE_VIRT 0xFB003000
#define TIMER1_COUNTER_OFFSET 0x00
#define TIMER1_AUTO_RELOAD_OFFSET 0x04
@ -227,16 +227,16 @@
* Testchip peripheral and fpga gic regions
*/
#define CNS3XXX_TC11MP_SCU_BASE 0x90000000 /* IRQ, Test chip */
#define CNS3XXX_TC11MP_SCU_BASE_VIRT 0xFF000000
#define CNS3XXX_TC11MP_SCU_BASE_VIRT 0xFB004000
#define CNS3XXX_TC11MP_GIC_CPU_BASE 0x90000100 /* Test chip interrupt controller CPU interface */
#define CNS3XXX_TC11MP_GIC_CPU_BASE_VIRT 0xFF000100
#define CNS3XXX_TC11MP_GIC_CPU_BASE_VIRT (CNS3XXX_TC11MP_SCU_BASE_VIRT + 0x100)
#define CNS3XXX_TC11MP_TWD_BASE 0x90000600
#define CNS3XXX_TC11MP_TWD_BASE_VIRT 0xFF000600
#define CNS3XXX_TC11MP_TWD_BASE_VIRT (CNS3XXX_TC11MP_SCU_BASE_VIRT + 0x600)
#define CNS3XXX_TC11MP_GIC_DIST_BASE 0x90001000 /* Test chip interrupt controller distributor */
#define CNS3XXX_TC11MP_GIC_DIST_BASE_VIRT 0xFF001000
#define CNS3XXX_TC11MP_GIC_DIST_BASE_VIRT (CNS3XXX_TC11MP_SCU_BASE_VIRT + 0x1000)
#define CNS3XXX_TC11MP_L220_BASE 0x92002000 /* L220 registers */
#define CNS3XXX_TC11MP_L220_BASE_VIRT 0xFF002000

View File

@ -90,7 +90,7 @@ void __init dove_ge00_init(struct mv643xx_eth_platform_data *eth_data)
{
orion_ge00_init(eth_data,
DOVE_GE00_PHYS_BASE, IRQ_DOVE_GE00_SUM,
0, get_tclk());
0, get_tclk(), 1600);
}
/*****************************************************************************

View File

@ -50,5 +50,6 @@
#define POWER_MANAGEMENT (BRIDGE_VIRT_BASE | 0x011c)
#define TIMER_VIRT_BASE (BRIDGE_VIRT_BASE | 0x0300)
#define TIMER_PHYS_BASE (BRIDGE_PHYS_BASE | 0x0300)
#endif

View File

@ -78,6 +78,7 @@
/* North-South Bridge */
#define BRIDGE_VIRT_BASE (DOVE_SB_REGS_VIRT_BASE | 0x20000)
#define BRIDGE_PHYS_BASE (DOVE_SB_REGS_PHYS_BASE | 0x20000)
/* Cryptographic Engine */
#define DOVE_CRYPT_PHYS_BASE (DOVE_SB_REGS_PHYS_BASE | 0x30000)

View File

@ -45,7 +45,7 @@ static inline int pmu_to_irq(int pin)
static inline int irq_to_pmu(int irq)
{
if (IRQ_DOVE_PMU_START < irq && irq < NR_IRQS)
if (IRQ_DOVE_PMU_START <= irq && irq < NR_IRQS)
return irq - IRQ_DOVE_PMU_START;
return -EINVAL;

View File

@ -61,8 +61,20 @@ static void pmu_irq_ack(struct irq_data *d)
int pin = irq_to_pmu(d->irq);
u32 u;
/*
* The PMU mask register is not RW0C: it is RW. This means that
* the bits take whatever value is written to them; if you write
* a '1', you will set the interrupt.
*
* Unfortunately this means there is NO race free way to clear
* these interrupts.
*
* So, let's structure the code so that the window is as small as
* possible.
*/
u = ~(1 << (pin & 31));
writel(u, PMU_INTERRUPT_CAUSE);
u &= readl_relaxed(PMU_INTERRUPT_CAUSE);
writel_relaxed(u, PMU_INTERRUPT_CAUSE);
}
static struct irq_chip pmu_irq_chip = {

View File

@ -15,6 +15,7 @@
#include <linux/init.h>
#include <linux/io.h>
#include <linux/spinlock.h>
#include <video/vga.h>
#include <asm/pgtable.h>
#include <asm/page.h>
@ -198,6 +199,8 @@ void __init footbridge_map_io(void)
*/
if (footbridge_cfn_mode())
iotable_init(ebsa285_host_io_desc, ARRAY_SIZE(ebsa285_host_io_desc));
vga_base = PCIMEM_BASE;
}
void footbridge_restart(char mode, const char *cmd)

View File

@ -18,7 +18,6 @@
#include <linux/irq.h>
#include <linux/io.h>
#include <linux/spinlock.h>
#include <video/vga.h>
#include <asm/irq.h>
#include <asm/mach/pci.h>
@ -298,7 +297,6 @@ void __init dc21285_preinit(void)
int cfn_mode;
pcibios_min_mem = 0x81000000;
vga_base = PCIMEM_BASE;
mem_size = (unsigned int)high_memory - PAGE_OFFSET;
for (mem_mask = 0x00100000; mem_mask < 0x10000000; mem_mask <<= 1)

View File

@ -23,7 +23,7 @@
#define MX53_DPLL1_BASE MX53_IO_ADDRESS(MX53_PLL1_BASE_ADDR)
#define MX53_DPLL2_BASE MX53_IO_ADDRESS(MX53_PLL2_BASE_ADDR)
#define MX53_DPLL3_BASE MX53_IO_ADDRESS(MX53_PLL3_BASE_ADDR)
#define MX53_DPLL4_BASE MX53_IO_ADDRESS(MX53_PLL3_BASE_ADDR)
#define MX53_DPLL4_BASE MX53_IO_ADDRESS(MX53_PLL4_BASE_ADDR)
/* PLL Register Offsets */
#define MXC_PLL_DP_CTL 0x00

View File

@ -12,6 +12,7 @@
#include <linux/errno.h>
#include <asm/cacheflush.h>
#include <asm/cp15.h>
#include <mach/common.h>
int platform_cpu_kill(unsigned int cpu)
@ -19,6 +20,28 @@ int platform_cpu_kill(unsigned int cpu)
return 1;
}
static inline void cpu_enter_lowpower(void)
{
unsigned int v;
flush_cache_all();
asm volatile(
"mcr p15, 0, %1, c7, c5, 0\n"
" mcr p15, 0, %1, c7, c10, 4\n"
/*
* Turn off coherency
*/
" mrc p15, 0, %0, c1, c0, 1\n"
" bic %0, %0, %3\n"
" mcr p15, 0, %0, c1, c0, 1\n"
" mrc p15, 0, %0, c1, c0, 0\n"
" bic %0, %0, %2\n"
" mcr p15, 0, %0, c1, c0, 0\n"
: "=&r" (v)
: "r" (0), "Ir" (CR_C), "Ir" (0x40)
: "cc");
}
/*
* platform-specific code to shutdown a CPU
*
@ -26,12 +49,12 @@ int platform_cpu_kill(unsigned int cpu)
*/
void platform_cpu_die(unsigned int cpu)
{
flush_cache_all();
cpu_enter_lowpower();
imx_enable_cpu(cpu, false);
cpu_do_idle();
/* We should never return from idle */
panic("cpu %d unexpectedly exit from shutdown\n", cpu);
/* spin here until hardware takes it down */
while (1)
;
}
int platform_cpu_disable(unsigned int cpu)

View File

@ -32,7 +32,7 @@
* Memory-mapped I/O on MX21ADS base board
*/
#define MX21ADS_MMIO_BASE_ADDR 0xf5000000
#define MX21ADS_MMIO_SIZE SZ_16M
#define MX21ADS_MMIO_SIZE 0xc00000
#define MX21ADS_REG_ADDR(offset) (void __force __iomem *) \
(MX21ADS_MMIO_BASE_ADDR + (offset))

View File

@ -366,7 +366,8 @@ static AMBA_APB_DEVICE(aaci, "mb:1d", 0, INTEGRATOR_CP_AACI_BASE,
static void cp_clcd_enable(struct clcd_fb *fb)
{
struct fb_var_screeninfo *var = &fb->fb.var;
u32 val = CM_CTRL_STATIC1 | CM_CTRL_STATIC2;
u32 val = CM_CTRL_STATIC1 | CM_CTRL_STATIC2
| CM_CTRL_LCDEN0 | CM_CTRL_LCDEN1;
if (var->bits_per_pixel <= 8 ||
(var->bits_per_pixel == 16 && var->green.length == 5))

View File

@ -28,6 +28,7 @@
#include <linux/clockchips.h>
#include <linux/io.h>
#include <linux/export.h>
#include <linux/gpio.h>
#include <mach/udc.h>
#include <mach/hardware.h>
@ -107,7 +108,7 @@ static signed char irq2gpio[32] = {
7, 8, 9, 10, 11, 12, -1, -1,
};
int gpio_to_irq(int gpio)
static int ixp4xx_gpio_to_irq(struct gpio_chip *chip, unsigned gpio)
{
int irq;
@ -117,7 +118,6 @@ int gpio_to_irq(int gpio)
}
return -EINVAL;
}
EXPORT_SYMBOL(gpio_to_irq);
int irq_to_gpio(unsigned int irq)
{
@ -383,12 +383,56 @@ static struct platform_device *ixp46x_devices[] __initdata = {
unsigned long ixp4xx_exp_bus_size;
EXPORT_SYMBOL(ixp4xx_exp_bus_size);
static int ixp4xx_gpio_direction_input(struct gpio_chip *chip, unsigned gpio)
{
gpio_line_config(gpio, IXP4XX_GPIO_IN);
return 0;
}
static int ixp4xx_gpio_direction_output(struct gpio_chip *chip, unsigned gpio,
int level)
{
gpio_line_set(gpio, level);
gpio_line_config(gpio, IXP4XX_GPIO_OUT);
return 0;
}
static int ixp4xx_gpio_get_value(struct gpio_chip *chip, unsigned gpio)
{
int value;
gpio_line_get(gpio, &value);
return value;
}
static void ixp4xx_gpio_set_value(struct gpio_chip *chip, unsigned gpio,
int value)
{
gpio_line_set(gpio, value);
}
static struct gpio_chip ixp4xx_gpio_chip = {
.label = "IXP4XX_GPIO_CHIP",
.direction_input = ixp4xx_gpio_direction_input,
.direction_output = ixp4xx_gpio_direction_output,
.get = ixp4xx_gpio_get_value,
.set = ixp4xx_gpio_set_value,
.to_irq = ixp4xx_gpio_to_irq,
.base = 0,
.ngpio = 16,
};
void __init ixp4xx_sys_init(void)
{
ixp4xx_exp_bus_size = SZ_16M;
platform_add_devices(ixp4xx_devices, ARRAY_SIZE(ixp4xx_devices));
gpiochip_add(&ixp4xx_gpio_chip);
if (cpu_is_ixp46x()) {
int region;

View File

@ -1,79 +1,2 @@
/*
* arch/arm/mach-ixp4xx/include/mach/gpio.h
*
* IXP4XX GPIO wrappers for arch-neutral GPIO calls
*
* Written by Milan Svoboda <msvoboda@ra.rockwell.com>
* Based on PXA implementation by Philipp Zabel <philipp.zabel@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#ifndef __ASM_ARCH_IXP4XX_GPIO_H
#define __ASM_ARCH_IXP4XX_GPIO_H
#include <linux/kernel.h>
#include <mach/hardware.h>
#define __ARM_GPIOLIB_COMPLEX
static inline int gpio_request(unsigned gpio, const char *label)
{
return 0;
}
static inline void gpio_free(unsigned gpio)
{
might_sleep();
return;
}
static inline int gpio_direction_input(unsigned gpio)
{
gpio_line_config(gpio, IXP4XX_GPIO_IN);
return 0;
}
static inline int gpio_direction_output(unsigned gpio, int level)
{
gpio_line_set(gpio, level);
gpio_line_config(gpio, IXP4XX_GPIO_OUT);
return 0;
}
static inline int gpio_get_value(unsigned gpio)
{
int value;
gpio_line_get(gpio, &value);
return value;
}
static inline void gpio_set_value(unsigned gpio, int value)
{
gpio_line_set(gpio, value);
}
#include <asm-generic/gpio.h> /* cansleep wrappers */
extern int gpio_to_irq(int gpio);
#define gpio_to_irq gpio_to_irq
extern int irq_to_gpio(unsigned int irq);
#endif
/* empty */

View File

@ -87,7 +87,7 @@ void __init kirkwood_ge00_init(struct mv643xx_eth_platform_data *eth_data)
orion_ge00_init(eth_data,
GE00_PHYS_BASE, IRQ_KIRKWOOD_GE00_SUM,
IRQ_KIRKWOOD_GE00_ERR, kirkwood_tclk);
IRQ_KIRKWOOD_GE00_ERR, kirkwood_tclk, 1600);
}
@ -101,7 +101,7 @@ void __init kirkwood_ge01_init(struct mv643xx_eth_platform_data *eth_data)
orion_ge01_init(eth_data,
GE01_PHYS_BASE, IRQ_KIRKWOOD_GE01_SUM,
IRQ_KIRKWOOD_GE01_ERR, kirkwood_tclk);
IRQ_KIRKWOOD_GE01_ERR, kirkwood_tclk, 1600);
}

View File

@ -38,6 +38,7 @@
#define IRQ_MASK_HIGH_OFF 0x0014
#define TIMER_VIRT_BASE (BRIDGE_VIRT_BASE | 0x0300)
#define TIMER_PHYS_BASE (BRIDGE_PHYS_BASE | 0x0300)
#define L2_CONFIG_REG (BRIDGE_VIRT_BASE | 0x0128)
#define L2_WRITETHROUGH 0x00000010

View File

@ -80,6 +80,7 @@
#define UART1_VIRT_BASE (DEV_BUS_VIRT_BASE | 0x2100)
#define BRIDGE_VIRT_BASE (KIRKWOOD_REGS_VIRT_BASE | 0x20000)
#define BRIDGE_PHYS_BASE (KIRKWOOD_REGS_PHYS_BASE | 0x20000)
#define CRYPTO_PHYS_BASE (KIRKWOOD_REGS_PHYS_BASE | 0x30000)

View File

@ -212,14 +212,19 @@ static int __init kirkwood_pcie_setup(int nr, struct pci_sys_data *sys)
return 1;
}
/*
* The root complex has a hardwired class of PCI_CLASS_MEMORY_OTHER, when it
* is operating as a root complex this needs to be switched to
* PCI_CLASS_BRIDGE_HOST or Linux will errantly try to process the BAR's on
* the device. Decoding setup is handled by the orion code.
*/
static void __devinit rc_pci_fixup(struct pci_dev *dev)
{
/*
* Prevent enumeration of root complex.
*/
if (dev->bus->parent == NULL && dev->devfn == 0) {
int i;
dev->class &= 0xff;
dev->class |= PCI_CLASS_BRIDGE_HOST << 8;
for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
dev->resource[i].start = 0;
dev->resource[i].end = 0;

View File

@ -124,7 +124,7 @@ static void __init qnap_ts219_init(void)
static int __init ts219_pci_init(void)
{
if (machine_is_ts219())
kirkwood_pcie_init(KW_PCIE0);
kirkwood_pcie_init(KW_PCIE1 | KW_PCIE0);
return 0;
}

View File

@ -22,6 +22,7 @@ endif
endif
obj-y += acpuclock.o
obj-$(CONFIG_HW_PERF_EVENTS) += perf_trace_counters.o
obj-$(CONFIG_ARCH_MSM_KRAIT) += acpuclock-krait.o
ifdef CONFIG_ARCH_MSM_KRAIT
obj-$(CONFIG_DEBUG_FS) += acpuclock-krait-debug.o

View File

@ -1,7 +1,7 @@
/* linux/arch/arm/mach-msm/dma.c
*
* Copyright (C) 2007 Google, Inc.
* Copyright (c) 2008-2010, 2012, 2013 The Linux Foundation. All rights reserved.
* Copyright (c) 2008-2010, 2012 The Linux Foundation. All rights reserved.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
@ -31,10 +31,8 @@
enum {
CLK_DIS,
CLK_ENABLING,
CLK_EN,
CLK_TO_BE_DIS,
CLK_DISABLING
CLK_EN
};
struct msm_dmov_ci_conf {
@ -64,8 +62,8 @@ struct msm_dmov_conf {
struct list_head staged_commands[MSM_DMOV_CHANNEL_COUNT];
struct list_head ready_commands[MSM_DMOV_CHANNEL_COUNT];
struct list_head active_commands[MSM_DMOV_CHANNEL_COUNT];
struct mutex clock_lock;
spinlock_t lock;
struct mutex lock;
spinlock_t list_lock;
unsigned int irq;
struct clk *clk;
struct clk *pclk;
@ -167,16 +165,16 @@ static struct msm_dmov_conf dmov_conf[] = {
{
.crci_conf = adm0_crci_conf,
.chan_conf = adm0_chan_conf,
.clock_lock = __MUTEX_INITIALIZER(dmov_conf[0].clock_lock),
.lock = __SPIN_LOCK_UNLOCKED(dmov_lock),
.lock = __MUTEX_INITIALIZER(dmov_conf[0].lock),
.list_lock = __SPIN_LOCK_UNLOCKED(dmov_list_lock),
.clk_ctl = CLK_DIS,
.work = __DELAYED_WORK_INITIALIZER(dmov_conf[0].work,
msm_dmov_clock_work),
}, {
.crci_conf = adm1_crci_conf,
.chan_conf = adm1_chan_conf,
.clock_lock = __MUTEX_INITIALIZER(dmov_conf[1].clock_lock),
.lock = __SPIN_LOCK_UNLOCKED(dmov_lock),
.lock = __MUTEX_INITIALIZER(dmov_conf[1].lock),
.list_lock = __SPIN_LOCK_UNLOCKED(dmov_list_lock),
.clk_ctl = CLK_DIS,
.work = __DELAYED_WORK_INITIALIZER(dmov_conf[1].work,
msm_dmov_clock_work),
@ -187,8 +185,8 @@ static struct msm_dmov_conf dmov_conf[] = {
{
.crci_conf = NULL,
.chan_conf = NULL,
.clock_lock = __MUTEX_INITIALIZER(dmov_conf[0].clock_lock),
.lock = __SPIN_LOCK_UNLOCKED(dmov_lock),
.lock = __MUTEX_INITIALIZER(dmov_conf[0].lock),
.list_lock = __SPIN_LOCK_UNLOCKED(dmov_list_lock),
.clk_ctl = CLK_DIS,
.work = __DELAYED_WORK_INITIALIZER(dmov_conf[0].work,
msm_dmov_clock_work),
@ -272,21 +270,13 @@ static void msm_dmov_clock_work(struct work_struct *work)
struct msm_dmov_conf *conf =
container_of(to_delayed_work(work), struct msm_dmov_conf, work);
int adm = DMOV_IRQ_TO_ADM(conf->irq);
unsigned long irq_flags;
mutex_lock(&conf->clock_lock);
spin_lock_irqsave(&conf->lock, irq_flags);
mutex_lock(&conf->lock);
if (conf->clk_ctl == CLK_TO_BE_DIS) {
BUG_ON(conf->channel_active);
conf->clk_ctl = CLK_DISABLING;
spin_unlock_irqrestore(&conf->lock, irq_flags);
msm_dmov_clk_off(adm);
spin_lock_irqsave(&conf->lock, irq_flags);
if (conf->clk_ctl == CLK_DISABLING)
conf->clk_ctl = CLK_DIS;
conf->clk_ctl = CLK_DIS;
}
spin_unlock_irqrestore(&conf->lock, irq_flags);
mutex_unlock(&conf->clock_lock);
mutex_unlock(&conf->lock);
}
enum {
@ -312,7 +302,7 @@ static struct msm_dmov_cmd *start_ready_cmd(unsigned ch, int adm)
if (!dmov_conf[adm].channel_active)
enable_irq(dmov_conf[adm].irq);
dmov_conf[adm].channel_active |= BIT(ch);
PRINT_IO("start_ready_cmd, %x, ch %d\n", cmd->cmdptr, ch);
PRINT_IO("msm dmov enqueue command, %x, ch %d\n", cmd->cmdptr, ch);
writel_relaxed(cmd->cmdptr, DMOV_REG(DMOV_CMD_PTR(ch), adm));
return cmd;
@ -326,86 +316,37 @@ static void msm_dmov_enqueue_cmd_ext_work(struct work_struct *work)
unsigned status;
unsigned long flags;
int adm = DMOV_ID_TO_ADM(id);
int ch = 0;
mutex_lock(&dmov_conf[adm].clock_lock);
/*No spin_lock is required for the condition check below*/
BUG_ON(dmov_conf[adm].clk_ctl != CLK_ENABLING);
status = msm_dmov_clk_on(adm);
if (status != 0) {
PRINT_ERROR("ADM: Unexpected clock failure at dma.c:%d/%s()!\n",
__LINE__, __func__);
goto error;
}
spin_lock_irqsave(&dmov_conf[adm].lock, flags);
dmov_conf[adm].clk_ctl = CLK_EN;
for (ch = 0; ch < MSM_DMOV_CHANNEL_COUNT; ch++) {
while (!list_empty(&dmov_conf[adm].staged_commands[ch])) {
cmd = list_entry(dmov_conf[adm].staged_commands[ch].
next, typeof(*cmd), list);
list_del(&cmd->list);
list_add_tail(&cmd->list, &dmov_conf[adm].
ready_commands[ch]);
}
if (!list_empty(&dmov_conf[adm].ready_commands[ch])) {
status = readl_relaxed(DMOV_REG(DMOV_STATUS(ch), adm));
if (status & DMOV_STATUS_CMD_PTR_RDY) {
PRINT_IO("msm_dmov_enqueue_cmd(%d),"\
" start command, status %x\n",
id, status);
cmd = start_ready_cmd(ch, adm);
/*
* We added something to the ready list,
* and still hold the list lock.
* Thus, no need to check for cmd == NULL
*/
if (cmd->toflush) {
int flush = (cmd->toflush == GRACEFUL) ?
1 << 31 : 0;
writel_relaxed(flush,
DMOV_REG(DMOV_FLUSH0(ch), adm));
}
} else {
if (list_empty(&dmov_conf[adm].
active_commands[ch]))
PRINT_ERROR("msm_dmov_enqueue_cmd_ext"\
"(%d), stalled, status %x\n",
id, status);
PRINT_IO("msm_dmov_enqueue_cmd(%d),"\
"enqueue command, status "
"%x\n", id, status);
}
}
}
spin_unlock_irqrestore(&dmov_conf[adm].lock, flags);
error:
mutex_unlock(&dmov_conf[adm].clock_lock);
}
void msm_dmov_enqueue_cmd_ext_atomic(unsigned id, struct msm_dmov_cmd *cmd)
{
unsigned int status;
int adm = DMOV_ID_TO_ADM(id);
int ch = DMOV_ID_TO_CHAN(id);
mutex_lock(&dmov_conf[adm].lock);
if (dmov_conf[adm].clk_ctl == CLK_DIS) {
status = msm_dmov_clk_on(adm);
if (status != 0)
goto error;
}
dmov_conf[adm].clk_ctl = CLK_EN;
spin_lock_irqsave(&dmov_conf[adm].list_lock, flags);
cmd = list_entry(dmov_conf[adm].staged_commands[ch].next, typeof(*cmd),
list);
list_del(&cmd->list);
list_add_tail(&cmd->list, &dmov_conf[adm].ready_commands[ch]);
status = readl_relaxed(DMOV_REG(DMOV_STATUS(ch), adm));
if (status & DMOV_STATUS_CMD_PTR_RDY) {
PRINT_IO("msm_dmov_enqueue_cmd(%d), start command, status %x\n",
id, status);
if (cmd->exec_func)
cmd->exec_func(cmd);
list_add_tail(&cmd->list, &dmov_conf[adm].active_commands[ch]);
if (!dmov_conf[adm].channel_active)
enable_irq(dmov_conf[adm].irq);
dmov_conf[adm].channel_active |= BIT(ch);
PRINT_IO("msm dmov enqueue command, %x, ch %d\n", cmd->cmdptr,
ch);
writel_relaxed(cmd->cmdptr, DMOV_REG(DMOV_CMD_PTR(ch), adm));
cmd = start_ready_cmd(ch, adm);
/*
* We added something to the ready list, and still hold the
* list lock. Thus, no need to check for cmd == NULL
*/
if (cmd->toflush) {
int flush = (cmd->toflush == GRACEFUL) ? 1 << 31 : 0;
writel_relaxed(flush, DMOV_REG(DMOV_FLUSH0(ch), adm));
}
} else {
list_add_tail(&cmd->list, &dmov_conf[adm].ready_commands[ch]);
cmd->toflush = 0;
if (list_empty(&dmov_conf[adm].active_commands[ch]) &&
!list_empty(&dmov_conf[adm].ready_commands[ch]))
PRINT_ERROR("msm_dmov_enqueue_cmd_ext(%d), stalled, "
@ -413,58 +354,33 @@ void msm_dmov_enqueue_cmd_ext_atomic(unsigned id, struct msm_dmov_cmd *cmd)
PRINT_IO("msm_dmov_enqueue_cmd(%d), enqueue command, status "
"%x\n", id, status);
}
if (!dmov_conf[adm].channel_active) {
dmov_conf[adm].clk_ctl = CLK_TO_BE_DIS;
schedule_delayed_work(&dmov_conf[adm].work, (HZ/10));
}
spin_unlock_irqrestore(&dmov_conf[adm].list_lock, flags);
error:
mutex_unlock(&dmov_conf[adm].lock);
}
static void __msm_dmov_enqueue_cmd_ext(unsigned id, struct msm_dmov_cmd *cmd,
int onstack)
static void __msm_dmov_enqueue_cmd_ext(unsigned id, struct msm_dmov_cmd *cmd)
{
int adm = DMOV_ID_TO_ADM(id);
int ch = DMOV_ID_TO_CHAN(id);
unsigned long flags;
cmd->id = id;
cmd->toflush = 0;
spin_lock_irqsave(&dmov_conf[adm].lock, flags);
switch (dmov_conf[adm].clk_ctl) {
case CLK_DIS:
case CLK_DISABLING:
if (onstack)
INIT_WORK_ONSTACK(&cmd->work,
msm_dmov_enqueue_cmd_ext_work);
else
INIT_WORK(&cmd->work,
msm_dmov_enqueue_cmd_ext_work);
list_add_tail(&cmd->list, &dmov_conf[adm].staged_commands[ch]);
dmov_conf[adm].clk_ctl = CLK_ENABLING;
queue_work(dmov_conf[adm].cmd_wq, &cmd->work);
break;
case CLK_ENABLING:
list_add_tail(&cmd->list, &dmov_conf[adm].staged_commands[ch]);
break;
case CLK_EN:
msm_dmov_enqueue_cmd_ext_atomic(id, cmd);
break;
case CLK_TO_BE_DIS:
cancel_delayed_work(&dmov_conf[adm].work);
dmov_conf[adm].clk_ctl = CLK_EN;
msm_dmov_enqueue_cmd_ext_atomic(id, cmd);
break;
default:
PRINT_ERROR("ADM%d: Invalid CLK State.\n", adm);
BUG_ON(dmov_conf[adm].clk_ctl);
}
spin_unlock_irqrestore(&dmov_conf[adm].lock, flags);
spin_lock_irqsave(&dmov_conf[adm].list_lock, flags);
list_add_tail(&cmd->list, &dmov_conf[adm].staged_commands[ch]);
queue_work(dmov_conf[adm].cmd_wq, &cmd->work);
spin_unlock_irqrestore(&dmov_conf[adm].list_lock, flags);
}
void msm_dmov_enqueue_cmd_ext(unsigned id, struct msm_dmov_cmd *cmd)
{
__msm_dmov_enqueue_cmd_ext(id, cmd, 0);
INIT_WORK(&cmd->work, msm_dmov_enqueue_cmd_ext_work);
__msm_dmov_enqueue_cmd_ext(id, cmd);
}
EXPORT_SYMBOL(msm_dmov_enqueue_cmd_ext);
@ -472,7 +388,8 @@ void msm_dmov_enqueue_cmd(unsigned id, struct msm_dmov_cmd *cmd)
{
/* Disable callback function (for backwards compatibility) */
cmd->exec_func = NULL;
__msm_dmov_enqueue_cmd_ext(id, cmd, 0);
INIT_WORK(&cmd->work, msm_dmov_enqueue_cmd_ext_work);
__msm_dmov_enqueue_cmd_ext(id, cmd);
}
EXPORT_SYMBOL(msm_dmov_enqueue_cmd);
@ -484,7 +401,7 @@ void msm_dmov_flush(unsigned int id, int graceful)
int flush = graceful ? DMOV_FLUSH_TYPE : 0;
struct msm_dmov_cmd *cmd;
spin_lock_irqsave(&dmov_conf[adm].lock, irq_flags);
spin_lock_irqsave(&dmov_conf[adm].list_lock, irq_flags);
/* XXX not checking if flush cmd sent already */
if (!list_empty(&dmov_conf[adm].active_commands[ch])) {
PRINT_IO("msm_dmov_flush(%d), send flush cmd\n", id);
@ -492,10 +409,8 @@ void msm_dmov_flush(unsigned int id, int graceful)
}
list_for_each_entry(cmd, &dmov_conf[adm].staged_commands[ch], list)
cmd->toflush = graceful ? GRACEFUL : NONGRACEFUL;
list_for_each_entry(cmd, &dmov_conf[adm].ready_commands[ch], list)
cmd->toflush = graceful ? GRACEFUL : NONGRACEFUL;
/* spin_unlock_irqrestore has the necessary barrier */
spin_unlock_irqrestore(&dmov_conf[adm].lock, irq_flags);
spin_unlock_irqrestore(&dmov_conf[adm].list_lock, irq_flags);
}
EXPORT_SYMBOL(msm_dmov_flush);
@ -512,8 +427,7 @@ dmov_exec_cmdptr_complete_func(struct msm_dmov_cmd *_cmd,
unsigned int result,
struct msm_dmov_errdata *err)
{
struct msm_dmov_exec_cmdptr_cmd *cmd =
container_of(_cmd, struct msm_dmov_exec_cmdptr_cmd, dmov_cmd);
struct msm_dmov_exec_cmdptr_cmd *cmd = container_of(_cmd, struct msm_dmov_exec_cmdptr_cmd, dmov_cmd);
cmd->result = result;
if (result != 0x80000002 && err)
memcpy(&cmd->err, err, sizeof(struct msm_dmov_errdata));
@ -532,17 +446,16 @@ int msm_dmov_exec_cmd(unsigned id, unsigned int cmdptr)
cmd.dmov_cmd.exec_func = NULL;
cmd.id = id;
cmd.result = 0;
INIT_WORK_ONSTACK(&cmd.dmov_cmd.work, msm_dmov_enqueue_cmd_ext_work);
init_completion(&cmd.complete);
__msm_dmov_enqueue_cmd_ext(id, &cmd.dmov_cmd, 1);
__msm_dmov_enqueue_cmd_ext(id, &cmd.dmov_cmd);
wait_for_completion_io(&cmd.complete);
if (cmd.result != 0x80000002) {
PRINT_ERROR("dmov_exec_cmdptr(%d): ERROR, result: %x\n",
id, cmd.result);
PRINT_ERROR("dmov_exec_cmdptr(%d): ERROR, result: %x\n", id, cmd.result);
PRINT_ERROR("dmov_exec_cmdptr(%d): flush: %x %x %x %x\n",
id, cmd.err.flush[0], cmd.err.flush[1],
cmd.err.flush[2], cmd.err.flush[3]);
id, cmd.err.flush[0], cmd.err.flush[1], cmd.err.flush[2], cmd.err.flush[3]);
return -EIO;
}
PRINT_FLOW("dmov_exec_cmdptr(%d, %x) done\n", id, cmdptr);
@ -573,17 +486,17 @@ static irqreturn_t msm_dmov_isr(int irq, void *dev_id)
struct msm_dmov_cmd *cmd;
int adm = DMOV_IRQ_TO_ADM(irq);
spin_lock_irqsave(&dmov_conf[adm].lock, irq_flags);
mutex_lock(&dmov_conf[adm].lock);
/* read and clear isr */
int_status = readl_relaxed(DMOV_REG(DMOV_ISR, adm));
PRINT_FLOW("msm_datamover_irq_handler: DMOV_ISR %x\n", int_status);
spin_lock_irqsave(&dmov_conf[adm].list_lock, irq_flags);
while (int_status) {
mask = int_status & -int_status;
ch = fls(mask) - 1;
id = DMOV_CHAN_ADM_TO_ID(ch, adm);
PRINT_FLOW("msm_datamover_irq_handler %08x %08x id %d\n",
int_status, mask, id);
PRINT_FLOW("msm_datamover_irq_handler %08x %08x id %d\n", int_status, mask, id);
int_status &= ~mask;
ch_status = readl_relaxed(DMOV_REG(DMOV_STATUS(ch), adm));
if (!(ch_status & DMOV_STATUS_RSLT_VALID)) {
@ -595,9 +508,8 @@ static irqreturn_t msm_dmov_isr(int irq, void *dev_id)
valid = 1;
ch_result = readl_relaxed(DMOV_REG(DMOV_RSLT(ch), adm));
if (list_empty(&dmov_conf[adm].active_commands[ch])) {
PRINT_ERROR("msm_datamover_irq_handler id %d,"\
" got result with no active command,"
" status %x, result %x\n",
PRINT_ERROR("msm_datamover_irq_handler id %d, got result "
"with no active command, status %x, result %x\n",
id, ch_status, ch_result);
cmd = NULL;
} else {
@ -605,33 +517,26 @@ static irqreturn_t msm_dmov_isr(int irq, void *dev_id)
active_commands[ch].next, typeof(*cmd),
list);
}
PRINT_FLOW("msm_datamover_irq_handler id %d, status"\
" %x, result %x\n", id, ch_status, ch_result);
PRINT_FLOW("msm_datamover_irq_handler id %d, status %x, result %x\n", id, ch_status, ch_result);
if (ch_result & DMOV_RSLT_DONE) {
PRINT_FLOW("msm_datamover_irq_handler id %d,"\
" status %x\n", id, ch_status);
PRINT_IO("msm_datamover_irq_handler id %d,"\
" got result for %p,"
" result %x\n", id, cmd, ch_result);
PRINT_FLOW("msm_datamover_irq_handler id %d, status %x\n",
id, ch_status);
PRINT_IO("msm_datamover_irq_handler id %d, got result "
"for %p, result %x\n", id, cmd, ch_result);
if (cmd) {
list_del(&cmd->list);
cmd->complete_func(cmd, ch_result,
NULL);
cmd->complete_func(cmd, ch_result, NULL);
}
}
if (ch_result & DMOV_RSLT_FLUSH) {
struct msm_dmov_errdata errdata;
fill_errdata(&errdata, ch, adm);
PRINT_FLOW("msm_datamover_irq_handler id %d,"\
" status %x\n", id, ch_status);
PRINT_FLOW("msm_datamover_irq_handler id %d,"\
" flush, result %x,flush0 %x\n", id,
ch_result, errdata.flush[0]);
PRINT_FLOW("msm_datamover_irq_handler id %d, status %x\n", id, ch_status);
PRINT_FLOW("msm_datamover_irq_handler id %d, flush, result %x, flush0 %x\n", id, ch_result, errdata.flush[0]);
if (cmd) {
list_del(&cmd->list);
cmd->complete_func(cmd, ch_result,
&errdata);
cmd->complete_func(cmd, ch_result, &errdata);
}
}
if (ch_result & DMOV_RSLT_ERROR) {
@ -639,47 +544,30 @@ static irqreturn_t msm_dmov_isr(int irq, void *dev_id)
fill_errdata(&errdata, ch, adm);
PRINT_ERROR("msm_datamover_irq_handler id %d,"\
" status %x\n", id, ch_status);
PRINT_ERROR("msm_datamover_irq_handler id %d,"\
" error, result %x, flush0 %x\n",
id, ch_result, errdata.flush[0]);
PRINT_ERROR("msm_datamover_irq_handler id %d, status %x\n", id, ch_status);
PRINT_ERROR("msm_datamover_irq_handler id %d, error, result %x, flush0 %x\n", id, ch_result, errdata.flush[0]);
if (cmd) {
list_del(&cmd->list);
cmd->complete_func(cmd, ch_result,
&errdata);
cmd->complete_func(cmd, ch_result, &errdata);
}
/* this does not seem to work, once we get an
* error. the datamover will no longer accept
* commands
*/
/* this does not seem to work, once we get an error */
/* the datamover will no longer accept commands */
writel_relaxed(0, DMOV_REG(DMOV_FLUSH0(ch),
adm));
}
rmb();
ch_status = readl_relaxed(DMOV_REG(DMOV_STATUS(ch),
adm));
PRINT_FLOW("msm_datamover_irq_handler id %d, status"\
" %x\n", id, ch_status);
if (ch_status & DMOV_STATUS_CMD_PTR_RDY) {
cmd = start_ready_cmd(ch, adm);
if (cmd != NULL) {
if (cmd->toflush) {
int flush = (cmd->toflush ==
GRACEFUL) ? 1 << 31 : 0;
writel_relaxed(flush,
DMOV_REG(DMOV_FLUSH0(ch), adm));
}
}
}
PRINT_FLOW("msm_datamover_irq_handler id %d, status %x\n", id, ch_status);
if (ch_status & DMOV_STATUS_CMD_PTR_RDY)
start_ready_cmd(ch, adm);
} while (ch_status & DMOV_STATUS_RSLT_VALID);
if (list_empty(&dmov_conf[adm].active_commands[ch]) &&
list_empty(&dmov_conf[adm].ready_commands[ch]))
list_empty(&dmov_conf[adm].ready_commands[ch]))
dmov_conf[adm].channel_active &= ~(1U << ch);
PRINT_FLOW("msm_datamover_irq_handler id %d, status %x\n", id,
ch_status);
PRINT_FLOW("msm_datamover_irq_handler id %d, status %x\n", id, ch_status);
}
spin_unlock_irqrestore(&dmov_conf[adm].list_lock, irq_flags);
if (!dmov_conf[adm].channel_active && valid) {
disable_irq_nosync(dmov_conf[adm].irq);
@ -687,7 +575,7 @@ static irqreturn_t msm_dmov_isr(int irq, void *dev_id)
schedule_delayed_work(&dmov_conf[adm].work, (HZ/10));
}
spin_unlock_irqrestore(&dmov_conf[adm].lock, irq_flags);
mutex_unlock(&dmov_conf[adm].lock);
return valid ? IRQ_HANDLED : IRQ_NONE;
}
@ -695,21 +583,13 @@ static int msm_dmov_suspend_late(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
int adm = (pdev->id >= 0) ? pdev->id : 0;
unsigned long irq_flags;
mutex_lock(&dmov_conf[adm].clock_lock);
spin_lock_irqsave(&dmov_conf[adm].lock, irq_flags);
mutex_lock(&dmov_conf[adm].lock);
if (dmov_conf[adm].clk_ctl == CLK_TO_BE_DIS) {
BUG_ON(dmov_conf[adm].channel_active);
dmov_conf[adm].clk_ctl = CLK_DISABLING;
spin_unlock_irqrestore(&dmov_conf[adm].lock, irq_flags);
msm_dmov_clk_off(adm);
spin_lock_irqsave(&dmov_conf[adm].lock, irq_flags);
if (dmov_conf[adm].clk_ctl == CLK_DISABLING)
dmov_conf[adm].clk_ctl = CLK_DIS;
dmov_conf[adm].clk_ctl = CLK_DIS;
}
spin_unlock_irqrestore(&dmov_conf[adm].lock, irq_flags);
mutex_unlock(&dmov_conf[adm].clock_lock);
mutex_unlock(&dmov_conf[adm].lock);
return 0;
}
@ -731,7 +611,7 @@ static int msm_dmov_runtime_idle(struct device *dev)
return 0;
}
static const struct dev_pm_ops msm_dmov_dev_pm_ops = {
static struct dev_pm_ops msm_dmov_dev_pm_ops = {
.runtime_suspend = msm_dmov_runtime_suspend,
.runtime_resume = msm_dmov_runtime_resume,
.runtime_idle = msm_dmov_runtime_idle,
@ -806,7 +686,6 @@ static int msm_dmov_probe(struct platform_device *pdev)
platform_get_resource(pdev, IORESOURCE_IRQ, 0);
struct resource *mres =
platform_get_resource(pdev, IORESOURCE_MEM, 0);
char wq_name[12];
if (pdata) {
dmov_conf[adm].sd = pdata->sd;
@ -825,16 +704,15 @@ static int msm_dmov_probe(struct platform_device *pdev)
if (!dmov_conf[adm].base)
return -ENOMEM;
snprintf(wq_name, sizeof(wq_name), "dmov%d_wq", adm);
dmov_conf[adm].cmd_wq = alloc_workqueue(wq_name, WQ_CPU_INTENSIVE, 1);
dmov_conf[adm].cmd_wq = alloc_ordered_workqueue("dmov%d_wq", 0, adm);
if (!dmov_conf[adm].cmd_wq) {
PRINT_ERROR("Couldn't allocate ADM%d workqueue.\n", adm);
ret = -ENOMEM;
goto out_map;
}
ret = request_irq(dmov_conf[adm].irq, msm_dmov_isr,
0, "msmdatamover", NULL);
ret = request_threaded_irq(dmov_conf[adm].irq, NULL, msm_dmov_isr,
IRQF_ONESHOT, "msmdatamover", NULL);
if (ret) {
PRINT_ERROR("Requesting ADM%d irq %d failed\n", adm,
dmov_conf[adm].irq);

View File

@ -2,7 +2,7 @@
#define __ASM_ARCH_MSM_MSM_KRAIT_L2_ACCESSORS_H
/*
* Copyright (c) 2011, The Linux Foundation. All rights reserved.
* Copyright (c) 2011-2013 The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@ -13,8 +13,70 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#define MAX_L2_PERIOD ((1ULL << 32) - 1)
#define MAX_KRAIT_L2_CTRS 10
#define PMCR_NUM_EV_SHIFT 11
#define PMCR_NUM_EV_MASK 0x1f
#define L2_EVT_MASK 0xfffff
#define L2_SLAVE_EV_PREFIX 4
#define L2_TRACECTR_PREFIX 5
#define L2PMCCNTR 0x409
#define L2PMCCNTCR 0x408
#define L2PMCCNTSR 0x40A
#define L2CYCLE_CTR_BIT 31
#define L2CYCLE_CTR_RAW_CODE 0xfe
#define L2PMOVSR 0x406
#define L2PMCR 0x400
#define L2PMCR_RESET_ALL 0x6
#define L2PMCR_GLOBAL_ENABLE 0x1
#define L2PMCR_GLOBAL_DISABLE 0x0
#define L2PMCNTENSET 0x403
#define L2PMCNTENCLR 0x402
#define L2PMINTENSET 0x405
#define L2PMINTENCLR 0x404
#define IA_L2PMXEVCNTCR_BASE 0x420
#define IA_L2PMXEVTYPER_BASE 0x424
#define IA_L2PMRESX_BASE 0x410
#define IA_L2PMXEVFILTER_BASE 0x423
#define IA_L2PMXEVCNTR_BASE 0x421
/* event format is -e rsRCCG See get_event_desc() */
#define EVENT_PREFIX_MASK 0xf0000
#define EVENT_REG_MASK 0x0f000
#define EVENT_GROUPSEL_MASK 0x0000f
#define EVENT_GROUPCODE_MASK 0x00ff0
#define EVENT_PREFIX_SHIFT 16
#define EVENT_REG_SHIFT 12
#define EVENT_GROUPCODE_SHIFT 4
#define RESRX_VALUE_EN 0x80000000
#ifdef CONFIG_ARCH_MSM_KRAIT
extern void set_l2_indirect_reg(u32 reg_addr, u32 val);
extern u32 get_l2_indirect_reg(u32 reg_addr);
extern u32 set_get_l2_indirect_reg(u32 reg_addr, u32 val);
#else
static inline void set_l2_indirect_reg(u32 reg_addr, u32 val) {}
static inline u32 get_l2_indirect_reg(u32 reg_addr)
{
return 0;
}
static inline u32 set_get_l2_indirect_reg(u32 reg_addr, u32 val)
{
return 0;
}
#endif
#endif

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2010-2011, The Linux Foundation. All rights reserved.
/* Copyright (c) 2010-2014, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@ -92,7 +92,7 @@ struct apr_hdr {
#define APR_SVC_SRD 0x7
/* APR Port IDs */
#define APR_MAX_PORTS 0x40
#define APR_MAX_PORTS 0x80
#define APR_NAME_MAX 0x40

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
/* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@ -27,12 +27,23 @@ static char *descriptions =
"2 Perf: Toggle PMU IRQ when CPU's are hotplugged\n"
"3 Perf: Correct irq for CPU hotplug detection\n"
"4 Perf: Check perf activity on correct CPU\n"
"5 Perf: Add DT support for L1 and L2 PMU\n"
"6 Perf: Add cortex A5 device tree support\n"
"7 Perf: Add L1 counters to tracepoints\n"
"8 Perf: Add cortex A7 perf support\n"
"9 ARM: dts: msm: add perf-events support for msm8226\n"
"10 Perf: Fix counts across power collapse\n"
"12 Perf: Make per-process counters configurable\n"
"13 msm: perf: Add L2 support for tracecounters\n"
"14 Perf: keep events across hotplug\n"
"15 Perf: bring CPU online if needed when disabling irq\n"
"16 Perf: Support sw events across hotplug\n"
"17 msm: perf: initialise krait perf L2 counter enables\n"
"18 msm: perf: clean up duplicate constraint events\n"
"19 Perf: Make per-process counters cumulative\n"
"20 Perf: Fix PID for tracepoints\n"
"21 Perf: preserve registers across hotplug\n"
"22 msm: perf: fix formatting of trace entry\n"
"23 msm: perf: Fix cpu id logic in tracectr notifier\n"
"24 msm: perf: tracectr: Initialize cnts after hotplug\n"
"25 Perf: Reset pmu after hotplug\n"
"26 msm: perf: set filter bits for cycle counter on krait\n"
;
static ssize_t desc_read(struct file *fp, char __user *buf,

View File

@ -18,54 +18,6 @@
#include <mach/msm-krait-l2-accessors.h>
#define MAX_L2_PERIOD ((1ULL << 32) - 1)
#define MAX_KRAIT_L2_CTRS 10
#define PMCR_NUM_EV_SHIFT 11
#define PMCR_NUM_EV_MASK 0x1f
#define L2_EVT_MASK 0xfffff
#define L2_SLAVE_EV_PREFIX 4
#define L2PMCCNTR 0x409
#define L2PMCCNTCR 0x408
#define L2PMCCNTSR 0x40A
#define L2CYCLE_CTR_BIT 31
#define L2CYCLE_CTR_RAW_CODE 0xfe
#define L2PMOVSR 0x406
#define L2PMCR 0x400
#define L2PMCR_RESET_ALL 0x6
#define L2PMCR_GLOBAL_ENABLE 0x1
#define L2PMCR_GLOBAL_DISABLE 0x0
#define L2PMCNTENSET 0x403
#define L2PMCNTENCLR 0x402
#define L2PMINTENSET 0x405
#define L2PMINTENCLR 0x404
#define IA_L2PMXEVCNTCR_BASE 0x420
#define IA_L2PMXEVTYPER_BASE 0x424
#define IA_L2PMRESX_BASE 0x410
#define IA_L2PMXEVFILTER_BASE 0x423
#define IA_L2PMXEVCNTR_BASE 0x421
/* event format is -e rsRCCG See get_event_desc() */
#define EVENT_PREFIX_MASK 0xf0000
#define EVENT_REG_MASK 0x0f000
#define EVENT_GROUPSEL_MASK 0x0000f
#define EVENT_GROUPCODE_MASK 0x00ff0
#define EVENT_PREFIX_SHIFT 16
#define EVENT_REG_SHIFT 12
#define EVENT_GROUPCODE_SHIFT 4
#define RESRX_VALUE_EN 0x80000000
/*
* The L2 PMU is shared between all CPU's, so protect
* its bitmap access.
@ -197,13 +149,16 @@ static void set_evfilter_task_mode(int ctr, unsigned int is_slv)
set_l2_indirect_reg(filter_reg, filter_val);
}
static void set_evfilter_sys_mode(int ctr, unsigned int is_slv)
static void set_evfilter_sys_mode(int ctr, unsigned int is_slv, int cpu,
unsigned int is_tracectr)
{
u32 filter_reg = (ctr * 16) + IA_L2PMXEVFILTER_BASE;
u32 filter_val = l2_orig_filter_prefix | 0xf;
if (is_slv)
if (is_slv == 1)
filter_val = l2_slv_filter_prefix;
if (is_tracectr == 1)
filter_val = l2_orig_filter_prefix | 1 << cpu;
set_l2_indirect_reg(filter_reg, filter_val);
}
@ -277,6 +232,7 @@ static void krait_l2_enable(struct hw_perf_event *hwc, int idx, int cpu)
struct event_desc evdesc;
unsigned long iflags;
unsigned int is_slv = 0;
unsigned int is_tracectr = 0;
unsigned int evt_prefix;
raw_spin_lock_irqsave(&krait_l2_pmu_hw_events.pmu_lock, iflags);
@ -290,6 +246,8 @@ static void krait_l2_enable(struct hw_perf_event *hwc, int idx, int cpu)
if (evt_prefix == L2_SLAVE_EV_PREFIX)
is_slv = 1;
else if (evt_prefix == L2_TRACECTR_PREFIX)
is_tracectr = 1;
set_evcntcr(idx);
@ -305,7 +263,7 @@ static void krait_l2_enable(struct hw_perf_event *hwc, int idx, int cpu)
if (cpu < 0)
set_evfilter_task_mode(idx, is_slv);
else
set_evfilter_sys_mode(idx, is_slv);
set_evfilter_sys_mode(idx, is_slv, cpu, is_tracectr);
out:
enable_intenset(idx);
@ -456,6 +414,7 @@ krait_l2_pmu_generic_free_irq(int irq)
static int msm_l2_test_set_ev_constraint(struct perf_event *event)
{
u32 evt_type = event->attr.config & L2_EVT_MASK;
u8 evt_prefix = (evt_type & EVENT_PREFIX_MASK) >> EVENT_PREFIX_SHIFT;
u8 reg = (evt_type & 0x0F000) >> 12;
u8 group = evt_type & 0x0000F;
u8 code = (evt_type & 0x00FF0) >> 4;
@ -464,6 +423,8 @@ static int msm_l2_test_set_ev_constraint(struct perf_event *event)
u64 bitmap_t;
u32 shift_idx;
if (evt_prefix == L2_TRACECTR_PREFIX)
return err;
/*
* Cycle counter collision is detected in
* get_event_idx().
@ -496,8 +457,10 @@ static int msm_l2_test_set_ev_constraint(struct perf_event *event)
* This sets the event OFF on all but one
* CPU.
*/
if (!(event->cpu < 0))
if (!(event->cpu < 0)) {
event->state = PERF_EVENT_STATE_OFF;
event->attr.constraint_duplicate = 1;
}
}
out:
raw_spin_unlock_irqrestore(&l2_pmu_constraints.lock, flags);
@ -507,12 +470,15 @@ out:
static int msm_l2_clear_ev_constraint(struct perf_event *event)
{
u32 evt_type = event->attr.config & L2_EVT_MASK;
u8 evt_prefix = (evt_type & EVENT_PREFIX_MASK) >> EVENT_PREFIX_SHIFT;
u8 reg = (evt_type & 0x0F000) >> 12;
u8 group = evt_type & 0x0000F;
unsigned long flags;
u64 bitmap_t;
u32 shift_idx;
if (evt_prefix == L2_TRACECTR_PREFIX)
return 1;
raw_spin_lock_irqsave(&l2_pmu_constraints.lock, flags);
shift_idx = ((reg * 4) + group);
@ -583,6 +549,8 @@ static struct platform_driver krait_l2_pmu_driver = {
static int __init register_krait_l2_pmu_driver(void)
{
int i;
/* Reset all ctrs */
set_l2_indirect_reg(L2PMCR, L2PMCR_RESET_ALL);
@ -604,6 +572,11 @@ static int __init register_krait_l2_pmu_driver(void)
/* Avoid spurious interrupt if any */
get_reset_pmovsr();
/* Clear counter enables */
disable_counter(l2_cycle_ctr_idx);
for (i = 0; i < total_l2_ctrs; i++)
disable_counter(i);
return platform_driver_register(&krait_l2_pmu_driver);
}
device_initcall(register_krait_l2_pmu_driver);

View File

@ -0,0 +1,184 @@
/* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include <asm/thread_notify.h>
#include <linux/uaccess.h>
#include <linux/debugfs.h>
#define CREATE_TRACE_POINTS
#include "perf_trace_counters.h"
static unsigned int tp_pid_state;
DEFINE_PER_CPU(u32, previous_ccnt);
DEFINE_PER_CPU(u32[NUM_L1_CTRS], previous_l1_cnts);
DEFINE_PER_CPU(u32[NUM_L2_PERCPU], previous_l2_cnts);
DEFINE_PER_CPU(u32, old_pid);
DEFINE_PER_CPU(u32, hotplug_flag);
/* Reset per_cpu variables that store counter values uppn CPU hotplug */
static int tracectr_cpu_hotplug_notifier(struct notifier_block *self,
unsigned long action, void *hcpu)
{
int ret = NOTIFY_OK;
int cpu = (int)hcpu;
if ((action & (~CPU_TASKS_FROZEN)) == CPU_STARTING)
per_cpu(hotplug_flag, cpu) = 1;
return ret;
}
static struct notifier_block tracectr_cpu_hotplug_notifier_block = {
.notifier_call = tracectr_cpu_hotplug_notifier,
};
static void setup_prev_cnts(u32 cpu)
{
int i;
u32 cnten_val;
/* Read PMCNTENSET */
asm volatile("mrc p15, 0, %0, c9, c12, 1" : "=r"(cnten_val));
/* Disable all the counters that were enabled */
asm volatile("mcr p15, 0, %0, c9, c12, 2" : : "r"(cnten_val));
if (cnten_val & CC) {
/* Read value */
asm volatile("mrc p15, 0, %0, c9, c13, 0"
: "=r"(per_cpu(previous_ccnt, cpu)));
}
for (i = 0; i < NUM_L1_CTRS; i++) {
if (cnten_val & (1 << i)) {
/* Select */
asm volatile("mcr p15, 0, %0, c9, c12, 5"
: : "r"(i));
/* Read value */
asm volatile("mrc p15, 0, %0, c9, c13, 2"
: "=r"(per_cpu(previous_l1_cnts[i], cpu)));
}
}
/* Enable all the counters that were disabled */
asm volatile("mcr p15, 0, %0, c9, c12, 1" : : "r"(cnten_val));
}
static int tracectr_notifier(struct notifier_block *self, unsigned long cmd,
void *v)
{
struct thread_info *thread = v;
int current_pid;
u32 cpu = thread->cpu;
if (cmd != THREAD_NOTIFY_SWITCH)
return -EFAULT;
current_pid = thread->task->pid;
if (per_cpu(old_pid, cpu) != -1) {
if (per_cpu(hotplug_flag, cpu) == 1) {
per_cpu(hotplug_flag, cpu) = 0;
setup_prev_cnts(cpu);
} else
trace_sched_switch_with_ctrs(per_cpu(old_pid, cpu),
current_pid);
}
per_cpu(old_pid, cpu) = current_pid;
return NOTIFY_OK;
}
static struct notifier_block tracectr_notifier_block = {
.notifier_call = tracectr_notifier,
};
static void enable_tp_pid(void)
{
if (tp_pid_state == 0) {
tp_pid_state = 1;
thread_register_notifier(&tracectr_notifier_block);
}
}
static void disable_tp_pid(void)
{
if (tp_pid_state == 1) {
tp_pid_state = 0;
thread_unregister_notifier(&tracectr_notifier_block);
}
}
static ssize_t read_enabled_perftp_file_bool(struct file *file,
char __user *user_buf, size_t count, loff_t *ppos)
{
char buf[2];
buf[1] = '\n';
if (tp_pid_state == 0)
buf[0] = '0';
else
buf[0] = '1';
return simple_read_from_buffer(user_buf, count, ppos, buf, 2);
}
static ssize_t write_enabled_perftp_file_bool(struct file *file,
const char __user *user_buf, size_t count, loff_t *ppos)
{
char buf[32];
size_t buf_size;
buf_size = min(count, (sizeof(buf)-1));
if (copy_from_user(buf, user_buf, buf_size))
return -EFAULT;
switch (buf[0]) {
case 'y':
case 'Y':
case '1':
enable_tp_pid();
break;
case 'n':
case 'N':
case '0':
disable_tp_pid();
break;
}
return count;
}
static const struct file_operations fops_perftp = {
.read = read_enabled_perftp_file_bool,
.write = write_enabled_perftp_file_bool,
.llseek = default_llseek,
};
int __init init_tracecounters(void)
{
struct dentry *dir;
struct dentry *file;
unsigned int value = 1;
int cpu;
dir = debugfs_create_dir("perf_debug_tp", NULL);
if (!dir)
return -ENOMEM;
file = debugfs_create_file("enabled", 0660, dir,
&value, &fops_perftp);
if (!file) {
debugfs_remove(dir);
return -ENOMEM;
}
register_cpu_notifier(&tracectr_cpu_hotplug_notifier_block);
for_each_possible_cpu(cpu)
per_cpu(old_pid, cpu) = -1;
return 0;
}
int __exit exit_tracecounters(void)
{
unregister_cpu_notifier(&tracectr_cpu_hotplug_notifier_block);
return 0;
}
late_initcall(init_tracecounters);

Some files were not shown because too many files have changed in this diff Show More