Merge remote-tracking branch 'invisiblek/cafkorg' into cm-11.0
This commit is contained in:
commit
ed8fa659c4
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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).
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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週間毎ですが、差し迫っ
|
||||
た問題がなければもう少し長くなることもあります。セキュリティ関連の問題
|
||||
の場合はこれに対してだいたいの場合、すぐにリリースがされます。
|
||||
|
|
|
@ -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 のアドレスに送られる。
|
||||
|
||||
レビューサイクル-
|
||||
|
|
|
@ -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>]]]
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
==========
|
||||
|
|
|
@ -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:
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
||||
==============================================================
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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文件具体描述了可被稳定
|
||||
|
|
|
@ -42,7 +42,7 @@ Documentation/stable_kernel_rules.txt 的中文翻译
|
|||
|
||||
向稳定版代码树提交补丁的过程:
|
||||
|
||||
- 在确认了补丁符合以上的规则后,将补丁发送到stable@kernel.org。
|
||||
- 在确认了补丁符合以上的规则后,将补丁发送到stable@vger.kernel.org。
|
||||
- 如果补丁被接受到队列里,发送者会收到一个ACK回复,如果没有被接受,收
|
||||
到的是NAK回复。回复需要几天的时间,这取决于开发者的时间安排。
|
||||
- 被接受的补丁会被加到稳定版本队列里,等待其他开发者的审查。
|
||||
|
|
|
@ -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>
|
||||
|
|
5
Makefile
5
Makefile
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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.
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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";
|
||||
};
|
||||
|
||||
|
|
|
@ -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 = <®_3p3v>;
|
||||
vddvario-supply = <®_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";
|
||||
|
||||
|
|
|
@ -64,7 +64,7 @@
|
|||
status = "disable";
|
||||
};
|
||||
|
||||
sdhci@78000400 {
|
||||
sdhci@78000600 {
|
||||
support-8bit;
|
||||
};
|
||||
};
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 */
|
|
@ -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__ */
|
|
@ -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)
|
||||
|
|
|
@ -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) \
|
||||
|
|
|
@ -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__)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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); \
|
||||
})
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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))) { \
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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) &&
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -109,10 +109,12 @@ static void set_segfault(struct pt_regs *regs, unsigned long addr)
|
|||
{
|
||||
siginfo_t info;
|
||||
|
||||
down_read(¤t->mm->mmap_sem);
|
||||
if (find_vma(current->mm, addr) == NULL)
|
||||
info.si_code = SEGV_MAPERR;
|
||||
else
|
||||
info.si_code = SEGV_ACCERR;
|
||||
up_read(¤t->mm->mmap_sem);
|
||||
|
||||
info.si_signo = SIGSEGV;
|
||||
info.si_errno = 0;
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 = {
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
Loading…
Reference in New Issue