Linux 3.13-rc4
-----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.15 (GNU/Linux) iQEcBAABAgAGBQJSrhGrAAoJEHm+PkMAQRiGsNoH/jIK3CsQ2lbW7yRLXmfgtbzz i2Kep6D4SDvmaLpLYOVC8xNYTiE8jtTbSXHomwP5wMZ63MQDhBfnEWsEWqeZ9+D9 3Q46p0QWuoBgYu2VGkoxTfygkT6hhSpwWIi3SeImbY4fg57OHiUil/+YGhORM4Qc K4549OCTY3sIrgmWL77gzqjRUo+pQ4C73NKqZ3+5nlOmYBZC1yugk8mFwEpQkwhK 4NRNU760Fo+XIht/bINqRiPMddzC15p0mxvJy3cDW8bZa1tFSS9SB7AQUULBbcHL +2dFlFOEb5SV1sNiNPrJ0W+h2qUh2e7kPB0F8epaBppgbwVdyQoC2u4uuLV2ZN0= =lI2r -----END PGP SIGNATURE----- Merge tag 'v3.13-rc4' into x86/mm Pick up the latest fixes before applying new patches. Signed-off-by: Ingo Molnar <mingo@kernel.org>
This commit is contained in:
commit
3331e924e7
5
CREDITS
5
CREDITS
@ -655,6 +655,11 @@ S: Stanford University
|
|||||||
S: Stanford, California 94305
|
S: Stanford, California 94305
|
||||||
S: USA
|
S: USA
|
||||||
|
|
||||||
|
N: Carlos Chinea
|
||||||
|
E: carlos.chinea@nokia.com
|
||||||
|
E: cch.devel@gmail.com
|
||||||
|
D: Author of HSI Subsystem
|
||||||
|
|
||||||
N: Randolph Chung
|
N: Randolph Chung
|
||||||
E: tausq@debian.org
|
E: tausq@debian.org
|
||||||
D: Linux/PA-RISC hacker
|
D: Linux/PA-RISC hacker
|
||||||
|
@ -196,13 +196,6 @@ chmod 0644 /dev/cpu/microcode
|
|||||||
as root before you can use this. You'll probably also want to
|
as root before you can use this. You'll probably also want to
|
||||||
get the user-space microcode_ctl utility to use with this.
|
get the user-space microcode_ctl utility to use with this.
|
||||||
|
|
||||||
Powertweak
|
|
||||||
----------
|
|
||||||
|
|
||||||
If you are running v0.1.17 or earlier, you should upgrade to
|
|
||||||
version v0.99.0 or higher. Running old versions may cause problems
|
|
||||||
with programs using shared memory.
|
|
||||||
|
|
||||||
udev
|
udev
|
||||||
----
|
----
|
||||||
udev is a userspace application for populating /dev dynamically with
|
udev is a userspace application for populating /dev dynamically with
|
||||||
@ -366,10 +359,6 @@ Intel P6 microcode
|
|||||||
------------------
|
------------------
|
||||||
o <http://www.urbanmyth.org/microcode/>
|
o <http://www.urbanmyth.org/microcode/>
|
||||||
|
|
||||||
Powertweak
|
|
||||||
----------
|
|
||||||
o <http://powertweak.sourceforge.net/>
|
|
||||||
|
|
||||||
udev
|
udev
|
||||||
----
|
----
|
||||||
o <http://www.kernel.org/pub/linux/utils/kernel/hotplug/udev.html>
|
o <http://www.kernel.org/pub/linux/utils/kernel/hotplug/udev.html>
|
||||||
|
@ -58,7 +58,7 @@
|
|||||||
</sect1>
|
</sect1>
|
||||||
<sect1><title>Wait queues and Wake events</title>
|
<sect1><title>Wait queues and Wake events</title>
|
||||||
!Iinclude/linux/wait.h
|
!Iinclude/linux/wait.h
|
||||||
!Ekernel/wait.c
|
!Ekernel/sched/wait.c
|
||||||
</sect1>
|
</sect1>
|
||||||
<sect1><title>High-resolution timers</title>
|
<sect1><title>High-resolution timers</title>
|
||||||
!Iinclude/linux/ktime.h
|
!Iinclude/linux/ktime.h
|
||||||
|
@ -73,7 +73,8 @@ range from zero to the maximal number of valid planes for the currently active
|
|||||||
format. For the single-planar API, applications must set <structfield> plane
|
format. For the single-planar API, applications must set <structfield> plane
|
||||||
</structfield> to zero. Additional flags may be posted in the <structfield>
|
</structfield> to zero. Additional flags may be posted in the <structfield>
|
||||||
flags </structfield> field. Refer to a manual for open() for details.
|
flags </structfield> field. Refer to a manual for open() for details.
|
||||||
Currently only O_CLOEXEC is supported. All other fields must be set to zero.
|
Currently only O_CLOEXEC, O_RDONLY, O_WRONLY, and O_RDWR are supported. All
|
||||||
|
other fields must be set to zero.
|
||||||
In the case of multi-planar API, every plane is exported separately using
|
In the case of multi-planar API, every plane is exported separately using
|
||||||
multiple <constant> VIDIOC_EXPBUF </constant> calls. </para>
|
multiple <constant> VIDIOC_EXPBUF </constant> calls. </para>
|
||||||
|
|
||||||
@ -170,8 +171,9 @@ multi-planar API. Otherwise this value must be set to zero. </entry>
|
|||||||
<entry>__u32</entry>
|
<entry>__u32</entry>
|
||||||
<entry><structfield>flags</structfield></entry>
|
<entry><structfield>flags</structfield></entry>
|
||||||
<entry>Flags for the newly created file, currently only <constant>
|
<entry>Flags for the newly created file, currently only <constant>
|
||||||
O_CLOEXEC </constant> is supported, refer to the manual of open() for more
|
O_CLOEXEC </constant>, <constant>O_RDONLY</constant>, <constant>O_WRONLY
|
||||||
details.</entry>
|
</constant>, and <constant>O_RDWR</constant> are supported, refer to the manual
|
||||||
|
of open() for more details.</entry>
|
||||||
</row>
|
</row>
|
||||||
<row>
|
<row>
|
||||||
<entry>__s32</entry>
|
<entry>__s32</entry>
|
||||||
|
574
Documentation/assoc_array.txt
Normal file
574
Documentation/assoc_array.txt
Normal file
@ -0,0 +1,574 @@
|
|||||||
|
========================================
|
||||||
|
GENERIC ASSOCIATIVE ARRAY IMPLEMENTATION
|
||||||
|
========================================
|
||||||
|
|
||||||
|
Contents:
|
||||||
|
|
||||||
|
- Overview.
|
||||||
|
|
||||||
|
- The public API.
|
||||||
|
- Edit script.
|
||||||
|
- Operations table.
|
||||||
|
- Manipulation functions.
|
||||||
|
- Access functions.
|
||||||
|
- Index key form.
|
||||||
|
|
||||||
|
- Internal workings.
|
||||||
|
- Basic internal tree layout.
|
||||||
|
- Shortcuts.
|
||||||
|
- Splitting and collapsing nodes.
|
||||||
|
- Non-recursive iteration.
|
||||||
|
- Simultaneous alteration and iteration.
|
||||||
|
|
||||||
|
|
||||||
|
========
|
||||||
|
OVERVIEW
|
||||||
|
========
|
||||||
|
|
||||||
|
This associative array implementation is an object container with the following
|
||||||
|
properties:
|
||||||
|
|
||||||
|
(1) Objects are opaque pointers. The implementation does not care where they
|
||||||
|
point (if anywhere) or what they point to (if anything).
|
||||||
|
|
||||||
|
[!] NOTE: Pointers to objects _must_ be zero in the least significant bit.
|
||||||
|
|
||||||
|
(2) Objects do not need to contain linkage blocks for use by the array. This
|
||||||
|
permits an object to be located in multiple arrays simultaneously.
|
||||||
|
Rather, the array is made up of metadata blocks that point to objects.
|
||||||
|
|
||||||
|
(3) Objects require index keys to locate them within the array.
|
||||||
|
|
||||||
|
(4) Index keys must be unique. Inserting an object with the same key as one
|
||||||
|
already in the array will replace the old object.
|
||||||
|
|
||||||
|
(5) Index keys can be of any length and can be of different lengths.
|
||||||
|
|
||||||
|
(6) Index keys should encode the length early on, before any variation due to
|
||||||
|
length is seen.
|
||||||
|
|
||||||
|
(7) Index keys can include a hash to scatter objects throughout the array.
|
||||||
|
|
||||||
|
(8) The array can iterated over. The objects will not necessarily come out in
|
||||||
|
key order.
|
||||||
|
|
||||||
|
(9) The array can be iterated over whilst it is being modified, provided the
|
||||||
|
RCU readlock is being held by the iterator. Note, however, under these
|
||||||
|
circumstances, some objects may be seen more than once. If this is a
|
||||||
|
problem, the iterator should lock against modification. Objects will not
|
||||||
|
be missed, however, unless deleted.
|
||||||
|
|
||||||
|
(10) Objects in the array can be looked up by means of their index key.
|
||||||
|
|
||||||
|
(11) Objects can be looked up whilst the array is being modified, provided the
|
||||||
|
RCU readlock is being held by the thread doing the look up.
|
||||||
|
|
||||||
|
The implementation uses a tree of 16-pointer nodes internally that are indexed
|
||||||
|
on each level by nibbles from the index key in the same manner as in a radix
|
||||||
|
tree. To improve memory efficiency, shortcuts can be emplaced to skip over
|
||||||
|
what would otherwise be a series of single-occupancy nodes. Further, nodes
|
||||||
|
pack leaf object pointers into spare space in the node rather than making an
|
||||||
|
extra branch until as such time an object needs to be added to a full node.
|
||||||
|
|
||||||
|
|
||||||
|
==============
|
||||||
|
THE PUBLIC API
|
||||||
|
==============
|
||||||
|
|
||||||
|
The public API can be found in <linux/assoc_array.h>. The associative array is
|
||||||
|
rooted on the following structure:
|
||||||
|
|
||||||
|
struct assoc_array {
|
||||||
|
...
|
||||||
|
};
|
||||||
|
|
||||||
|
The code is selected by enabling CONFIG_ASSOCIATIVE_ARRAY.
|
||||||
|
|
||||||
|
|
||||||
|
EDIT SCRIPT
|
||||||
|
-----------
|
||||||
|
|
||||||
|
The insertion and deletion functions produce an 'edit script' that can later be
|
||||||
|
applied to effect the changes without risking ENOMEM. This retains the
|
||||||
|
preallocated metadata blocks that will be installed in the internal tree and
|
||||||
|
keeps track of the metadata blocks that will be removed from the tree when the
|
||||||
|
script is applied.
|
||||||
|
|
||||||
|
This is also used to keep track of dead blocks and dead objects after the
|
||||||
|
script has been applied so that they can be freed later. The freeing is done
|
||||||
|
after an RCU grace period has passed - thus allowing access functions to
|
||||||
|
proceed under the RCU read lock.
|
||||||
|
|
||||||
|
The script appears as outside of the API as a pointer of the type:
|
||||||
|
|
||||||
|
struct assoc_array_edit;
|
||||||
|
|
||||||
|
There are two functions for dealing with the script:
|
||||||
|
|
||||||
|
(1) Apply an edit script.
|
||||||
|
|
||||||
|
void assoc_array_apply_edit(struct assoc_array_edit *edit);
|
||||||
|
|
||||||
|
This will perform the edit functions, interpolating various write barriers
|
||||||
|
to permit accesses under the RCU read lock to continue. The edit script
|
||||||
|
will then be passed to call_rcu() to free it and any dead stuff it points
|
||||||
|
to.
|
||||||
|
|
||||||
|
(2) Cancel an edit script.
|
||||||
|
|
||||||
|
void assoc_array_cancel_edit(struct assoc_array_edit *edit);
|
||||||
|
|
||||||
|
This frees the edit script and all preallocated memory immediately. If
|
||||||
|
this was for insertion, the new object is _not_ released by this function,
|
||||||
|
but must rather be released by the caller.
|
||||||
|
|
||||||
|
These functions are guaranteed not to fail.
|
||||||
|
|
||||||
|
|
||||||
|
OPERATIONS TABLE
|
||||||
|
----------------
|
||||||
|
|
||||||
|
Various functions take a table of operations:
|
||||||
|
|
||||||
|
struct assoc_array_ops {
|
||||||
|
...
|
||||||
|
};
|
||||||
|
|
||||||
|
This points to a number of methods, all of which need to be provided:
|
||||||
|
|
||||||
|
(1) Get a chunk of index key from caller data:
|
||||||
|
|
||||||
|
unsigned long (*get_key_chunk)(const void *index_key, int level);
|
||||||
|
|
||||||
|
This should return a chunk of caller-supplied index key starting at the
|
||||||
|
*bit* position given by the level argument. The level argument will be a
|
||||||
|
multiple of ASSOC_ARRAY_KEY_CHUNK_SIZE and the function should return
|
||||||
|
ASSOC_ARRAY_KEY_CHUNK_SIZE bits. No error is possible.
|
||||||
|
|
||||||
|
|
||||||
|
(2) Get a chunk of an object's index key.
|
||||||
|
|
||||||
|
unsigned long (*get_object_key_chunk)(const void *object, int level);
|
||||||
|
|
||||||
|
As the previous function, but gets its data from an object in the array
|
||||||
|
rather than from a caller-supplied index key.
|
||||||
|
|
||||||
|
|
||||||
|
(3) See if this is the object we're looking for.
|
||||||
|
|
||||||
|
bool (*compare_object)(const void *object, const void *index_key);
|
||||||
|
|
||||||
|
Compare the object against an index key and return true if it matches and
|
||||||
|
false if it doesn't.
|
||||||
|
|
||||||
|
|
||||||
|
(4) Diff the index keys of two objects.
|
||||||
|
|
||||||
|
int (*diff_objects)(const void *object, const void *index_key);
|
||||||
|
|
||||||
|
Return the bit position at which the index key of the specified object
|
||||||
|
differs from the given index key or -1 if they are the same.
|
||||||
|
|
||||||
|
|
||||||
|
(5) Free an object.
|
||||||
|
|
||||||
|
void (*free_object)(void *object);
|
||||||
|
|
||||||
|
Free the specified object. Note that this may be called an RCU grace
|
||||||
|
period after assoc_array_apply_edit() was called, so synchronize_rcu() may
|
||||||
|
be necessary on module unloading.
|
||||||
|
|
||||||
|
|
||||||
|
MANIPULATION FUNCTIONS
|
||||||
|
----------------------
|
||||||
|
|
||||||
|
There are a number of functions for manipulating an associative array:
|
||||||
|
|
||||||
|
(1) Initialise an associative array.
|
||||||
|
|
||||||
|
void assoc_array_init(struct assoc_array *array);
|
||||||
|
|
||||||
|
This initialises the base structure for an associative array. It can't
|
||||||
|
fail.
|
||||||
|
|
||||||
|
|
||||||
|
(2) Insert/replace an object in an associative array.
|
||||||
|
|
||||||
|
struct assoc_array_edit *
|
||||||
|
assoc_array_insert(struct assoc_array *array,
|
||||||
|
const struct assoc_array_ops *ops,
|
||||||
|
const void *index_key,
|
||||||
|
void *object);
|
||||||
|
|
||||||
|
This inserts the given object into the array. Note that the least
|
||||||
|
significant bit of the pointer must be zero as it's used to type-mark
|
||||||
|
pointers internally.
|
||||||
|
|
||||||
|
If an object already exists for that key then it will be replaced with the
|
||||||
|
new object and the old one will be freed automatically.
|
||||||
|
|
||||||
|
The index_key argument should hold index key information and is
|
||||||
|
passed to the methods in the ops table when they are called.
|
||||||
|
|
||||||
|
This function makes no alteration to the array itself, but rather returns
|
||||||
|
an edit script that must be applied. -ENOMEM is returned in the case of
|
||||||
|
an out-of-memory error.
|
||||||
|
|
||||||
|
The caller should lock exclusively against other modifiers of the array.
|
||||||
|
|
||||||
|
|
||||||
|
(3) Delete an object from an associative array.
|
||||||
|
|
||||||
|
struct assoc_array_edit *
|
||||||
|
assoc_array_delete(struct assoc_array *array,
|
||||||
|
const struct assoc_array_ops *ops,
|
||||||
|
const void *index_key);
|
||||||
|
|
||||||
|
This deletes an object that matches the specified data from the array.
|
||||||
|
|
||||||
|
The index_key argument should hold index key information and is
|
||||||
|
passed to the methods in the ops table when they are called.
|
||||||
|
|
||||||
|
This function makes no alteration to the array itself, but rather returns
|
||||||
|
an edit script that must be applied. -ENOMEM is returned in the case of
|
||||||
|
an out-of-memory error. NULL will be returned if the specified object is
|
||||||
|
not found within the array.
|
||||||
|
|
||||||
|
The caller should lock exclusively against other modifiers of the array.
|
||||||
|
|
||||||
|
|
||||||
|
(4) Delete all objects from an associative array.
|
||||||
|
|
||||||
|
struct assoc_array_edit *
|
||||||
|
assoc_array_clear(struct assoc_array *array,
|
||||||
|
const struct assoc_array_ops *ops);
|
||||||
|
|
||||||
|
This deletes all the objects from an associative array and leaves it
|
||||||
|
completely empty.
|
||||||
|
|
||||||
|
This function makes no alteration to the array itself, but rather returns
|
||||||
|
an edit script that must be applied. -ENOMEM is returned in the case of
|
||||||
|
an out-of-memory error.
|
||||||
|
|
||||||
|
The caller should lock exclusively against other modifiers of the array.
|
||||||
|
|
||||||
|
|
||||||
|
(5) Destroy an associative array, deleting all objects.
|
||||||
|
|
||||||
|
void assoc_array_destroy(struct assoc_array *array,
|
||||||
|
const struct assoc_array_ops *ops);
|
||||||
|
|
||||||
|
This destroys the contents of the associative array and leaves it
|
||||||
|
completely empty. It is not permitted for another thread to be traversing
|
||||||
|
the array under the RCU read lock at the same time as this function is
|
||||||
|
destroying it as no RCU deferral is performed on memory release -
|
||||||
|
something that would require memory to be allocated.
|
||||||
|
|
||||||
|
The caller should lock exclusively against other modifiers and accessors
|
||||||
|
of the array.
|
||||||
|
|
||||||
|
|
||||||
|
(6) Garbage collect an associative array.
|
||||||
|
|
||||||
|
int assoc_array_gc(struct assoc_array *array,
|
||||||
|
const struct assoc_array_ops *ops,
|
||||||
|
bool (*iterator)(void *object, void *iterator_data),
|
||||||
|
void *iterator_data);
|
||||||
|
|
||||||
|
This iterates over the objects in an associative array and passes each one
|
||||||
|
to iterator(). If iterator() returns true, the object is kept. If it
|
||||||
|
returns false, the object will be freed. If the iterator() function
|
||||||
|
returns true, it must perform any appropriate refcount incrementing on the
|
||||||
|
object before returning.
|
||||||
|
|
||||||
|
The internal tree will be packed down if possible as part of the iteration
|
||||||
|
to reduce the number of nodes in it.
|
||||||
|
|
||||||
|
The iterator_data is passed directly to iterator() and is otherwise
|
||||||
|
ignored by the function.
|
||||||
|
|
||||||
|
The function will return 0 if successful and -ENOMEM if there wasn't
|
||||||
|
enough memory.
|
||||||
|
|
||||||
|
It is possible for other threads to iterate over or search the array under
|
||||||
|
the RCU read lock whilst this function is in progress. The caller should
|
||||||
|
lock exclusively against other modifiers of the array.
|
||||||
|
|
||||||
|
|
||||||
|
ACCESS FUNCTIONS
|
||||||
|
----------------
|
||||||
|
|
||||||
|
There are two functions for accessing an associative array:
|
||||||
|
|
||||||
|
(1) Iterate over all the objects in an associative array.
|
||||||
|
|
||||||
|
int assoc_array_iterate(const struct assoc_array *array,
|
||||||
|
int (*iterator)(const void *object,
|
||||||
|
void *iterator_data),
|
||||||
|
void *iterator_data);
|
||||||
|
|
||||||
|
This passes each object in the array to the iterator callback function.
|
||||||
|
iterator_data is private data for that function.
|
||||||
|
|
||||||
|
This may be used on an array at the same time as the array is being
|
||||||
|
modified, provided the RCU read lock is held. Under such circumstances,
|
||||||
|
it is possible for the iteration function to see some objects twice. If
|
||||||
|
this is a problem, then modification should be locked against. The
|
||||||
|
iteration algorithm should not, however, miss any objects.
|
||||||
|
|
||||||
|
The function will return 0 if no objects were in the array or else it will
|
||||||
|
return the result of the last iterator function called. Iteration stops
|
||||||
|
immediately if any call to the iteration function results in a non-zero
|
||||||
|
return.
|
||||||
|
|
||||||
|
|
||||||
|
(2) Find an object in an associative array.
|
||||||
|
|
||||||
|
void *assoc_array_find(const struct assoc_array *array,
|
||||||
|
const struct assoc_array_ops *ops,
|
||||||
|
const void *index_key);
|
||||||
|
|
||||||
|
This walks through the array's internal tree directly to the object
|
||||||
|
specified by the index key..
|
||||||
|
|
||||||
|
This may be used on an array at the same time as the array is being
|
||||||
|
modified, provided the RCU read lock is held.
|
||||||
|
|
||||||
|
The function will return the object if found (and set *_type to the object
|
||||||
|
type) or will return NULL if the object was not found.
|
||||||
|
|
||||||
|
|
||||||
|
INDEX KEY FORM
|
||||||
|
--------------
|
||||||
|
|
||||||
|
The index key can be of any form, but since the algorithms aren't told how long
|
||||||
|
the key is, it is strongly recommended that the index key includes its length
|
||||||
|
very early on before any variation due to the length would have an effect on
|
||||||
|
comparisons.
|
||||||
|
|
||||||
|
This will cause leaves with different length keys to scatter away from each
|
||||||
|
other - and those with the same length keys to cluster together.
|
||||||
|
|
||||||
|
It is also recommended that the index key begin with a hash of the rest of the
|
||||||
|
key to maximise scattering throughout keyspace.
|
||||||
|
|
||||||
|
The better the scattering, the wider and lower the internal tree will be.
|
||||||
|
|
||||||
|
Poor scattering isn't too much of a problem as there are shortcuts and nodes
|
||||||
|
can contain mixtures of leaves and metadata pointers.
|
||||||
|
|
||||||
|
The index key is read in chunks of machine word. Each chunk is subdivided into
|
||||||
|
one nibble (4 bits) per level, so on a 32-bit CPU this is good for 8 levels and
|
||||||
|
on a 64-bit CPU, 16 levels. Unless the scattering is really poor, it is
|
||||||
|
unlikely that more than one word of any particular index key will have to be
|
||||||
|
used.
|
||||||
|
|
||||||
|
|
||||||
|
=================
|
||||||
|
INTERNAL WORKINGS
|
||||||
|
=================
|
||||||
|
|
||||||
|
The associative array data structure has an internal tree. This tree is
|
||||||
|
constructed of two types of metadata blocks: nodes and shortcuts.
|
||||||
|
|
||||||
|
A node is an array of slots. Each slot can contain one of four things:
|
||||||
|
|
||||||
|
(*) A NULL pointer, indicating that the slot is empty.
|
||||||
|
|
||||||
|
(*) A pointer to an object (a leaf).
|
||||||
|
|
||||||
|
(*) A pointer to a node at the next level.
|
||||||
|
|
||||||
|
(*) A pointer to a shortcut.
|
||||||
|
|
||||||
|
|
||||||
|
BASIC INTERNAL TREE LAYOUT
|
||||||
|
--------------------------
|
||||||
|
|
||||||
|
Ignoring shortcuts for the moment, the nodes form a multilevel tree. The index
|
||||||
|
key space is strictly subdivided by the nodes in the tree and nodes occur on
|
||||||
|
fixed levels. For example:
|
||||||
|
|
||||||
|
Level: 0 1 2 3
|
||||||
|
=============== =============== =============== ===============
|
||||||
|
NODE D
|
||||||
|
NODE B NODE C +------>+---+
|
||||||
|
+------>+---+ +------>+---+ | | 0 |
|
||||||
|
NODE A | | 0 | | | 0 | | +---+
|
||||||
|
+---+ | +---+ | +---+ | : :
|
||||||
|
| 0 | | : : | : : | +---+
|
||||||
|
+---+ | +---+ | +---+ | | f |
|
||||||
|
| 1 |---+ | 3 |---+ | 7 |---+ +---+
|
||||||
|
+---+ +---+ +---+
|
||||||
|
: : : : | 8 |---+
|
||||||
|
+---+ +---+ +---+ | NODE E
|
||||||
|
| e |---+ | f | : : +------>+---+
|
||||||
|
+---+ | +---+ +---+ | 0 |
|
||||||
|
| f | | | f | +---+
|
||||||
|
+---+ | +---+ : :
|
||||||
|
| NODE F +---+
|
||||||
|
+------>+---+ | f |
|
||||||
|
| 0 | NODE G +---+
|
||||||
|
+---+ +------>+---+
|
||||||
|
: : | | 0 |
|
||||||
|
+---+ | +---+
|
||||||
|
| 6 |---+ : :
|
||||||
|
+---+ +---+
|
||||||
|
: : | f |
|
||||||
|
+---+ +---+
|
||||||
|
| f |
|
||||||
|
+---+
|
||||||
|
|
||||||
|
In the above example, there are 7 nodes (A-G), each with 16 slots (0-f).
|
||||||
|
Assuming no other meta data nodes in the tree, the key space is divided thusly:
|
||||||
|
|
||||||
|
KEY PREFIX NODE
|
||||||
|
========== ====
|
||||||
|
137* D
|
||||||
|
138* E
|
||||||
|
13[0-69-f]* C
|
||||||
|
1[0-24-f]* B
|
||||||
|
e6* G
|
||||||
|
e[0-57-f]* F
|
||||||
|
[02-df]* A
|
||||||
|
|
||||||
|
So, for instance, keys with the following example index keys will be found in
|
||||||
|
the appropriate nodes:
|
||||||
|
|
||||||
|
INDEX KEY PREFIX NODE
|
||||||
|
=============== ======= ====
|
||||||
|
13694892892489 13 C
|
||||||
|
13795289025897 137 D
|
||||||
|
13889dde88793 138 E
|
||||||
|
138bbb89003093 138 E
|
||||||
|
1394879524789 12 C
|
||||||
|
1458952489 1 B
|
||||||
|
9431809de993ba - A
|
||||||
|
b4542910809cd - A
|
||||||
|
e5284310def98 e F
|
||||||
|
e68428974237 e6 G
|
||||||
|
e7fffcbd443 e F
|
||||||
|
f3842239082 - A
|
||||||
|
|
||||||
|
To save memory, if a node can hold all the leaves in its portion of keyspace,
|
||||||
|
then the node will have all those leaves in it and will not have any metadata
|
||||||
|
pointers - even if some of those leaves would like to be in the same slot.
|
||||||
|
|
||||||
|
A node can contain a heterogeneous mix of leaves and metadata pointers.
|
||||||
|
Metadata pointers must be in the slots that match their subdivisions of key
|
||||||
|
space. The leaves can be in any slot not occupied by a metadata pointer. It
|
||||||
|
is guaranteed that none of the leaves in a node will match a slot occupied by a
|
||||||
|
metadata pointer. If the metadata pointer is there, any leaf whose key matches
|
||||||
|
the metadata key prefix must be in the subtree that the metadata pointer points
|
||||||
|
to.
|
||||||
|
|
||||||
|
In the above example list of index keys, node A will contain:
|
||||||
|
|
||||||
|
SLOT CONTENT INDEX KEY (PREFIX)
|
||||||
|
==== =============== ==================
|
||||||
|
1 PTR TO NODE B 1*
|
||||||
|
any LEAF 9431809de993ba
|
||||||
|
any LEAF b4542910809cd
|
||||||
|
e PTR TO NODE F e*
|
||||||
|
any LEAF f3842239082
|
||||||
|
|
||||||
|
and node B:
|
||||||
|
|
||||||
|
3 PTR TO NODE C 13*
|
||||||
|
any LEAF 1458952489
|
||||||
|
|
||||||
|
|
||||||
|
SHORTCUTS
|
||||||
|
---------
|
||||||
|
|
||||||
|
Shortcuts are metadata records that jump over a piece of keyspace. A shortcut
|
||||||
|
is a replacement for a series of single-occupancy nodes ascending through the
|
||||||
|
levels. Shortcuts exist to save memory and to speed up traversal.
|
||||||
|
|
||||||
|
It is possible for the root of the tree to be a shortcut - say, for example,
|
||||||
|
the tree contains at least 17 nodes all with key prefix '1111'. The insertion
|
||||||
|
algorithm will insert a shortcut to skip over the '1111' keyspace in a single
|
||||||
|
bound and get to the fourth level where these actually become different.
|
||||||
|
|
||||||
|
|
||||||
|
SPLITTING AND COLLAPSING NODES
|
||||||
|
------------------------------
|
||||||
|
|
||||||
|
Each node has a maximum capacity of 16 leaves and metadata pointers. If the
|
||||||
|
insertion algorithm finds that it is trying to insert a 17th object into a
|
||||||
|
node, that node will be split such that at least two leaves that have a common
|
||||||
|
key segment at that level end up in a separate node rooted on that slot for
|
||||||
|
that common key segment.
|
||||||
|
|
||||||
|
If the leaves in a full node and the leaf that is being inserted are
|
||||||
|
sufficiently similar, then a shortcut will be inserted into the tree.
|
||||||
|
|
||||||
|
When the number of objects in the subtree rooted at a node falls to 16 or
|
||||||
|
fewer, then the subtree will be collapsed down to a single node - and this will
|
||||||
|
ripple towards the root if possible.
|
||||||
|
|
||||||
|
|
||||||
|
NON-RECURSIVE ITERATION
|
||||||
|
-----------------------
|
||||||
|
|
||||||
|
Each node and shortcut contains a back pointer to its parent and the number of
|
||||||
|
slot in that parent that points to it. None-recursive iteration uses these to
|
||||||
|
proceed rootwards through the tree, going to the parent node, slot N + 1 to
|
||||||
|
make sure progress is made without the need for a stack.
|
||||||
|
|
||||||
|
The backpointers, however, make simultaneous alteration and iteration tricky.
|
||||||
|
|
||||||
|
|
||||||
|
SIMULTANEOUS ALTERATION AND ITERATION
|
||||||
|
-------------------------------------
|
||||||
|
|
||||||
|
There are a number of cases to consider:
|
||||||
|
|
||||||
|
(1) Simple insert/replace. This involves simply replacing a NULL or old
|
||||||
|
matching leaf pointer with the pointer to the new leaf after a barrier.
|
||||||
|
The metadata blocks don't change otherwise. An old leaf won't be freed
|
||||||
|
until after the RCU grace period.
|
||||||
|
|
||||||
|
(2) Simple delete. This involves just clearing an old matching leaf. The
|
||||||
|
metadata blocks don't change otherwise. The old leaf won't be freed until
|
||||||
|
after the RCU grace period.
|
||||||
|
|
||||||
|
(3) Insertion replacing part of a subtree that we haven't yet entered. This
|
||||||
|
may involve replacement of part of that subtree - but that won't affect
|
||||||
|
the iteration as we won't have reached the pointer to it yet and the
|
||||||
|
ancestry blocks are not replaced (the layout of those does not change).
|
||||||
|
|
||||||
|
(4) Insertion replacing nodes that we're actively processing. This isn't a
|
||||||
|
problem as we've passed the anchoring pointer and won't switch onto the
|
||||||
|
new layout until we follow the back pointers - at which point we've
|
||||||
|
already examined the leaves in the replaced node (we iterate over all the
|
||||||
|
leaves in a node before following any of its metadata pointers).
|
||||||
|
|
||||||
|
We might, however, re-see some leaves that have been split out into a new
|
||||||
|
branch that's in a slot further along than we were at.
|
||||||
|
|
||||||
|
(5) Insertion replacing nodes that we're processing a dependent branch of.
|
||||||
|
This won't affect us until we follow the back pointers. Similar to (4).
|
||||||
|
|
||||||
|
(6) Deletion collapsing a branch under us. This doesn't affect us because the
|
||||||
|
back pointers will get us back to the parent of the new node before we
|
||||||
|
could see the new node. The entire collapsed subtree is thrown away
|
||||||
|
unchanged - and will still be rooted on the same slot, so we shouldn't
|
||||||
|
process it a second time as we'll go back to slot + 1.
|
||||||
|
|
||||||
|
Note:
|
||||||
|
|
||||||
|
(*) Under some circumstances, we need to simultaneously change the parent
|
||||||
|
pointer and the parent slot pointer on a node (say, for example, we
|
||||||
|
inserted another node before it and moved it up a level). We cannot do
|
||||||
|
this without locking against a read - so we have to replace that node too.
|
||||||
|
|
||||||
|
However, when we're changing a shortcut into a node this isn't a problem
|
||||||
|
as shortcuts only have one slot and so the parent slot number isn't used
|
||||||
|
when traversing backwards over one. This means that it's okay to change
|
||||||
|
the slot number first - provided suitable barriers are used to make sure
|
||||||
|
the parent slot number is read after the back pointer.
|
||||||
|
|
||||||
|
Obsolete blocks and leaves are freed up after an RCU grace period has passed,
|
||||||
|
so as long as anyone doing walking or iteration holds the RCU read lock, the
|
||||||
|
old superstructure should not go away on them.
|
@ -266,10 +266,12 @@ E.g.
|
|||||||
Invalidation is removing an entry from the cache without writing it
|
Invalidation is removing an entry from the cache without writing it
|
||||||
back. Cache blocks can be invalidated via the invalidate_cblocks
|
back. Cache blocks can be invalidated via the invalidate_cblocks
|
||||||
message, which takes an arbitrary number of cblock ranges. Each cblock
|
message, which takes an arbitrary number of cblock ranges. Each cblock
|
||||||
must be expressed as a decimal value, in the future a variant message
|
range's end value is "one past the end", meaning 5-10 expresses a range
|
||||||
that takes cblock ranges expressed in hexidecimal may be needed to
|
of values from 5 to 9. Each cblock must be expressed as a decimal
|
||||||
better support efficient invalidation of larger caches. The cache must
|
value, in the future a variant message that takes cblock ranges
|
||||||
be in passthrough mode when invalidate_cblocks is used.
|
expressed in hexidecimal may be needed to better support efficient
|
||||||
|
invalidation of larger caches. The cache must be in passthrough mode
|
||||||
|
when invalidate_cblocks is used.
|
||||||
|
|
||||||
invalidate_cblocks [<cblock>|<cblock begin>-<cblock end>]*
|
invalidate_cblocks [<cblock>|<cblock begin>-<cblock end>]*
|
||||||
|
|
||||||
|
24
Documentation/devicetree/bindings/arc/pmu.txt
Normal file
24
Documentation/devicetree/bindings/arc/pmu.txt
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
* ARC Performance Monitor Unit
|
||||||
|
|
||||||
|
The ARC 700 can be configured with a pipeline performance monitor for counting
|
||||||
|
CPU and cache events like cache misses and hits.
|
||||||
|
|
||||||
|
Note that:
|
||||||
|
* ARC 700 refers to a family of ARC processor cores;
|
||||||
|
- There is only one type of PMU available for the whole family;
|
||||||
|
- The PMU may support different sets of events; supported events are probed
|
||||||
|
at boot time, as required by the reference manual.
|
||||||
|
|
||||||
|
* The ARC 700 PMU does not support interrupts; although HW events may be
|
||||||
|
counted, the HW events themselves cannot serve as a trigger for a sample.
|
||||||
|
|
||||||
|
Required properties:
|
||||||
|
|
||||||
|
- compatible : should contain
|
||||||
|
"snps,arc700-pmu"
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
pmu {
|
||||||
|
compatible = "snps,arc700-pmu";
|
||||||
|
};
|
@ -7,10 +7,18 @@ The MPU contain CPUs, GIC, L2 cache and a local PRCM.
|
|||||||
Required properties:
|
Required properties:
|
||||||
- compatible : Should be "ti,omap3-mpu" for OMAP3
|
- compatible : Should be "ti,omap3-mpu" for OMAP3
|
||||||
Should be "ti,omap4-mpu" for OMAP4
|
Should be "ti,omap4-mpu" for OMAP4
|
||||||
|
Should be "ti,omap5-mpu" for OMAP5
|
||||||
- ti,hwmods: "mpu"
|
- ti,hwmods: "mpu"
|
||||||
|
|
||||||
Examples:
|
Examples:
|
||||||
|
|
||||||
|
- For an OMAP5 SMP system:
|
||||||
|
|
||||||
|
mpu {
|
||||||
|
compatible = "ti,omap5-mpu";
|
||||||
|
ti,hwmods = "mpu"
|
||||||
|
};
|
||||||
|
|
||||||
- For an OMAP4 SMP system:
|
- For an OMAP4 SMP system:
|
||||||
|
|
||||||
mpu {
|
mpu {
|
||||||
|
@ -7,6 +7,7 @@ representation in the device tree should be done as under:-
|
|||||||
Required properties:
|
Required properties:
|
||||||
|
|
||||||
- compatible : should be one of
|
- compatible : should be one of
|
||||||
|
"arm,armv8-pmuv3"
|
||||||
"arm,cortex-a15-pmu"
|
"arm,cortex-a15-pmu"
|
||||||
"arm,cortex-a9-pmu"
|
"arm,cortex-a9-pmu"
|
||||||
"arm,cortex-a8-pmu"
|
"arm,cortex-a8-pmu"
|
||||||
|
@ -49,7 +49,7 @@ adc@12D10000 {
|
|||||||
/* NTC thermistor is a hwmon device */
|
/* NTC thermistor is a hwmon device */
|
||||||
ncp15wb473@0 {
|
ncp15wb473@0 {
|
||||||
compatible = "ntc,ncp15wb473";
|
compatible = "ntc,ncp15wb473";
|
||||||
pullup-uV = <1800000>;
|
pullup-uv = <1800000>;
|
||||||
pullup-ohm = <47000>;
|
pullup-ohm = <47000>;
|
||||||
pulldown-ohm = <0>;
|
pulldown-ohm = <0>;
|
||||||
io-channels = <&adc 4>;
|
io-channels = <&adc 4>;
|
||||||
|
@ -6,7 +6,7 @@ SoC's in the Exynos4 family.
|
|||||||
|
|
||||||
Required Properties:
|
Required Properties:
|
||||||
|
|
||||||
- comptible: should be one of the following.
|
- compatible: should be one of the following.
|
||||||
- "samsung,exynos4210-clock" - controller compatible with Exynos4210 SoC.
|
- "samsung,exynos4210-clock" - controller compatible with Exynos4210 SoC.
|
||||||
- "samsung,exynos4412-clock" - controller compatible with Exynos4412 SoC.
|
- "samsung,exynos4412-clock" - controller compatible with Exynos4412 SoC.
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@ controllers within the Exynos5250 SoC.
|
|||||||
|
|
||||||
Required Properties:
|
Required Properties:
|
||||||
|
|
||||||
- comptible: should be one of the following.
|
- compatible: should be one of the following.
|
||||||
- "samsung,exynos5250-clock" - controller compatible with Exynos5250 SoC.
|
- "samsung,exynos5250-clock" - controller compatible with Exynos5250 SoC.
|
||||||
|
|
||||||
- reg: physical base address of the controller and length of memory mapped
|
- reg: physical base address of the controller and length of memory mapped
|
||||||
|
@ -5,7 +5,7 @@ controllers within the Exynos5420 SoC.
|
|||||||
|
|
||||||
Required Properties:
|
Required Properties:
|
||||||
|
|
||||||
- comptible: should be one of the following.
|
- compatible: should be one of the following.
|
||||||
- "samsung,exynos5420-clock" - controller compatible with Exynos5420 SoC.
|
- "samsung,exynos5420-clock" - controller compatible with Exynos5420 SoC.
|
||||||
|
|
||||||
- reg: physical base address of the controller and length of memory mapped
|
- reg: physical base address of the controller and length of memory mapped
|
||||||
|
@ -5,7 +5,7 @@ controllers within the Exynos5440 SoC.
|
|||||||
|
|
||||||
Required Properties:
|
Required Properties:
|
||||||
|
|
||||||
- comptible: should be "samsung,exynos5440-clock".
|
- compatible: should be "samsung,exynos5440-clock".
|
||||||
|
|
||||||
- reg: physical base address of the controller and length of memory mapped
|
- reg: physical base address of the controller and length of memory mapped
|
||||||
region.
|
region.
|
||||||
|
@ -28,7 +28,7 @@ The three cells in order are:
|
|||||||
dependent:
|
dependent:
|
||||||
- bit 7-0: peripheral identifier for the hardware handshaking interface. The
|
- bit 7-0: peripheral identifier for the hardware handshaking interface. The
|
||||||
identifier can be different for tx and rx.
|
identifier can be different for tx and rx.
|
||||||
- bit 11-8: FIFO configuration. 0 for half FIFO, 1 for ALAP, 1 for ASAP.
|
- bit 11-8: FIFO configuration. 0 for half FIFO, 1 for ALAP, 2 for ASAP.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
|
@ -5,16 +5,42 @@ This is for the non-QE/CPM/GUTs GPIO controllers as found on
|
|||||||
|
|
||||||
Every GPIO controller node must have #gpio-cells property defined,
|
Every GPIO controller node must have #gpio-cells property defined,
|
||||||
this information will be used to translate gpio-specifiers.
|
this information will be used to translate gpio-specifiers.
|
||||||
|
See bindings/gpio/gpio.txt for details of how to specify GPIO
|
||||||
|
information for devices.
|
||||||
|
|
||||||
|
The GPIO module usually is connected to the SoC's internal interrupt
|
||||||
|
controller, see bindings/interrupt-controller/interrupts.txt (the
|
||||||
|
interrupt client nodes section) for details how to specify this GPIO
|
||||||
|
module's interrupt.
|
||||||
|
|
||||||
|
The GPIO module may serve as another interrupt controller (cascaded to
|
||||||
|
the SoC's internal interrupt controller). See the interrupt controller
|
||||||
|
nodes section in bindings/interrupt-controller/interrupts.txt for
|
||||||
|
details.
|
||||||
|
|
||||||
Required properties:
|
Required properties:
|
||||||
- compatible : "fsl,<CHIP>-gpio" followed by "fsl,mpc8349-gpio" for
|
- compatible: "fsl,<chip>-gpio" followed by "fsl,mpc8349-gpio"
|
||||||
83xx, "fsl,mpc8572-gpio" for 85xx and "fsl,mpc8610-gpio" for 86xx.
|
for 83xx, "fsl,mpc8572-gpio" for 85xx, or
|
||||||
- #gpio-cells : Should be two. The first cell is the pin number and the
|
"fsl,mpc8610-gpio" for 86xx.
|
||||||
second cell is used to specify optional parameters (currently unused).
|
- #gpio-cells: Should be two. The first cell is the pin number
|
||||||
- interrupts : Interrupt mapping for GPIO IRQ.
|
and the second cell is used to specify optional
|
||||||
- interrupt-parent : Phandle for the interrupt controller that
|
parameters (currently unused).
|
||||||
services interrupts for this device.
|
- interrupt-parent: Phandle for the interrupt controller that
|
||||||
- gpio-controller : Marks the port as GPIO controller.
|
services interrupts for this device.
|
||||||
|
- interrupts: Interrupt mapping for GPIO IRQ.
|
||||||
|
- gpio-controller: Marks the port as GPIO controller.
|
||||||
|
|
||||||
|
Optional properties:
|
||||||
|
- interrupt-controller: Empty boolean property which marks the GPIO
|
||||||
|
module as an IRQ controller.
|
||||||
|
- #interrupt-cells: Should be two. Defines the number of integer
|
||||||
|
cells required to specify an interrupt within
|
||||||
|
this interrupt controller. The first cell
|
||||||
|
defines the pin number, the second cell
|
||||||
|
defines additional flags (trigger type,
|
||||||
|
trigger polarity). Note that the available
|
||||||
|
set of trigger conditions supported by the
|
||||||
|
GPIO module depends on the actual SoC.
|
||||||
|
|
||||||
Example of gpio-controller nodes for a MPC8347 SoC:
|
Example of gpio-controller nodes for a MPC8347 SoC:
|
||||||
|
|
||||||
@ -22,39 +48,27 @@ Example of gpio-controller nodes for a MPC8347 SoC:
|
|||||||
#gpio-cells = <2>;
|
#gpio-cells = <2>;
|
||||||
compatible = "fsl,mpc8347-gpio", "fsl,mpc8349-gpio";
|
compatible = "fsl,mpc8347-gpio", "fsl,mpc8349-gpio";
|
||||||
reg = <0xc00 0x100>;
|
reg = <0xc00 0x100>;
|
||||||
interrupts = <74 0x8>;
|
|
||||||
interrupt-parent = <&ipic>;
|
interrupt-parent = <&ipic>;
|
||||||
|
interrupts = <74 0x8>;
|
||||||
gpio-controller;
|
gpio-controller;
|
||||||
|
interrupt-controller;
|
||||||
|
#interrupt-cells = <2>;
|
||||||
};
|
};
|
||||||
|
|
||||||
gpio2: gpio-controller@d00 {
|
gpio2: gpio-controller@d00 {
|
||||||
#gpio-cells = <2>;
|
#gpio-cells = <2>;
|
||||||
compatible = "fsl,mpc8347-gpio", "fsl,mpc8349-gpio";
|
compatible = "fsl,mpc8347-gpio", "fsl,mpc8349-gpio";
|
||||||
reg = <0xd00 0x100>;
|
reg = <0xd00 0x100>;
|
||||||
interrupts = <75 0x8>;
|
|
||||||
interrupt-parent = <&ipic>;
|
interrupt-parent = <&ipic>;
|
||||||
|
interrupts = <75 0x8>;
|
||||||
gpio-controller;
|
gpio-controller;
|
||||||
};
|
};
|
||||||
|
|
||||||
See booting-without-of.txt for details of how to specify GPIO
|
Example of a peripheral using the GPIO module as an IRQ controller:
|
||||||
information for devices.
|
|
||||||
|
|
||||||
To use GPIO pins as interrupt sources for peripherals, specify the
|
|
||||||
GPIO controller as the interrupt parent and define GPIO number +
|
|
||||||
trigger mode using the interrupts property, which is defined like
|
|
||||||
this:
|
|
||||||
|
|
||||||
interrupts = <number trigger>, where:
|
|
||||||
- number: GPIO pin (0..31)
|
|
||||||
- trigger: trigger mode:
|
|
||||||
2 = trigger on falling edge
|
|
||||||
3 = trigger on both edges
|
|
||||||
|
|
||||||
Example of device using this is:
|
|
||||||
|
|
||||||
funkyfpga@0 {
|
funkyfpga@0 {
|
||||||
compatible = "funky-fpga";
|
compatible = "funky-fpga";
|
||||||
...
|
...
|
||||||
interrupts = <4 3>;
|
|
||||||
interrupt-parent = <&gpio1>;
|
interrupt-parent = <&gpio1>;
|
||||||
|
interrupts = <4 3>;
|
||||||
};
|
};
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
I2C for OMAP platforms
|
I2C for OMAP platforms
|
||||||
|
|
||||||
Required properties :
|
Required properties :
|
||||||
- compatible : Must be "ti,omap3-i2c" or "ti,omap4-i2c"
|
- compatible : Must be "ti,omap2420-i2c", "ti,omap2430-i2c", "ti,omap3-i2c"
|
||||||
|
or "ti,omap4-i2c"
|
||||||
- ti,hwmods : Must be "i2c<n>", n being the instance number (1-based)
|
- ti,hwmods : Must be "i2c<n>", n being the instance number (1-based)
|
||||||
- #address-cells = <1>;
|
- #address-cells = <1>;
|
||||||
- #size-cells = <0>;
|
- #size-cells = <0>;
|
||||||
|
@ -15,6 +15,7 @@ adi,adt7461 +/-1C TDM Extended Temp Range I.C
|
|||||||
adt7461 +/-1C TDM Extended Temp Range I.C
|
adt7461 +/-1C TDM Extended Temp Range I.C
|
||||||
at,24c08 i2c serial eeprom (24cxx)
|
at,24c08 i2c serial eeprom (24cxx)
|
||||||
atmel,24c02 i2c serial eeprom (24cxx)
|
atmel,24c02 i2c serial eeprom (24cxx)
|
||||||
|
atmel,at97sc3204t i2c trusted platform module (TPM)
|
||||||
catalyst,24c32 i2c serial eeprom
|
catalyst,24c32 i2c serial eeprom
|
||||||
dallas,ds1307 64 x 8, Serial, I2C Real-Time Clock
|
dallas,ds1307 64 x 8, Serial, I2C Real-Time Clock
|
||||||
dallas,ds1338 I2C RTC with 56-Byte NV RAM
|
dallas,ds1338 I2C RTC with 56-Byte NV RAM
|
||||||
@ -35,6 +36,7 @@ fsl,mc13892 MC13892: Power Management Integrated Circuit (PMIC) for i.MX35/51
|
|||||||
fsl,mma8450 MMA8450Q: Xtrinsic Low-power, 3-axis Xtrinsic Accelerometer
|
fsl,mma8450 MMA8450Q: Xtrinsic Low-power, 3-axis Xtrinsic Accelerometer
|
||||||
fsl,mpr121 MPR121: Proximity Capacitive Touch Sensor Controller
|
fsl,mpr121 MPR121: Proximity Capacitive Touch Sensor Controller
|
||||||
fsl,sgtl5000 SGTL5000: Ultra Low-Power Audio Codec
|
fsl,sgtl5000 SGTL5000: Ultra Low-Power Audio Codec
|
||||||
|
gmt,g751 G751: Digital Temperature Sensor and Thermal Watchdog with Two-Wire Interface
|
||||||
infineon,slb9635tt Infineon SLB9635 (Soft-) I2C TPM (old protocol, max 100khz)
|
infineon,slb9635tt Infineon SLB9635 (Soft-) I2C TPM (old protocol, max 100khz)
|
||||||
infineon,slb9645tt Infineon SLB9645 I2C TPM (new protocol, max 400khz)
|
infineon,slb9645tt Infineon SLB9645 I2C TPM (new protocol, max 400khz)
|
||||||
maxim,ds1050 5 Bit Programmable, Pulse-Width Modulator
|
maxim,ds1050 5 Bit Programmable, Pulse-Width Modulator
|
||||||
@ -44,6 +46,7 @@ mc,rv3029c2 Real Time Clock Module with I2C-Bus
|
|||||||
national,lm75 I2C TEMP SENSOR
|
national,lm75 I2C TEMP SENSOR
|
||||||
national,lm80 Serial Interface ACPI-Compatible Microprocessor System Hardware Monitor
|
national,lm80 Serial Interface ACPI-Compatible Microprocessor System Hardware Monitor
|
||||||
national,lm92 ±0.33°C Accurate, 12-Bit + Sign Temperature Sensor and Thermal Window Comparator with Two-Wire Interface
|
national,lm92 ±0.33°C Accurate, 12-Bit + Sign Temperature Sensor and Thermal Window Comparator with Two-Wire Interface
|
||||||
|
nuvoton,npct501 i2c trusted platform module (TPM)
|
||||||
nxp,pca9556 Octal SMBus and I2C registered interface
|
nxp,pca9556 Octal SMBus and I2C registered interface
|
||||||
nxp,pca9557 8-bit I2C-bus and SMBus I/O port with reset
|
nxp,pca9557 8-bit I2C-bus and SMBus I/O port with reset
|
||||||
nxp,pcf8563 Real-time clock/calendar
|
nxp,pcf8563 Real-time clock/calendar
|
||||||
@ -61,3 +64,4 @@ taos,tsl2550 Ambient Light Sensor with SMBUS/Two Wire Serial Interface
|
|||||||
ti,tsc2003 I2C Touch-Screen Controller
|
ti,tsc2003 I2C Touch-Screen Controller
|
||||||
ti,tmp102 Low Power Digital Temperature Sensor with SMBUS/Two Wire Serial Interface
|
ti,tmp102 Low Power Digital Temperature Sensor with SMBUS/Two Wire Serial Interface
|
||||||
ti,tmp275 Digital Temperature Sensor
|
ti,tmp275 Digital Temperature Sensor
|
||||||
|
winbond,wpct301 i2c trusted platform module (TPM)
|
||||||
|
54
Documentation/devicetree/bindings/mmc/ti-omap.txt
Normal file
54
Documentation/devicetree/bindings/mmc/ti-omap.txt
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
* TI MMC host controller for OMAP1 and 2420
|
||||||
|
|
||||||
|
The MMC Host Controller on TI OMAP1 and 2420 family provides
|
||||||
|
an interface for MMC, SD, and SDIO types of memory cards.
|
||||||
|
|
||||||
|
This file documents differences between the core properties described
|
||||||
|
by mmc.txt and the properties used by the omap mmc driver.
|
||||||
|
|
||||||
|
Note that this driver will not work with omap2430 or later omaps,
|
||||||
|
please see the omap hsmmc driver for the current omaps.
|
||||||
|
|
||||||
|
Required properties:
|
||||||
|
- compatible: Must be "ti,omap2420-mmc", for OMAP2420 controllers
|
||||||
|
- ti,hwmods: For 2420, must be "msdi<n>", where n is controller
|
||||||
|
instance starting 1
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
|
||||||
|
msdi1: mmc@4809c000 {
|
||||||
|
compatible = "ti,omap2420-mmc";
|
||||||
|
ti,hwmods = "msdi1";
|
||||||
|
reg = <0x4809c000 0x80>;
|
||||||
|
interrupts = <83>;
|
||||||
|
dmas = <&sdma 61 &sdma 62>;
|
||||||
|
dma-names = "tx", "rx";
|
||||||
|
};
|
||||||
|
|
||||||
|
* TI MMC host controller for OMAP1 and 2420
|
||||||
|
|
||||||
|
The MMC Host Controller on TI OMAP1 and 2420 family provides
|
||||||
|
an interface for MMC, SD, and SDIO types of memory cards.
|
||||||
|
|
||||||
|
This file documents differences between the core properties described
|
||||||
|
by mmc.txt and the properties used by the omap mmc driver.
|
||||||
|
|
||||||
|
Note that this driver will not work with omap2430 or later omaps,
|
||||||
|
please see the omap hsmmc driver for the current omaps.
|
||||||
|
|
||||||
|
Required properties:
|
||||||
|
- compatible: Must be "ti,omap2420-mmc", for OMAP2420 controllers
|
||||||
|
- ti,hwmods: For 2420, must be "msdi<n>", where n is controller
|
||||||
|
instance starting 1
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
|
||||||
|
msdi1: mmc@4809c000 {
|
||||||
|
compatible = "ti,omap2420-mmc";
|
||||||
|
ti,hwmods = "msdi1";
|
||||||
|
reg = <0x4809c000 0x80>;
|
||||||
|
interrupts = <83>;
|
||||||
|
dmas = <&sdma 61 &sdma 62>;
|
||||||
|
dma-names = "tx", "rx";
|
||||||
|
};
|
||||||
|
|
@ -4,7 +4,7 @@ This file provides information, what the device node
|
|||||||
for the davinci_emac interface contains.
|
for the davinci_emac interface contains.
|
||||||
|
|
||||||
Required properties:
|
Required properties:
|
||||||
- compatible: "ti,davinci-dm6467-emac";
|
- compatible: "ti,davinci-dm6467-emac" or "ti,am3517-emac"
|
||||||
- reg: Offset and length of the register set for the device
|
- reg: Offset and length of the register set for the device
|
||||||
- ti,davinci-ctrl-reg-offset: offset to control register
|
- ti,davinci-ctrl-reg-offset: offset to control register
|
||||||
- ti,davinci-ctrl-mod-reg-offset: offset to control module register
|
- ti,davinci-ctrl-mod-reg-offset: offset to control module register
|
||||||
|
@ -15,6 +15,7 @@ Optional properties:
|
|||||||
only if property "phy-reset-gpios" is available. Missing the property
|
only if property "phy-reset-gpios" is available. Missing the property
|
||||||
will have the duration be 1 millisecond. Numbers greater than 1000 are
|
will have the duration be 1 millisecond. Numbers greater than 1000 are
|
||||||
invalid and 1 millisecond will be used instead.
|
invalid and 1 millisecond will be used instead.
|
||||||
|
- phy-supply: regulator that powers the Ethernet PHY.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
@ -25,4 +26,5 @@ ethernet@83fec000 {
|
|||||||
phy-mode = "mii";
|
phy-mode = "mii";
|
||||||
phy-reset-gpios = <&gpio2 14 0>; /* GPIO2_14 */
|
phy-reset-gpios = <&gpio2 14 0>; /* GPIO2_14 */
|
||||||
local-mac-address = [00 04 9F 01 1B B9];
|
local-mac-address = [00 04 9F 01 1B B9];
|
||||||
|
phy-supply = <®_fec_supply>;
|
||||||
};
|
};
|
||||||
|
@ -8,3 +8,7 @@ Required properties:
|
|||||||
Optional properties:
|
Optional properties:
|
||||||
- phy-device : phandle to Ethernet phy
|
- phy-device : phandle to Ethernet phy
|
||||||
- local-mac-address : Ethernet mac address to use
|
- local-mac-address : Ethernet mac address to use
|
||||||
|
- reg-io-width : Mask of sizes (in bytes) of the IO accesses that
|
||||||
|
are supported on the device. Valid value for SMSC LAN91c111 are
|
||||||
|
1, 2 or 4. If it's omitted or invalid, the size would be 2 meaning
|
||||||
|
16-bit access only.
|
||||||
|
@ -1,33 +1,30 @@
|
|||||||
* Freescale 83xx DMA Controller
|
* Freescale DMA Controllers
|
||||||
|
|
||||||
Freescale PowerPC 83xx have on chip general purpose DMA controllers.
|
** Freescale Elo DMA Controller
|
||||||
|
This is a little-endian 4-channel DMA controller, used in Freescale mpc83xx
|
||||||
|
series chips such as mpc8315, mpc8349, mpc8379 etc.
|
||||||
|
|
||||||
Required properties:
|
Required properties:
|
||||||
|
|
||||||
- compatible : compatible list, contains 2 entries, first is
|
- compatible : must include "fsl,elo-dma"
|
||||||
"fsl,CHIP-dma", where CHIP is the processor
|
- reg : DMA General Status Register, i.e. DGSR which contains
|
||||||
(mpc8349, mpc8360, etc.) and the second is
|
status for all the 4 DMA channels
|
||||||
"fsl,elo-dma"
|
- ranges : describes the mapping between the address space of the
|
||||||
- reg : <registers mapping for DMA general status reg>
|
DMA channels and the address space of the DMA controller
|
||||||
- ranges : Should be defined as specified in 1) to describe the
|
|
||||||
DMA controller channels.
|
|
||||||
- cell-index : controller index. 0 for controller @ 0x8100
|
- cell-index : controller index. 0 for controller @ 0x8100
|
||||||
- interrupts : <interrupt mapping for DMA IRQ>
|
- interrupts : interrupt specifier for DMA IRQ
|
||||||
- interrupt-parent : optional, if needed for interrupt mapping
|
- interrupt-parent : optional, if needed for interrupt mapping
|
||||||
|
|
||||||
|
|
||||||
- DMA channel nodes:
|
- DMA channel nodes:
|
||||||
- compatible : compatible list, contains 2 entries, first is
|
- compatible : must include "fsl,elo-dma-channel"
|
||||||
"fsl,CHIP-dma-channel", where CHIP is the processor
|
However, see note below.
|
||||||
(mpc8349, mpc8350, etc.) and the second is
|
- reg : DMA channel specific registers
|
||||||
"fsl,elo-dma-channel". However, see note below.
|
- cell-index : DMA channel index starts at 0.
|
||||||
- reg : <registers mapping for channel>
|
|
||||||
- cell-index : dma channel index starts at 0.
|
|
||||||
|
|
||||||
Optional properties:
|
Optional properties:
|
||||||
- interrupts : <interrupt mapping for DMA channel IRQ>
|
- interrupts : interrupt specifier for DMA channel IRQ
|
||||||
(on 83xx this is expected to be identical to
|
(on 83xx this is expected to be identical to
|
||||||
the interrupts property of the parent node)
|
the interrupts property of the parent node)
|
||||||
- interrupt-parent : optional, if needed for interrupt mapping
|
- interrupt-parent : optional, if needed for interrupt mapping
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
@ -70,30 +67,27 @@ Example:
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
* Freescale 85xx/86xx DMA Controller
|
** Freescale EloPlus DMA Controller
|
||||||
|
This is a 4-channel DMA controller with extended addresses and chaining,
|
||||||
Freescale PowerPC 85xx/86xx have on chip general purpose DMA controllers.
|
mainly used in Freescale mpc85xx/86xx, Pxxx and BSC series chips, such as
|
||||||
|
mpc8540, mpc8641 p4080, bsc9131 etc.
|
||||||
|
|
||||||
Required properties:
|
Required properties:
|
||||||
|
|
||||||
- compatible : compatible list, contains 2 entries, first is
|
- compatible : must include "fsl,eloplus-dma"
|
||||||
"fsl,CHIP-dma", where CHIP is the processor
|
- reg : DMA General Status Register, i.e. DGSR which contains
|
||||||
(mpc8540, mpc8540, etc.) and the second is
|
status for all the 4 DMA channels
|
||||||
"fsl,eloplus-dma"
|
|
||||||
- reg : <registers mapping for DMA general status reg>
|
|
||||||
- cell-index : controller index. 0 for controller @ 0x21000,
|
- cell-index : controller index. 0 for controller @ 0x21000,
|
||||||
1 for controller @ 0xc000
|
1 for controller @ 0xc000
|
||||||
- ranges : Should be defined as specified in 1) to describe the
|
- ranges : describes the mapping between the address space of the
|
||||||
DMA controller channels.
|
DMA channels and the address space of the DMA controller
|
||||||
|
|
||||||
- DMA channel nodes:
|
- DMA channel nodes:
|
||||||
- compatible : compatible list, contains 2 entries, first is
|
- compatible : must include "fsl,eloplus-dma-channel"
|
||||||
"fsl,CHIP-dma-channel", where CHIP is the processor
|
However, see note below.
|
||||||
(mpc8540, mpc8560, etc.) and the second is
|
- cell-index : DMA channel index starts at 0.
|
||||||
"fsl,eloplus-dma-channel". However, see note below.
|
- reg : DMA channel specific registers
|
||||||
- cell-index : dma channel index starts at 0.
|
- interrupts : interrupt specifier for DMA channel IRQ
|
||||||
- reg : <registers mapping for channel>
|
|
||||||
- interrupts : <interrupt mapping for DMA channel IRQ>
|
|
||||||
- interrupt-parent : optional, if needed for interrupt mapping
|
- interrupt-parent : optional, if needed for interrupt mapping
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
@ -134,6 +128,76 @@ Example:
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
** Freescale Elo3 DMA Controller
|
||||||
|
DMA controller which has same function as EloPlus except that Elo3 has 8
|
||||||
|
channels while EloPlus has only 4, it is used in Freescale Txxx and Bxxx
|
||||||
|
series chips, such as t1040, t4240, b4860.
|
||||||
|
|
||||||
|
Required properties:
|
||||||
|
|
||||||
|
- compatible : must include "fsl,elo3-dma"
|
||||||
|
- reg : contains two entries for DMA General Status Registers,
|
||||||
|
i.e. DGSR0 which includes status for channel 1~4, and
|
||||||
|
DGSR1 for channel 5~8
|
||||||
|
- ranges : describes the mapping between the address space of the
|
||||||
|
DMA channels and the address space of the DMA controller
|
||||||
|
|
||||||
|
- DMA channel nodes:
|
||||||
|
- compatible : must include "fsl,eloplus-dma-channel"
|
||||||
|
- reg : DMA channel specific registers
|
||||||
|
- interrupts : interrupt specifier for DMA channel IRQ
|
||||||
|
- interrupt-parent : optional, if needed for interrupt mapping
|
||||||
|
|
||||||
|
Example:
|
||||||
|
dma@100300 {
|
||||||
|
#address-cells = <1>;
|
||||||
|
#size-cells = <1>;
|
||||||
|
compatible = "fsl,elo3-dma";
|
||||||
|
reg = <0x100300 0x4>,
|
||||||
|
<0x100600 0x4>;
|
||||||
|
ranges = <0x0 0x100100 0x500>;
|
||||||
|
dma-channel@0 {
|
||||||
|
compatible = "fsl,eloplus-dma-channel";
|
||||||
|
reg = <0x0 0x80>;
|
||||||
|
interrupts = <28 2 0 0>;
|
||||||
|
};
|
||||||
|
dma-channel@80 {
|
||||||
|
compatible = "fsl,eloplus-dma-channel";
|
||||||
|
reg = <0x80 0x80>;
|
||||||
|
interrupts = <29 2 0 0>;
|
||||||
|
};
|
||||||
|
dma-channel@100 {
|
||||||
|
compatible = "fsl,eloplus-dma-channel";
|
||||||
|
reg = <0x100 0x80>;
|
||||||
|
interrupts = <30 2 0 0>;
|
||||||
|
};
|
||||||
|
dma-channel@180 {
|
||||||
|
compatible = "fsl,eloplus-dma-channel";
|
||||||
|
reg = <0x180 0x80>;
|
||||||
|
interrupts = <31 2 0 0>;
|
||||||
|
};
|
||||||
|
dma-channel@300 {
|
||||||
|
compatible = "fsl,eloplus-dma-channel";
|
||||||
|
reg = <0x300 0x80>;
|
||||||
|
interrupts = <76 2 0 0>;
|
||||||
|
};
|
||||||
|
dma-channel@380 {
|
||||||
|
compatible = "fsl,eloplus-dma-channel";
|
||||||
|
reg = <0x380 0x80>;
|
||||||
|
interrupts = <77 2 0 0>;
|
||||||
|
};
|
||||||
|
dma-channel@400 {
|
||||||
|
compatible = "fsl,eloplus-dma-channel";
|
||||||
|
reg = <0x400 0x80>;
|
||||||
|
interrupts = <78 2 0 0>;
|
||||||
|
};
|
||||||
|
dma-channel@480 {
|
||||||
|
compatible = "fsl,eloplus-dma-channel";
|
||||||
|
reg = <0x480 0x80>;
|
||||||
|
interrupts = <79 2 0 0>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
Note on DMA channel compatible properties: The compatible property must say
|
Note on DMA channel compatible properties: The compatible property must say
|
||||||
"fsl,elo-dma-channel" or "fsl,eloplus-dma-channel" to be used by the Elo DMA
|
"fsl,elo-dma-channel" or "fsl,eloplus-dma-channel" to be used by the Elo DMA
|
||||||
driver (fsldma). Any DMA channel used by fsldma cannot be used by another
|
driver (fsldma). Any DMA channel used by fsldma cannot be used by another
|
||||||
|
17
Documentation/devicetree/bindings/rng/qcom,prng.txt
Normal file
17
Documentation/devicetree/bindings/rng/qcom,prng.txt
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
Qualcomm MSM pseudo random number generator.
|
||||||
|
|
||||||
|
Required properties:
|
||||||
|
|
||||||
|
- compatible : should be "qcom,prng"
|
||||||
|
- reg : specifies base physical address and size of the registers map
|
||||||
|
- clocks : phandle to clock-controller plus clock-specifier pair
|
||||||
|
- clock-names : "core" clocks all registers, FIFO and circuits in PRNG IP block
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
rng@f9bff000 {
|
||||||
|
compatible = "qcom,prng";
|
||||||
|
reg = <0xf9bff000 0x200>;
|
||||||
|
clocks = <&clock GCC_PRNG_AHB_CLK>;
|
||||||
|
clock-names = "core";
|
||||||
|
};
|
@ -1,5 +0,0 @@
|
|||||||
NVIDIA Tegra 2 SPI device
|
|
||||||
|
|
||||||
Required properties:
|
|
||||||
- compatible : should be "nvidia,tegra20-spi".
|
|
||||||
- gpios : should specify GPIOs used for chipselect.
|
|
@ -32,12 +32,14 @@ est ESTeem Wireless Modems
|
|||||||
fsl Freescale Semiconductor
|
fsl Freescale Semiconductor
|
||||||
GEFanuc GE Fanuc Intelligent Platforms Embedded Systems, Inc.
|
GEFanuc GE Fanuc Intelligent Platforms Embedded Systems, Inc.
|
||||||
gef GE Fanuc Intelligent Platforms Embedded Systems, Inc.
|
gef GE Fanuc Intelligent Platforms Embedded Systems, Inc.
|
||||||
|
gmt Global Mixed-mode Technology, Inc.
|
||||||
hisilicon Hisilicon Limited.
|
hisilicon Hisilicon Limited.
|
||||||
hp Hewlett Packard
|
hp Hewlett Packard
|
||||||
ibm International Business Machines (IBM)
|
ibm International Business Machines (IBM)
|
||||||
idt Integrated Device Technologies, Inc.
|
idt Integrated Device Technologies, Inc.
|
||||||
img Imagination Technologies Ltd.
|
img Imagination Technologies Ltd.
|
||||||
intercontrol Inter Control Group
|
intercontrol Inter Control Group
|
||||||
|
lg LG Corporation
|
||||||
linux Linux-specific binding
|
linux Linux-specific binding
|
||||||
lsi LSI Corp. (LSI Logic)
|
lsi LSI Corp. (LSI Logic)
|
||||||
marvell Marvell Technology Group Ltd.
|
marvell Marvell Technology Group Ltd.
|
||||||
|
@ -15,39 +15,48 @@ be built as module or inside kernel. Let's consider those cases.
|
|||||||
|
|
||||||
Part 2 - When dmatest is built as a module...
|
Part 2 - When dmatest is built as a module...
|
||||||
|
|
||||||
After mounting debugfs and loading the module, the /sys/kernel/debug/dmatest
|
|
||||||
folder with nodes will be created. There are two important files located. First
|
|
||||||
is the 'run' node that controls run and stop phases of the test, and the second
|
|
||||||
one, 'results', is used to get the test case results.
|
|
||||||
|
|
||||||
Note that in this case test will not run on load automatically.
|
|
||||||
|
|
||||||
Example of usage:
|
Example of usage:
|
||||||
|
% modprobe dmatest channel=dma0chan0 timeout=2000 iterations=1 run=1
|
||||||
|
|
||||||
|
...or:
|
||||||
|
% modprobe dmatest
|
||||||
% echo dma0chan0 > /sys/module/dmatest/parameters/channel
|
% echo dma0chan0 > /sys/module/dmatest/parameters/channel
|
||||||
% echo 2000 > /sys/module/dmatest/parameters/timeout
|
% echo 2000 > /sys/module/dmatest/parameters/timeout
|
||||||
% echo 1 > /sys/module/dmatest/parameters/iterations
|
% echo 1 > /sys/module/dmatest/parameters/iterations
|
||||||
% echo 1 > /sys/kernel/debug/dmatest/run
|
% echo 1 > /sys/module/dmatest/parameters/run
|
||||||
|
|
||||||
|
...or on the kernel command line:
|
||||||
|
|
||||||
|
dmatest.channel=dma0chan0 dmatest.timeout=2000 dmatest.iterations=1 dmatest.run=1
|
||||||
|
|
||||||
Hint: available channel list could be extracted by running the following
|
Hint: available channel list could be extracted by running the following
|
||||||
command:
|
command:
|
||||||
% ls -1 /sys/class/dma/
|
% ls -1 /sys/class/dma/
|
||||||
|
|
||||||
After a while you will start to get messages about current status or error like
|
Once started a message like "dmatest: Started 1 threads using dma0chan0" is
|
||||||
in the original code.
|
emitted. After that only test failure messages are reported until the test
|
||||||
|
stops.
|
||||||
|
|
||||||
Note that running a new test will not stop any in progress test.
|
Note that running a new test will not stop any in progress test.
|
||||||
|
|
||||||
The following command should return actual state of the test.
|
The following command returns the state of the test.
|
||||||
% cat /sys/kernel/debug/dmatest/run
|
% cat /sys/module/dmatest/parameters/run
|
||||||
|
|
||||||
To wait for test done the user may perform a busy loop that checks the state.
|
To wait for test completion userpace can poll 'run' until it is false, or use
|
||||||
|
the wait parameter. Specifying 'wait=1' when loading the module causes module
|
||||||
|
initialization to pause until a test run has completed, while reading
|
||||||
|
/sys/module/dmatest/parameters/wait waits for any running test to complete
|
||||||
|
before returning. For example, the following scripts wait for 42 tests
|
||||||
|
to complete before exiting. Note that if 'iterations' is set to 'infinite' then
|
||||||
|
waiting is disabled.
|
||||||
|
|
||||||
% while [ $(cat /sys/kernel/debug/dmatest/run) = "Y" ]
|
Example:
|
||||||
> do
|
% modprobe dmatest run=1 iterations=42 wait=1
|
||||||
> echo -n "."
|
% modprobe -r dmatest
|
||||||
> sleep 1
|
...or:
|
||||||
> done
|
% modprobe dmatest run=1 iterations=42
|
||||||
> echo
|
% cat /sys/module/dmatest/parameters/wait
|
||||||
|
% modprobe -r dmatest
|
||||||
|
|
||||||
Part 3 - When built-in in the kernel...
|
Part 3 - When built-in in the kernel...
|
||||||
|
|
||||||
@ -62,21 +71,22 @@ case. You always could check them at run-time by running
|
|||||||
|
|
||||||
Part 4 - Gathering the test results
|
Part 4 - Gathering the test results
|
||||||
|
|
||||||
The module provides a storage for the test results in the memory. The gathered
|
Test results are printed to the kernel log buffer with the format:
|
||||||
data could be used after test is done.
|
|
||||||
|
|
||||||
The special file 'results' in the debugfs represents gathered data of the in
|
"dmatest: result <channel>: <test id>: '<error msg>' with src_off=<val> dst_off=<val> len=<val> (<err code>)"
|
||||||
progress test. The messages collected are printed to the kernel log as well.
|
|
||||||
|
|
||||||
Example of output:
|
Example of output:
|
||||||
% cat /sys/kernel/debug/dmatest/results
|
% dmesg | tail -n 1
|
||||||
dma0chan0-copy0: #1: No errors with src_off=0x7bf dst_off=0x8ad len=0x3fea (0)
|
dmatest: result dma0chan0-copy0: #1: No errors with src_off=0x7bf dst_off=0x8ad len=0x3fea (0)
|
||||||
|
|
||||||
The message format is unified across the different types of errors. A number in
|
The message format is unified across the different types of errors. A number in
|
||||||
the parens represents additional information, e.g. error code, error counter,
|
the parens represents additional information, e.g. error code, error counter,
|
||||||
or status.
|
or status. A test thread also emits a summary line at completion listing the
|
||||||
|
number of tests executed, number that failed, and a result code.
|
||||||
|
|
||||||
Comparison between buffers is stored to the dedicated structure.
|
Example:
|
||||||
|
% dmesg | tail -n 1
|
||||||
|
dmatest: dma0chan0-copy0: summary 1 test, 0 failures 1000 iops 100000 KB/s (0)
|
||||||
|
|
||||||
Note that the verify result is now accessible only via file 'results' in the
|
The details of a data miscompare error are also emitted, but do not follow the
|
||||||
debugfs.
|
above format.
|
||||||
|
@ -70,6 +70,12 @@ Unless otherwise specified, all options default to off.
|
|||||||
|
|
||||||
See comments at the top of fs/btrfs/check-integrity.c for more info.
|
See comments at the top of fs/btrfs/check-integrity.c for more info.
|
||||||
|
|
||||||
|
commit=<seconds>
|
||||||
|
Set the interval of periodic commit, 30 seconds by default. Higher
|
||||||
|
values defer data being synced to permanent storage with obvious
|
||||||
|
consequences when the system crashes. The upper bound is not forced,
|
||||||
|
but a warning is printed if it's more than 300 seconds (5 minutes).
|
||||||
|
|
||||||
compress
|
compress
|
||||||
compress=<type>
|
compress=<type>
|
||||||
compress-force
|
compress-force
|
||||||
@ -154,7 +160,11 @@ Unless otherwise specified, all options default to off.
|
|||||||
Currently this scans a list of several previous tree roots and tries to
|
Currently this scans a list of several previous tree roots and tries to
|
||||||
use the first readable.
|
use the first readable.
|
||||||
|
|
||||||
skip_balance
|
rescan_uuid_tree
|
||||||
|
Force check and rebuild procedure of the UUID tree. This should not
|
||||||
|
normally be needed.
|
||||||
|
|
||||||
|
skip_balance
|
||||||
Skip automatic resume of interrupted balance operation after mount.
|
Skip automatic resume of interrupted balance operation after mount.
|
||||||
May be resumed with "btrfs balance resume."
|
May be resumed with "btrfs balance resume."
|
||||||
|
|
||||||
@ -234,24 +244,14 @@ available from the git repository at the following location:
|
|||||||
|
|
||||||
These include the following tools:
|
These include the following tools:
|
||||||
|
|
||||||
mkfs.btrfs: create a filesystem
|
* mkfs.btrfs: create a filesystem
|
||||||
|
|
||||||
btrfsctl: control program to create snapshots and subvolumes:
|
* btrfs: a single tool to manage the filesystems, refer to the manpage for more details
|
||||||
|
|
||||||
mount /dev/sda2 /mnt
|
* 'btrfsck' or 'btrfs check': do a consistency check of the filesystem
|
||||||
btrfsctl -s new_subvol_name /mnt
|
|
||||||
btrfsctl -s snapshot_of_default /mnt/default
|
|
||||||
btrfsctl -s snapshot_of_new_subvol /mnt/new_subvol_name
|
|
||||||
btrfsctl -s snapshot_of_a_snapshot /mnt/snapshot_of_new_subvol
|
|
||||||
ls /mnt
|
|
||||||
default snapshot_of_a_snapshot snapshot_of_new_subvol
|
|
||||||
new_subvol_name snapshot_of_default
|
|
||||||
|
|
||||||
Snapshots and subvolumes cannot be deleted right now, but you can
|
Other tools for specific tasks:
|
||||||
rm -rf all the files and directories inside them.
|
|
||||||
|
|
||||||
btrfsck: do a limited check of the FS extent trees.
|
* btrfs-convert: in-place conversion from ext2/3/4 filesystems
|
||||||
|
|
||||||
btrfs-debug-tree: print all of the FS metadata in text form. Example:
|
* btrfs-image: dump filesystem metadata for debugging
|
||||||
|
|
||||||
btrfs-debug-tree /dev/sda2 >& big_output_file
|
|
||||||
|
14
Documentation/gpio/00-INDEX
Normal file
14
Documentation/gpio/00-INDEX
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
00-INDEX
|
||||||
|
- This file
|
||||||
|
gpio.txt
|
||||||
|
- Introduction to GPIOs and their kernel interfaces
|
||||||
|
consumer.txt
|
||||||
|
- How to obtain and use GPIOs in a driver
|
||||||
|
driver.txt
|
||||||
|
- How to write a GPIO driver
|
||||||
|
board.txt
|
||||||
|
- How to assign GPIOs to a consumer device and a function
|
||||||
|
sysfs.txt
|
||||||
|
- Information about the GPIO sysfs interface
|
||||||
|
gpio-legacy.txt
|
||||||
|
- Historical documentation of the deprecated GPIO integer interface
|
115
Documentation/gpio/board.txt
Normal file
115
Documentation/gpio/board.txt
Normal file
@ -0,0 +1,115 @@
|
|||||||
|
GPIO Mappings
|
||||||
|
=============
|
||||||
|
|
||||||
|
This document explains how GPIOs can be assigned to given devices and functions.
|
||||||
|
Note that it only applies to the new descriptor-based interface. For a
|
||||||
|
description of the deprecated integer-based GPIO interface please refer to
|
||||||
|
gpio-legacy.txt (actually, there is no real mapping possible with the old
|
||||||
|
interface; you just fetch an integer from somewhere and request the
|
||||||
|
corresponding GPIO.
|
||||||
|
|
||||||
|
Platforms that make use of GPIOs must select ARCH_REQUIRE_GPIOLIB (if GPIO usage
|
||||||
|
is mandatory) or ARCH_WANT_OPTIONAL_GPIOLIB (if GPIO support can be omitted) in
|
||||||
|
their Kconfig. Then, how GPIOs are mapped depends on what the platform uses to
|
||||||
|
describe its hardware layout. Currently, mappings can be defined through device
|
||||||
|
tree, ACPI, and platform data.
|
||||||
|
|
||||||
|
Device Tree
|
||||||
|
-----------
|
||||||
|
GPIOs can easily be mapped to devices and functions in the device tree. The
|
||||||
|
exact way to do it depends on the GPIO controller providing the GPIOs, see the
|
||||||
|
device tree bindings for your controller.
|
||||||
|
|
||||||
|
GPIOs mappings are defined in the consumer device's node, in a property named
|
||||||
|
<function>-gpios, where <function> is the function the driver will request
|
||||||
|
through gpiod_get(). For example:
|
||||||
|
|
||||||
|
foo_device {
|
||||||
|
compatible = "acme,foo";
|
||||||
|
...
|
||||||
|
led-gpios = <&gpio 15 GPIO_ACTIVE_HIGH>, /* red */
|
||||||
|
<&gpio 16 GPIO_ACTIVE_HIGH>, /* green */
|
||||||
|
<&gpio 17 GPIO_ACTIVE_HIGH>; /* blue */
|
||||||
|
|
||||||
|
power-gpio = <&gpio 1 GPIO_ACTIVE_LOW>;
|
||||||
|
};
|
||||||
|
|
||||||
|
This property will make GPIOs 15, 16 and 17 available to the driver under the
|
||||||
|
"led" function, and GPIO 1 as the "power" GPIO:
|
||||||
|
|
||||||
|
struct gpio_desc *red, *green, *blue, *power;
|
||||||
|
|
||||||
|
red = gpiod_get_index(dev, "led", 0);
|
||||||
|
green = gpiod_get_index(dev, "led", 1);
|
||||||
|
blue = gpiod_get_index(dev, "led", 2);
|
||||||
|
|
||||||
|
power = gpiod_get(dev, "power");
|
||||||
|
|
||||||
|
The led GPIOs will be active-high, while the power GPIO will be active-low (i.e.
|
||||||
|
gpiod_is_active_low(power) will be true).
|
||||||
|
|
||||||
|
ACPI
|
||||||
|
----
|
||||||
|
ACPI does not support function names for GPIOs. Therefore, only the "idx"
|
||||||
|
argument of gpiod_get_index() is useful to discriminate between GPIOs assigned
|
||||||
|
to a device. The "con_id" argument can still be set for debugging purposes (it
|
||||||
|
will appear under error messages as well as debug and sysfs nodes).
|
||||||
|
|
||||||
|
Platform Data
|
||||||
|
-------------
|
||||||
|
Finally, GPIOs can be bound to devices and functions using platform data. Board
|
||||||
|
files that desire to do so need to include the following header:
|
||||||
|
|
||||||
|
#include <linux/gpio/driver.h>
|
||||||
|
|
||||||
|
GPIOs are mapped by the means of tables of lookups, containing instances of the
|
||||||
|
gpiod_lookup structure. Two macros are defined to help declaring such mappings:
|
||||||
|
|
||||||
|
GPIO_LOOKUP(chip_label, chip_hwnum, dev_id, con_id, flags)
|
||||||
|
GPIO_LOOKUP_IDX(chip_label, chip_hwnum, dev_id, con_id, idx, flags)
|
||||||
|
|
||||||
|
where
|
||||||
|
|
||||||
|
- chip_label is the label of the gpiod_chip instance providing the GPIO
|
||||||
|
- chip_hwnum is the hardware number of the GPIO within the chip
|
||||||
|
- dev_id is the identifier of the device that will make use of this GPIO. If
|
||||||
|
NULL, the GPIO will be available to all devices.
|
||||||
|
- con_id is the name of the GPIO function from the device point of view. It
|
||||||
|
can be NULL.
|
||||||
|
- idx is the index of the GPIO within the function.
|
||||||
|
- flags is defined to specify the following properties:
|
||||||
|
* GPIOF_ACTIVE_LOW - to configure the GPIO as active-low
|
||||||
|
* GPIOF_OPEN_DRAIN - GPIO pin is open drain type.
|
||||||
|
* GPIOF_OPEN_SOURCE - GPIO pin is open source type.
|
||||||
|
|
||||||
|
In the future, these flags might be extended to support more properties.
|
||||||
|
|
||||||
|
Note that GPIO_LOOKUP() is just a shortcut to GPIO_LOOKUP_IDX() where idx = 0.
|
||||||
|
|
||||||
|
A lookup table can then be defined as follows:
|
||||||
|
|
||||||
|
struct gpiod_lookup gpios_table[] = {
|
||||||
|
GPIO_LOOKUP_IDX("gpio.0", 15, "foo.0", "led", 0, GPIO_ACTIVE_HIGH),
|
||||||
|
GPIO_LOOKUP_IDX("gpio.0", 16, "foo.0", "led", 1, GPIO_ACTIVE_HIGH),
|
||||||
|
GPIO_LOOKUP_IDX("gpio.0", 17, "foo.0", "led", 2, GPIO_ACTIVE_HIGH),
|
||||||
|
GPIO_LOOKUP("gpio.0", 1, "foo.0", "power", GPIO_ACTIVE_LOW),
|
||||||
|
};
|
||||||
|
|
||||||
|
And the table can be added by the board code as follows:
|
||||||
|
|
||||||
|
gpiod_add_table(gpios_table, ARRAY_SIZE(gpios_table));
|
||||||
|
|
||||||
|
The driver controlling "foo.0" will then be able to obtain its GPIOs as follows:
|
||||||
|
|
||||||
|
struct gpio_desc *red, *green, *blue, *power;
|
||||||
|
|
||||||
|
red = gpiod_get_index(dev, "led", 0);
|
||||||
|
green = gpiod_get_index(dev, "led", 1);
|
||||||
|
blue = gpiod_get_index(dev, "led", 2);
|
||||||
|
|
||||||
|
power = gpiod_get(dev, "power");
|
||||||
|
gpiod_direction_output(power, 1);
|
||||||
|
|
||||||
|
Since the "power" GPIO is mapped as active-low, its actual signal will be 0
|
||||||
|
after this code. Contrary to the legacy integer GPIO interface, the active-low
|
||||||
|
property is handled during mapping and is thus transparent to GPIO consumers.
|
197
Documentation/gpio/consumer.txt
Normal file
197
Documentation/gpio/consumer.txt
Normal file
@ -0,0 +1,197 @@
|
|||||||
|
GPIO Descriptor Consumer Interface
|
||||||
|
==================================
|
||||||
|
|
||||||
|
This document describes the consumer interface of the GPIO framework. Note that
|
||||||
|
it describes the new descriptor-based interface. For a description of the
|
||||||
|
deprecated integer-based GPIO interface please refer to gpio-legacy.txt.
|
||||||
|
|
||||||
|
|
||||||
|
Guidelines for GPIOs consumers
|
||||||
|
==============================
|
||||||
|
|
||||||
|
Drivers that can't work without standard GPIO calls should have Kconfig entries
|
||||||
|
that depend on GPIOLIB. The functions that allow a driver to obtain and use
|
||||||
|
GPIOs are available by including the following file:
|
||||||
|
|
||||||
|
#include <linux/gpio/consumer.h>
|
||||||
|
|
||||||
|
All the functions that work with the descriptor-based GPIO interface are
|
||||||
|
prefixed with gpiod_. The gpio_ prefix is used for the legacy interface. No
|
||||||
|
other function in the kernel should use these prefixes.
|
||||||
|
|
||||||
|
|
||||||
|
Obtaining and Disposing GPIOs
|
||||||
|
=============================
|
||||||
|
|
||||||
|
With the descriptor-based interface, GPIOs are identified with an opaque,
|
||||||
|
non-forgeable handler that must be obtained through a call to one of the
|
||||||
|
gpiod_get() functions. Like many other kernel subsystems, gpiod_get() takes the
|
||||||
|
device that will use the GPIO and the function the requested GPIO is supposed to
|
||||||
|
fulfill:
|
||||||
|
|
||||||
|
struct gpio_desc *gpiod_get(struct device *dev, const char *con_id)
|
||||||
|
|
||||||
|
If a function is implemented by using several GPIOs together (e.g. a simple LED
|
||||||
|
device that displays digits), an additional index argument can be specified:
|
||||||
|
|
||||||
|
struct gpio_desc *gpiod_get_index(struct device *dev,
|
||||||
|
const char *con_id, unsigned int idx)
|
||||||
|
|
||||||
|
Both functions return either a valid GPIO descriptor, or an error code checkable
|
||||||
|
with IS_ERR(). They will never return a NULL pointer.
|
||||||
|
|
||||||
|
Device-managed variants of these functions are also defined:
|
||||||
|
|
||||||
|
struct gpio_desc *devm_gpiod_get(struct device *dev, const char *con_id)
|
||||||
|
|
||||||
|
struct gpio_desc *devm_gpiod_get_index(struct device *dev,
|
||||||
|
const char *con_id,
|
||||||
|
unsigned int idx)
|
||||||
|
|
||||||
|
A GPIO descriptor can be disposed of using the gpiod_put() function:
|
||||||
|
|
||||||
|
void gpiod_put(struct gpio_desc *desc)
|
||||||
|
|
||||||
|
It is strictly forbidden to use a descriptor after calling this function. The
|
||||||
|
device-managed variant is, unsurprisingly:
|
||||||
|
|
||||||
|
void devm_gpiod_put(struct device *dev, struct gpio_desc *desc)
|
||||||
|
|
||||||
|
|
||||||
|
Using GPIOs
|
||||||
|
===========
|
||||||
|
|
||||||
|
Setting Direction
|
||||||
|
-----------------
|
||||||
|
The first thing a driver must do with a GPIO is setting its direction. This is
|
||||||
|
done by invoking one of the gpiod_direction_*() functions:
|
||||||
|
|
||||||
|
int gpiod_direction_input(struct gpio_desc *desc)
|
||||||
|
int gpiod_direction_output(struct gpio_desc *desc, int value)
|
||||||
|
|
||||||
|
The return value is zero for success, else a negative errno. It should be
|
||||||
|
checked, since the get/set calls don't return errors and since misconfiguration
|
||||||
|
is possible. You should normally issue these calls from a task context. However,
|
||||||
|
for spinlock-safe GPIOs it is OK to use them before tasking is enabled, as part
|
||||||
|
of early board setup.
|
||||||
|
|
||||||
|
For output GPIOs, the value provided becomes the initial output value. This
|
||||||
|
helps avoid signal glitching during system startup.
|
||||||
|
|
||||||
|
A driver can also query the current direction of a GPIO:
|
||||||
|
|
||||||
|
int gpiod_get_direction(const struct gpio_desc *desc)
|
||||||
|
|
||||||
|
This function will return either GPIOF_DIR_IN or GPIOF_DIR_OUT.
|
||||||
|
|
||||||
|
Be aware that there is no default direction for GPIOs. Therefore, **using a GPIO
|
||||||
|
without setting its direction first is illegal and will result in undefined
|
||||||
|
behavior!**
|
||||||
|
|
||||||
|
|
||||||
|
Spinlock-Safe GPIO Access
|
||||||
|
-------------------------
|
||||||
|
Most GPIO controllers can be accessed with memory read/write instructions. Those
|
||||||
|
don't need to sleep, and can safely be done from inside hard (non-threaded) IRQ
|
||||||
|
handlers and similar contexts.
|
||||||
|
|
||||||
|
Use the following calls to access GPIOs from an atomic context:
|
||||||
|
|
||||||
|
int gpiod_get_value(const struct gpio_desc *desc);
|
||||||
|
void gpiod_set_value(struct gpio_desc *desc, int value);
|
||||||
|
|
||||||
|
The values are boolean, zero for low, nonzero for high. When reading the value
|
||||||
|
of an output pin, the value returned should be what's seen on the pin. That
|
||||||
|
won't always match the specified output value, because of issues including
|
||||||
|
open-drain signaling and output latencies.
|
||||||
|
|
||||||
|
The get/set calls do not return errors because "invalid GPIO" should have been
|
||||||
|
reported earlier from gpiod_direction_*(). However, note that not all platforms
|
||||||
|
can read the value of output pins; those that can't should always return zero.
|
||||||
|
Also, using these calls for GPIOs that can't safely be accessed without sleeping
|
||||||
|
(see below) is an error.
|
||||||
|
|
||||||
|
|
||||||
|
GPIO Access That May Sleep
|
||||||
|
--------------------------
|
||||||
|
Some GPIO controllers must be accessed using message based buses like I2C or
|
||||||
|
SPI. Commands to read or write those GPIO values require waiting to get to the
|
||||||
|
head of a queue to transmit a command and get its response. This requires
|
||||||
|
sleeping, which can't be done from inside IRQ handlers.
|
||||||
|
|
||||||
|
Platforms that support this type of GPIO distinguish them from other GPIOs by
|
||||||
|
returning nonzero from this call:
|
||||||
|
|
||||||
|
int gpiod_cansleep(const struct gpio_desc *desc)
|
||||||
|
|
||||||
|
To access such GPIOs, a different set of accessors is defined:
|
||||||
|
|
||||||
|
int gpiod_get_value_cansleep(const struct gpio_desc *desc)
|
||||||
|
void gpiod_set_value_cansleep(struct gpio_desc *desc, int value)
|
||||||
|
|
||||||
|
Accessing such GPIOs requires a context which may sleep, for example a threaded
|
||||||
|
IRQ handler, and those accessors must be used instead of spinlock-safe
|
||||||
|
accessors without the cansleep() name suffix.
|
||||||
|
|
||||||
|
Other than the fact that these accessors might sleep, and will work on GPIOs
|
||||||
|
that can't be accessed from hardIRQ handlers, these calls act the same as the
|
||||||
|
spinlock-safe calls.
|
||||||
|
|
||||||
|
|
||||||
|
Active-low State and Raw GPIO Values
|
||||||
|
------------------------------------
|
||||||
|
Device drivers like to manage the logical state of a GPIO, i.e. the value their
|
||||||
|
device will actually receive, no matter what lies between it and the GPIO line.
|
||||||
|
In some cases, it might make sense to control the actual GPIO line value. The
|
||||||
|
following set of calls ignore the active-low property of a GPIO and work on the
|
||||||
|
raw line value:
|
||||||
|
|
||||||
|
int gpiod_get_raw_value(const struct gpio_desc *desc)
|
||||||
|
void gpiod_set_raw_value(struct gpio_desc *desc, int value)
|
||||||
|
int gpiod_get_raw_value_cansleep(const struct gpio_desc *desc)
|
||||||
|
void gpiod_set_raw_value_cansleep(struct gpio_desc *desc, int value)
|
||||||
|
|
||||||
|
The active-low state of a GPIO can also be queried using the following call:
|
||||||
|
|
||||||
|
int gpiod_is_active_low(const struct gpio_desc *desc)
|
||||||
|
|
||||||
|
Note that these functions should only be used with great moderation ; a driver
|
||||||
|
should not have to care about the physical line level.
|
||||||
|
|
||||||
|
GPIOs mapped to IRQs
|
||||||
|
--------------------
|
||||||
|
GPIO lines can quite often be used as IRQs. You can get the IRQ number
|
||||||
|
corresponding to a given GPIO using the following call:
|
||||||
|
|
||||||
|
int gpiod_to_irq(const struct gpio_desc *desc)
|
||||||
|
|
||||||
|
It will return an IRQ number, or an negative errno code if the mapping can't be
|
||||||
|
done (most likely because that particular GPIO cannot be used as IRQ). It is an
|
||||||
|
unchecked error to use a GPIO that wasn't set up as an input using
|
||||||
|
gpiod_direction_input(), or to use an IRQ number that didn't originally come
|
||||||
|
from gpiod_to_irq(). gpiod_to_irq() is not allowed to sleep.
|
||||||
|
|
||||||
|
Non-error values returned from gpiod_to_irq() can be passed to request_irq() or
|
||||||
|
free_irq(). They will often be stored into IRQ resources for platform devices,
|
||||||
|
by the board-specific initialization code. Note that IRQ trigger options are
|
||||||
|
part of the IRQ interface, e.g. IRQF_TRIGGER_FALLING, as are system wakeup
|
||||||
|
capabilities.
|
||||||
|
|
||||||
|
|
||||||
|
Interacting With the Legacy GPIO Subsystem
|
||||||
|
==========================================
|
||||||
|
Many kernel subsystems still handle GPIOs using the legacy integer-based
|
||||||
|
interface. Although it is strongly encouraged to upgrade them to the safer
|
||||||
|
descriptor-based API, the following two functions allow you to convert a GPIO
|
||||||
|
descriptor into the GPIO integer namespace and vice-versa:
|
||||||
|
|
||||||
|
int desc_to_gpio(const struct gpio_desc *desc)
|
||||||
|
struct gpio_desc *gpio_to_desc(unsigned gpio)
|
||||||
|
|
||||||
|
The GPIO number returned by desc_to_gpio() can be safely used as long as the
|
||||||
|
GPIO descriptor has not been freed. All the same, a GPIO number passed to
|
||||||
|
gpio_to_desc() must have been properly acquired, and usage of the returned GPIO
|
||||||
|
descriptor is only possible after the GPIO number has been released.
|
||||||
|
|
||||||
|
Freeing a GPIO obtained by one API with the other API is forbidden and an
|
||||||
|
unchecked error.
|
75
Documentation/gpio/driver.txt
Normal file
75
Documentation/gpio/driver.txt
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
GPIO Descriptor Driver Interface
|
||||||
|
================================
|
||||||
|
|
||||||
|
This document serves as a guide for GPIO chip drivers writers. Note that it
|
||||||
|
describes the new descriptor-based interface. For a description of the
|
||||||
|
deprecated integer-based GPIO interface please refer to gpio-legacy.txt.
|
||||||
|
|
||||||
|
Each GPIO controller driver needs to include the following header, which defines
|
||||||
|
the structures used to define a GPIO driver:
|
||||||
|
|
||||||
|
#include <linux/gpio/driver.h>
|
||||||
|
|
||||||
|
|
||||||
|
Internal Representation of GPIOs
|
||||||
|
================================
|
||||||
|
|
||||||
|
Inside a GPIO driver, individual GPIOs are identified by their hardware number,
|
||||||
|
which is a unique number between 0 and n, n being the number of GPIOs managed by
|
||||||
|
the chip. This number is purely internal: the hardware number of a particular
|
||||||
|
GPIO descriptor is never made visible outside of the driver.
|
||||||
|
|
||||||
|
On top of this internal number, each GPIO also need to have a global number in
|
||||||
|
the integer GPIO namespace so that it can be used with the legacy GPIO
|
||||||
|
interface. Each chip must thus have a "base" number (which can be automatically
|
||||||
|
assigned), and for each GPIO the global number will be (base + hardware number).
|
||||||
|
Although the integer representation is considered deprecated, it still has many
|
||||||
|
users and thus needs to be maintained.
|
||||||
|
|
||||||
|
So for example one platform could use numbers 32-159 for GPIOs, with a
|
||||||
|
controller defining 128 GPIOs at a "base" of 32 ; while another platform uses
|
||||||
|
numbers 0..63 with one set of GPIO controllers, 64-79 with another type of GPIO
|
||||||
|
controller, and on one particular board 80-95 with an FPGA. The numbers need not
|
||||||
|
be contiguous; either of those platforms could also use numbers 2000-2063 to
|
||||||
|
identify GPIOs in a bank of I2C GPIO expanders.
|
||||||
|
|
||||||
|
|
||||||
|
Controller Drivers: gpio_chip
|
||||||
|
=============================
|
||||||
|
|
||||||
|
In the gpiolib framework each GPIO controller is packaged as a "struct
|
||||||
|
gpio_chip" (see linux/gpio/driver.h for its complete definition) with members
|
||||||
|
common to each controller of that type:
|
||||||
|
|
||||||
|
- methods to establish GPIO direction
|
||||||
|
- methods used to access GPIO values
|
||||||
|
- method to return the IRQ number associated to a given GPIO
|
||||||
|
- flag saying whether calls to its methods may sleep
|
||||||
|
- optional debugfs dump method (showing extra state like pullup config)
|
||||||
|
- optional base number (will be automatically assigned if omitted)
|
||||||
|
- label for diagnostics and GPIOs mapping using platform data
|
||||||
|
|
||||||
|
The code implementing a gpio_chip should support multiple instances of the
|
||||||
|
controller, possibly using the driver model. That code will configure each
|
||||||
|
gpio_chip and issue gpiochip_add(). Removing a GPIO controller should be rare;
|
||||||
|
use gpiochip_remove() when it is unavoidable.
|
||||||
|
|
||||||
|
Most often a gpio_chip is part of an instance-specific structure with state not
|
||||||
|
exposed by the GPIO interfaces, such as addressing, power management, and more.
|
||||||
|
Chips such as codecs will have complex non-GPIO state.
|
||||||
|
|
||||||
|
Any debugfs dump method should normally ignore signals which haven't been
|
||||||
|
requested as GPIOs. They can use gpiochip_is_requested(), which returns either
|
||||||
|
NULL or the label associated with that GPIO when it was requested.
|
||||||
|
|
||||||
|
Locking IRQ usage
|
||||||
|
-----------------
|
||||||
|
Input GPIOs can be used as IRQ signals. When this happens, a driver is requested
|
||||||
|
to mark the GPIO as being used as an IRQ:
|
||||||
|
|
||||||
|
int gpiod_lock_as_irq(struct gpio_desc *desc)
|
||||||
|
|
||||||
|
This will prevent the use of non-irq related GPIO APIs until the GPIO IRQ lock
|
||||||
|
is released:
|
||||||
|
|
||||||
|
void gpiod_unlock_as_irq(struct gpio_desc *desc)
|
119
Documentation/gpio/gpio.txt
Normal file
119
Documentation/gpio/gpio.txt
Normal file
@ -0,0 +1,119 @@
|
|||||||
|
GPIO Interfaces
|
||||||
|
===============
|
||||||
|
|
||||||
|
The documents in this directory give detailed instructions on how to access
|
||||||
|
GPIOs in drivers, and how to write a driver for a device that provides GPIOs
|
||||||
|
itself.
|
||||||
|
|
||||||
|
Due to the history of GPIO interfaces in the kernel, there are two different
|
||||||
|
ways to obtain and use GPIOs:
|
||||||
|
|
||||||
|
- The descriptor-based interface is the preferred way to manipulate GPIOs,
|
||||||
|
and is described by all the files in this directory excepted gpio-legacy.txt.
|
||||||
|
- The legacy integer-based interface which is considered deprecated (but still
|
||||||
|
usable for compatibility reasons) is documented in gpio-legacy.txt.
|
||||||
|
|
||||||
|
The remainder of this document applies to the new descriptor-based interface.
|
||||||
|
gpio-legacy.txt contains the same information applied to the legacy
|
||||||
|
integer-based interface.
|
||||||
|
|
||||||
|
|
||||||
|
What is a GPIO?
|
||||||
|
===============
|
||||||
|
|
||||||
|
A "General Purpose Input/Output" (GPIO) is a flexible software-controlled
|
||||||
|
digital signal. They are provided from many kinds of chip, and are familiar
|
||||||
|
to Linux developers working with embedded and custom hardware. Each GPIO
|
||||||
|
represents a bit connected to a particular pin, or "ball" on Ball Grid Array
|
||||||
|
(BGA) packages. Board schematics show which external hardware connects to
|
||||||
|
which GPIOs. Drivers can be written generically, so that board setup code
|
||||||
|
passes such pin configuration data to drivers.
|
||||||
|
|
||||||
|
System-on-Chip (SOC) processors heavily rely on GPIOs. In some cases, every
|
||||||
|
non-dedicated pin can be configured as a GPIO; and most chips have at least
|
||||||
|
several dozen of them. Programmable logic devices (like FPGAs) can easily
|
||||||
|
provide GPIOs; multifunction chips like power managers, and audio codecs
|
||||||
|
often have a few such pins to help with pin scarcity on SOCs; and there are
|
||||||
|
also "GPIO Expander" chips that connect using the I2C or SPI serial buses.
|
||||||
|
Most PC southbridges have a few dozen GPIO-capable pins (with only the BIOS
|
||||||
|
firmware knowing how they're used).
|
||||||
|
|
||||||
|
The exact capabilities of GPIOs vary between systems. Common options:
|
||||||
|
|
||||||
|
- Output values are writable (high=1, low=0). Some chips also have
|
||||||
|
options about how that value is driven, so that for example only one
|
||||||
|
value might be driven, supporting "wire-OR" and similar schemes for the
|
||||||
|
other value (notably, "open drain" signaling).
|
||||||
|
|
||||||
|
- Input values are likewise readable (1, 0). Some chips support readback
|
||||||
|
of pins configured as "output", which is very useful in such "wire-OR"
|
||||||
|
cases (to support bidirectional signaling). GPIO controllers may have
|
||||||
|
input de-glitch/debounce logic, sometimes with software controls.
|
||||||
|
|
||||||
|
- Inputs can often be used as IRQ signals, often edge triggered but
|
||||||
|
sometimes level triggered. Such IRQs may be configurable as system
|
||||||
|
wakeup events, to wake the system from a low power state.
|
||||||
|
|
||||||
|
- Usually a GPIO will be configurable as either input or output, as needed
|
||||||
|
by different product boards; single direction ones exist too.
|
||||||
|
|
||||||
|
- Most GPIOs can be accessed while holding spinlocks, but those accessed
|
||||||
|
through a serial bus normally can't. Some systems support both types.
|
||||||
|
|
||||||
|
On a given board each GPIO is used for one specific purpose like monitoring
|
||||||
|
MMC/SD card insertion/removal, detecting card write-protect status, driving
|
||||||
|
a LED, configuring a transceiver, bit-banging a serial bus, poking a hardware
|
||||||
|
watchdog, sensing a switch, and so on.
|
||||||
|
|
||||||
|
|
||||||
|
Common GPIO Properties
|
||||||
|
======================
|
||||||
|
|
||||||
|
These properties are met through all the other documents of the GPIO interface
|
||||||
|
and it is useful to understand them, especially if you need to define GPIO
|
||||||
|
mappings.
|
||||||
|
|
||||||
|
Active-High and Active-Low
|
||||||
|
--------------------------
|
||||||
|
It is natural to assume that a GPIO is "active" when its output signal is 1
|
||||||
|
("high"), and inactive when it is 0 ("low"). However in practice the signal of a
|
||||||
|
GPIO may be inverted before is reaches its destination, or a device could decide
|
||||||
|
to have different conventions about what "active" means. Such decisions should
|
||||||
|
be transparent to device drivers, therefore it is possible to define a GPIO as
|
||||||
|
being either active-high ("1" means "active", the default) or active-low ("0"
|
||||||
|
means "active") so that drivers only need to worry about the logical signal and
|
||||||
|
not about what happens at the line level.
|
||||||
|
|
||||||
|
Open Drain and Open Source
|
||||||
|
--------------------------
|
||||||
|
Sometimes shared signals need to use "open drain" (where only the low signal
|
||||||
|
level is actually driven), or "open source" (where only the high signal level is
|
||||||
|
driven) signaling. That term applies to CMOS transistors; "open collector" is
|
||||||
|
used for TTL. A pullup or pulldown resistor causes the high or low signal level.
|
||||||
|
This is sometimes called a "wire-AND"; or more practically, from the negative
|
||||||
|
logic (low=true) perspective this is a "wire-OR".
|
||||||
|
|
||||||
|
One common example of an open drain signal is a shared active-low IRQ line.
|
||||||
|
Also, bidirectional data bus signals sometimes use open drain signals.
|
||||||
|
|
||||||
|
Some GPIO controllers directly support open drain and open source outputs; many
|
||||||
|
don't. When you need open drain signaling but your hardware doesn't directly
|
||||||
|
support it, there's a common idiom you can use to emulate it with any GPIO pin
|
||||||
|
that can be used as either an input or an output:
|
||||||
|
|
||||||
|
LOW: gpiod_direction_output(gpio, 0) ... this drives the signal and overrides
|
||||||
|
the pullup.
|
||||||
|
|
||||||
|
HIGH: gpiod_direction_input(gpio) ... this turns off the output, so the pullup
|
||||||
|
(or some other device) controls the signal.
|
||||||
|
|
||||||
|
The same logic can be applied to emulate open source signaling, by driving the
|
||||||
|
high signal and configuring the GPIO as input for low. This open drain/open
|
||||||
|
source emulation can be handled transparently by the GPIO framework.
|
||||||
|
|
||||||
|
If you are "driving" the signal high but gpiod_get_value(gpio) reports a low
|
||||||
|
value (after the appropriate rise time passes), you know some other component is
|
||||||
|
driving the shared signal low. That's not necessarily an error. As one common
|
||||||
|
example, that's how I2C clocks are stretched: a slave that needs a slower clock
|
||||||
|
delays the rising edge of SCK, and the I2C master adjusts its signaling rate
|
||||||
|
accordingly.
|
155
Documentation/gpio/sysfs.txt
Normal file
155
Documentation/gpio/sysfs.txt
Normal file
@ -0,0 +1,155 @@
|
|||||||
|
GPIO Sysfs Interface for Userspace
|
||||||
|
==================================
|
||||||
|
|
||||||
|
Platforms which use the "gpiolib" implementors framework may choose to
|
||||||
|
configure a sysfs user interface to GPIOs. This is different from the
|
||||||
|
debugfs interface, since it provides control over GPIO direction and
|
||||||
|
value instead of just showing a gpio state summary. Plus, it could be
|
||||||
|
present on production systems without debugging support.
|
||||||
|
|
||||||
|
Given appropriate hardware documentation for the system, userspace could
|
||||||
|
know for example that GPIO #23 controls the write protect line used to
|
||||||
|
protect boot loader segments in flash memory. System upgrade procedures
|
||||||
|
may need to temporarily remove that protection, first importing a GPIO,
|
||||||
|
then changing its output state, then updating the code before re-enabling
|
||||||
|
the write protection. In normal use, GPIO #23 would never be touched,
|
||||||
|
and the kernel would have no need to know about it.
|
||||||
|
|
||||||
|
Again depending on appropriate hardware documentation, on some systems
|
||||||
|
userspace GPIO can be used to determine system configuration data that
|
||||||
|
standard kernels won't know about. And for some tasks, simple userspace
|
||||||
|
GPIO drivers could be all that the system really needs.
|
||||||
|
|
||||||
|
Note that standard kernel drivers exist for common "LEDs and Buttons"
|
||||||
|
GPIO tasks: "leds-gpio" and "gpio_keys", respectively. Use those
|
||||||
|
instead of talking directly to the GPIOs; they integrate with kernel
|
||||||
|
frameworks better than your userspace code could.
|
||||||
|
|
||||||
|
|
||||||
|
Paths in Sysfs
|
||||||
|
--------------
|
||||||
|
There are three kinds of entry in /sys/class/gpio:
|
||||||
|
|
||||||
|
- Control interfaces used to get userspace control over GPIOs;
|
||||||
|
|
||||||
|
- GPIOs themselves; and
|
||||||
|
|
||||||
|
- GPIO controllers ("gpio_chip" instances).
|
||||||
|
|
||||||
|
That's in addition to standard files including the "device" symlink.
|
||||||
|
|
||||||
|
The control interfaces are write-only:
|
||||||
|
|
||||||
|
/sys/class/gpio/
|
||||||
|
|
||||||
|
"export" ... Userspace may ask the kernel to export control of
|
||||||
|
a GPIO to userspace by writing its number to this file.
|
||||||
|
|
||||||
|
Example: "echo 19 > export" will create a "gpio19" node
|
||||||
|
for GPIO #19, if that's not requested by kernel code.
|
||||||
|
|
||||||
|
"unexport" ... Reverses the effect of exporting to userspace.
|
||||||
|
|
||||||
|
Example: "echo 19 > unexport" will remove a "gpio19"
|
||||||
|
node exported using the "export" file.
|
||||||
|
|
||||||
|
GPIO signals have paths like /sys/class/gpio/gpio42/ (for GPIO #42)
|
||||||
|
and have the following read/write attributes:
|
||||||
|
|
||||||
|
/sys/class/gpio/gpioN/
|
||||||
|
|
||||||
|
"direction" ... reads as either "in" or "out". This value may
|
||||||
|
normally be written. Writing as "out" defaults to
|
||||||
|
initializing the value as low. To ensure glitch free
|
||||||
|
operation, values "low" and "high" may be written to
|
||||||
|
configure the GPIO as an output with that initial value.
|
||||||
|
|
||||||
|
Note that this attribute *will not exist* if the kernel
|
||||||
|
doesn't support changing the direction of a GPIO, or
|
||||||
|
it was exported by kernel code that didn't explicitly
|
||||||
|
allow userspace to reconfigure this GPIO's direction.
|
||||||
|
|
||||||
|
"value" ... reads as either 0 (low) or 1 (high). If the GPIO
|
||||||
|
is configured as an output, this value may be written;
|
||||||
|
any nonzero value is treated as high.
|
||||||
|
|
||||||
|
If the pin can be configured as interrupt-generating interrupt
|
||||||
|
and if it has been configured to generate interrupts (see the
|
||||||
|
description of "edge"), you can poll(2) on that file and
|
||||||
|
poll(2) will return whenever the interrupt was triggered. If
|
||||||
|
you use poll(2), set the events POLLPRI and POLLERR. If you
|
||||||
|
use select(2), set the file descriptor in exceptfds. After
|
||||||
|
poll(2) returns, either lseek(2) to the beginning of the sysfs
|
||||||
|
file and read the new value or close the file and re-open it
|
||||||
|
to read the value.
|
||||||
|
|
||||||
|
"edge" ... reads as either "none", "rising", "falling", or
|
||||||
|
"both". Write these strings to select the signal edge(s)
|
||||||
|
that will make poll(2) on the "value" file return.
|
||||||
|
|
||||||
|
This file exists only if the pin can be configured as an
|
||||||
|
interrupt generating input pin.
|
||||||
|
|
||||||
|
"active_low" ... reads as either 0 (false) or 1 (true). Write
|
||||||
|
any nonzero value to invert the value attribute both
|
||||||
|
for reading and writing. Existing and subsequent
|
||||||
|
poll(2) support configuration via the edge attribute
|
||||||
|
for "rising" and "falling" edges will follow this
|
||||||
|
setting.
|
||||||
|
|
||||||
|
GPIO controllers have paths like /sys/class/gpio/gpiochip42/ (for the
|
||||||
|
controller implementing GPIOs starting at #42) and have the following
|
||||||
|
read-only attributes:
|
||||||
|
|
||||||
|
/sys/class/gpio/gpiochipN/
|
||||||
|
|
||||||
|
"base" ... same as N, the first GPIO managed by this chip
|
||||||
|
|
||||||
|
"label" ... provided for diagnostics (not always unique)
|
||||||
|
|
||||||
|
"ngpio" ... how many GPIOs this manges (N to N + ngpio - 1)
|
||||||
|
|
||||||
|
Board documentation should in most cases cover what GPIOs are used for
|
||||||
|
what purposes. However, those numbers are not always stable; GPIOs on
|
||||||
|
a daughtercard might be different depending on the base board being used,
|
||||||
|
or other cards in the stack. In such cases, you may need to use the
|
||||||
|
gpiochip nodes (possibly in conjunction with schematics) to determine
|
||||||
|
the correct GPIO number to use for a given signal.
|
||||||
|
|
||||||
|
|
||||||
|
Exporting from Kernel code
|
||||||
|
--------------------------
|
||||||
|
Kernel code can explicitly manage exports of GPIOs which have already been
|
||||||
|
requested using gpio_request():
|
||||||
|
|
||||||
|
/* export the GPIO to userspace */
|
||||||
|
int gpiod_export(struct gpio_desc *desc, bool direction_may_change);
|
||||||
|
|
||||||
|
/* reverse gpio_export() */
|
||||||
|
void gpiod_unexport(struct gpio_desc *desc);
|
||||||
|
|
||||||
|
/* create a sysfs link to an exported GPIO node */
|
||||||
|
int gpiod_export_link(struct device *dev, const char *name,
|
||||||
|
struct gpio_desc *desc);
|
||||||
|
|
||||||
|
/* change the polarity of a GPIO node in sysfs */
|
||||||
|
int gpiod_sysfs_set_active_low(struct gpio_desc *desc, int value);
|
||||||
|
|
||||||
|
After a kernel driver requests a GPIO, it may only be made available in
|
||||||
|
the sysfs interface by gpiod_export(). The driver can control whether the
|
||||||
|
signal direction may change. This helps drivers prevent userspace code
|
||||||
|
from accidentally clobbering important system state.
|
||||||
|
|
||||||
|
This explicit exporting can help with debugging (by making some kinds
|
||||||
|
of experiments easier), or can provide an always-there interface that's
|
||||||
|
suitable for documenting as part of a board support package.
|
||||||
|
|
||||||
|
After the GPIO has been exported, gpiod_export_link() allows creating
|
||||||
|
symlinks from elsewhere in sysfs to the GPIO sysfs node. Drivers can
|
||||||
|
use this to provide the interface under their own device in sysfs with
|
||||||
|
a descriptive name.
|
||||||
|
|
||||||
|
Drivers can use gpiod_sysfs_set_active_low() to hide GPIO line polarity
|
||||||
|
differences between boards from user space. Polarity change can be done both
|
||||||
|
before and after gpiod_export(), and previously enabled poll(2) support for
|
||||||
|
either rising or falling edge will be reconfigured to follow this setting.
|
@ -1190,15 +1190,24 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
|
|||||||
owned by uid=0.
|
owned by uid=0.
|
||||||
|
|
||||||
ima_hash= [IMA]
|
ima_hash= [IMA]
|
||||||
Format: { "sha1" | "md5" }
|
Format: { md5 | sha1 | rmd160 | sha256 | sha384
|
||||||
|
| sha512 | ... }
|
||||||
default: "sha1"
|
default: "sha1"
|
||||||
|
|
||||||
|
The list of supported hash algorithms is defined
|
||||||
|
in crypto/hash_info.h.
|
||||||
|
|
||||||
ima_tcb [IMA]
|
ima_tcb [IMA]
|
||||||
Load a policy which meets the needs of the Trusted
|
Load a policy which meets the needs of the Trusted
|
||||||
Computing Base. This means IMA will measure all
|
Computing Base. This means IMA will measure all
|
||||||
programs exec'd, files mmap'd for exec, and all files
|
programs exec'd, files mmap'd for exec, and all files
|
||||||
opened for read by uid=0.
|
opened for read by uid=0.
|
||||||
|
|
||||||
|
ima_template= [IMA]
|
||||||
|
Select one of defined IMA measurements template formats.
|
||||||
|
Formats: { "ima" | "ima-ng" }
|
||||||
|
Default: "ima-ng"
|
||||||
|
|
||||||
init= [KNL]
|
init= [KNL]
|
||||||
Format: <full_path>
|
Format: <full_path>
|
||||||
Run specified binary instead of /sbin/init as init
|
Run specified binary instead of /sbin/init as init
|
||||||
|
@ -313,7 +313,7 @@ static struct mic_device_desc *get_device_desc(struct mic_info *mic, int type)
|
|||||||
int i;
|
int i;
|
||||||
void *dp = get_dp(mic, type);
|
void *dp = get_dp(mic, type);
|
||||||
|
|
||||||
for (i = mic_aligned_size(struct mic_bootparam); i < PAGE_SIZE;
|
for (i = sizeof(struct mic_bootparam); i < PAGE_SIZE;
|
||||||
i += mic_total_desc_size(d)) {
|
i += mic_total_desc_size(d)) {
|
||||||
d = dp + i;
|
d = dp + i;
|
||||||
|
|
||||||
@ -445,8 +445,8 @@ init_vr(struct mic_info *mic, int fd, int type,
|
|||||||
__func__, mic->name, vr0->va, vr0->info, vr_size,
|
__func__, mic->name, vr0->va, vr0->info, vr_size,
|
||||||
vring_size(MIC_VRING_ENTRIES, MIC_VIRTIO_RING_ALIGN));
|
vring_size(MIC_VRING_ENTRIES, MIC_VIRTIO_RING_ALIGN));
|
||||||
mpsslog("magic 0x%x expected 0x%x\n",
|
mpsslog("magic 0x%x expected 0x%x\n",
|
||||||
vr0->info->magic, MIC_MAGIC + type);
|
le32toh(vr0->info->magic), MIC_MAGIC + type);
|
||||||
assert(vr0->info->magic == MIC_MAGIC + type);
|
assert(le32toh(vr0->info->magic) == MIC_MAGIC + type);
|
||||||
if (vr1) {
|
if (vr1) {
|
||||||
vr1->va = (struct mic_vring *)
|
vr1->va = (struct mic_vring *)
|
||||||
&va[MIC_DEVICE_PAGE_END + vr_size];
|
&va[MIC_DEVICE_PAGE_END + vr_size];
|
||||||
@ -458,8 +458,8 @@ init_vr(struct mic_info *mic, int fd, int type,
|
|||||||
__func__, mic->name, vr1->va, vr1->info, vr_size,
|
__func__, mic->name, vr1->va, vr1->info, vr_size,
|
||||||
vring_size(MIC_VRING_ENTRIES, MIC_VIRTIO_RING_ALIGN));
|
vring_size(MIC_VRING_ENTRIES, MIC_VIRTIO_RING_ALIGN));
|
||||||
mpsslog("magic 0x%x expected 0x%x\n",
|
mpsslog("magic 0x%x expected 0x%x\n",
|
||||||
vr1->info->magic, MIC_MAGIC + type + 1);
|
le32toh(vr1->info->magic), MIC_MAGIC + type + 1);
|
||||||
assert(vr1->info->magic == MIC_MAGIC + type + 1);
|
assert(le32toh(vr1->info->magic) == MIC_MAGIC + type + 1);
|
||||||
}
|
}
|
||||||
done:
|
done:
|
||||||
return va;
|
return va;
|
||||||
@ -520,7 +520,7 @@ static void *
|
|||||||
virtio_net(void *arg)
|
virtio_net(void *arg)
|
||||||
{
|
{
|
||||||
static __u8 vnet_hdr[2][sizeof(struct virtio_net_hdr)];
|
static __u8 vnet_hdr[2][sizeof(struct virtio_net_hdr)];
|
||||||
static __u8 vnet_buf[2][MAX_NET_PKT_SIZE] __aligned(64);
|
static __u8 vnet_buf[2][MAX_NET_PKT_SIZE] __attribute__ ((aligned(64)));
|
||||||
struct iovec vnet_iov[2][2] = {
|
struct iovec vnet_iov[2][2] = {
|
||||||
{ { .iov_base = vnet_hdr[0], .iov_len = sizeof(vnet_hdr[0]) },
|
{ { .iov_base = vnet_hdr[0], .iov_len = sizeof(vnet_hdr[0]) },
|
||||||
{ .iov_base = vnet_buf[0], .iov_len = sizeof(vnet_buf[0]) } },
|
{ .iov_base = vnet_buf[0], .iov_len = sizeof(vnet_buf[0]) } },
|
||||||
@ -1412,6 +1412,12 @@ mic_config(void *arg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
do {
|
do {
|
||||||
|
ret = lseek(fd, 0, SEEK_SET);
|
||||||
|
if (ret < 0) {
|
||||||
|
mpsslog("%s: Failed to seek to file start '%s': %s\n",
|
||||||
|
mic->name, pathname, strerror(errno));
|
||||||
|
goto close_error1;
|
||||||
|
}
|
||||||
ret = read(fd, value, sizeof(value));
|
ret = read(fd, value, sizeof(value));
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
mpsslog("%s: Failed to read sysfs entry '%s': %s\n",
|
mpsslog("%s: Failed to read sysfs entry '%s': %s\n",
|
||||||
|
@ -577,9 +577,6 @@ tcp_limit_output_bytes - INTEGER
|
|||||||
typical pfifo_fast qdiscs.
|
typical pfifo_fast qdiscs.
|
||||||
tcp_limit_output_bytes limits the number of bytes on qdisc
|
tcp_limit_output_bytes limits the number of bytes on qdisc
|
||||||
or device to reduce artificial RTT/cwnd and reduce bufferbloat.
|
or device to reduce artificial RTT/cwnd and reduce bufferbloat.
|
||||||
Note: For GSO/TSO enabled flows, we try to have at least two
|
|
||||||
packets in flight. Reducing tcp_limit_output_bytes might also
|
|
||||||
reduce the size of individual GSO packet (64KB being the max)
|
|
||||||
Default: 131072
|
Default: 131072
|
||||||
|
|
||||||
tcp_challenge_ack_limit - INTEGER
|
tcp_challenge_ack_limit - INTEGER
|
||||||
|
@ -123,6 +123,16 @@ Transmission process is similar to capture as shown below.
|
|||||||
[shutdown] close() --------> destruction of the transmission socket and
|
[shutdown] close() --------> destruction of the transmission socket and
|
||||||
deallocation of all associated resources.
|
deallocation of all associated resources.
|
||||||
|
|
||||||
|
Socket creation and destruction is also straight forward, and is done
|
||||||
|
the same way as in capturing described in the previous paragraph:
|
||||||
|
|
||||||
|
int fd = socket(PF_PACKET, mode, 0);
|
||||||
|
|
||||||
|
The protocol can optionally be 0 in case we only want to transmit
|
||||||
|
via this socket, which avoids an expensive call to packet_rcv().
|
||||||
|
In this case, you also need to bind(2) the TX_RING with sll_protocol = 0
|
||||||
|
set. Otherwise, htons(ETH_P_ALL) or any other protocol, for example.
|
||||||
|
|
||||||
Binding the socket to your network interface is mandatory (with zero copy) to
|
Binding the socket to your network interface is mandatory (with zero copy) to
|
||||||
know the header size of frames used in the circular buffer.
|
know the header size of frames used in the circular buffer.
|
||||||
|
|
||||||
|
@ -547,13 +547,11 @@ helper functions described in Section 4. In that case, pm_runtime_resume()
|
|||||||
should be used. Of course, for this purpose the device's runtime PM has to be
|
should be used. Of course, for this purpose the device's runtime PM has to be
|
||||||
enabled earlier by calling pm_runtime_enable().
|
enabled earlier by calling pm_runtime_enable().
|
||||||
|
|
||||||
If the device bus type's or driver's ->probe() callback runs
|
It may be desirable to suspend the device once ->probe() has finished.
|
||||||
pm_runtime_suspend() or pm_runtime_idle() or their asynchronous counterparts,
|
Therefore the driver core uses the asyncronous pm_request_idle() to submit a
|
||||||
they will fail returning -EAGAIN, because the device's usage counter is
|
request to execute the subsystem-level idle callback for the device at that
|
||||||
incremented by the driver core before executing ->probe(). Still, it may be
|
time. A driver that makes use of the runtime autosuspend feature, may want to
|
||||||
desirable to suspend the device as soon as ->probe() has finished, so the driver
|
update the last busy mark before returning from ->probe().
|
||||||
core uses pm_runtime_put_sync() to invoke the subsystem-level idle callback for
|
|
||||||
the device at that time.
|
|
||||||
|
|
||||||
Moreover, the driver core prevents runtime PM callbacks from racing with the bus
|
Moreover, the driver core prevents runtime PM callbacks from racing with the bus
|
||||||
notifier callback in __device_release_driver(), which is necessary, because the
|
notifier callback in __device_release_driver(), which is necessary, because the
|
||||||
@ -656,7 +654,7 @@ out the following operations:
|
|||||||
__pm_runtime_disable() with 'false' as the second argument for every device
|
__pm_runtime_disable() with 'false' as the second argument for every device
|
||||||
right before executing the subsystem-level .suspend_late() callback for it.
|
right before executing the subsystem-level .suspend_late() callback for it.
|
||||||
|
|
||||||
* During system resume it calls pm_runtime_enable() and pm_runtime_put_sync()
|
* During system resume it calls pm_runtime_enable() and pm_runtime_put()
|
||||||
for every device right after executing the subsystem-level .resume_early()
|
for every device right after executing the subsystem-level .resume_early()
|
||||||
callback and right after executing the subsystem-level .resume() callback
|
callback and right after executing the subsystem-level .resume() callback
|
||||||
for it, respectively.
|
for it, respectively.
|
||||||
|
@ -22,3 +22,5 @@ keys.txt
|
|||||||
- description of the kernel key retention service.
|
- description of the kernel key retention service.
|
||||||
tomoyo.txt
|
tomoyo.txt
|
||||||
- documentation on the TOMOYO Linux Security Module.
|
- documentation on the TOMOYO Linux Security Module.
|
||||||
|
IMA-templates.txt
|
||||||
|
- documentation on the template management mechanism for IMA.
|
||||||
|
87
Documentation/security/IMA-templates.txt
Normal file
87
Documentation/security/IMA-templates.txt
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
IMA Template Management Mechanism
|
||||||
|
|
||||||
|
|
||||||
|
==== INTRODUCTION ====
|
||||||
|
|
||||||
|
The original 'ima' template is fixed length, containing the filedata hash
|
||||||
|
and pathname. The filedata hash is limited to 20 bytes (md5/sha1).
|
||||||
|
The pathname is a null terminated string, limited to 255 characters.
|
||||||
|
To overcome these limitations and to add additional file metadata, it is
|
||||||
|
necessary to extend the current version of IMA by defining additional
|
||||||
|
templates. For example, information that could be possibly reported are
|
||||||
|
the inode UID/GID or the LSM labels either of the inode and of the process
|
||||||
|
that is accessing it.
|
||||||
|
|
||||||
|
However, the main problem to introduce this feature is that, each time
|
||||||
|
a new template is defined, the functions that generate and display
|
||||||
|
the measurements list would include the code for handling a new format
|
||||||
|
and, thus, would significantly grow over the time.
|
||||||
|
|
||||||
|
The proposed solution solves this problem by separating the template
|
||||||
|
management from the remaining IMA code. The core of this solution is the
|
||||||
|
definition of two new data structures: a template descriptor, to determine
|
||||||
|
which information should be included in the measurement list; a template
|
||||||
|
field, to generate and display data of a given type.
|
||||||
|
|
||||||
|
Managing templates with these structures is very simple. To support
|
||||||
|
a new data type, developers define the field identifier and implement
|
||||||
|
two functions, init() and show(), respectively to generate and display
|
||||||
|
measurement entries. Defining a new template descriptor requires
|
||||||
|
specifying the template format, a string of field identifiers separated
|
||||||
|
by the '|' character. While in the current implementation it is possible
|
||||||
|
to define new template descriptors only by adding their definition in the
|
||||||
|
template specific code (ima_template.c), in a future version it will be
|
||||||
|
possible to register a new template on a running kernel by supplying to IMA
|
||||||
|
the desired format string. In this version, IMA initializes at boot time
|
||||||
|
all defined template descriptors by translating the format into an array
|
||||||
|
of template fields structures taken from the set of the supported ones.
|
||||||
|
|
||||||
|
After the initialization step, IMA will call ima_alloc_init_template()
|
||||||
|
(new function defined within the patches for the new template management
|
||||||
|
mechanism) to generate a new measurement entry by using the template
|
||||||
|
descriptor chosen through the kernel configuration or through the newly
|
||||||
|
introduced 'ima_template=' kernel command line parameter. It is during this
|
||||||
|
phase that the advantages of the new architecture are clearly shown:
|
||||||
|
the latter function will not contain specific code to handle a given template
|
||||||
|
but, instead, it simply calls the init() method of the template fields
|
||||||
|
associated to the chosen template descriptor and store the result (pointer
|
||||||
|
to allocated data and data length) in the measurement entry structure.
|
||||||
|
|
||||||
|
The same mechanism is employed to display measurements entries.
|
||||||
|
The functions ima[_ascii]_measurements_show() retrieve, for each entry,
|
||||||
|
the template descriptor used to produce that entry and call the show()
|
||||||
|
method for each item of the array of template fields structures.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
==== SUPPORTED TEMPLATE FIELDS AND DESCRIPTORS ====
|
||||||
|
|
||||||
|
In the following, there is the list of supported template fields
|
||||||
|
('<identifier>': description), that can be used to define new template
|
||||||
|
descriptors by adding their identifier to the format string
|
||||||
|
(support for more data types will be added later):
|
||||||
|
|
||||||
|
- 'd': the digest of the event (i.e. the digest of a measured file),
|
||||||
|
calculated with the SHA1 or MD5 hash algorithm;
|
||||||
|
- 'n': the name of the event (i.e. the file name), with size up to 255 bytes;
|
||||||
|
- 'd-ng': the digest of the event, calculated with an arbitrary hash
|
||||||
|
algorithm (field format: [<hash algo>:]digest, where the digest
|
||||||
|
prefix is shown only if the hash algorithm is not SHA1 or MD5);
|
||||||
|
- 'n-ng': the name of the event, without size limitations.
|
||||||
|
|
||||||
|
|
||||||
|
Below, there is the list of defined template descriptors:
|
||||||
|
- "ima": its format is 'd|n';
|
||||||
|
- "ima-ng" (default): its format is 'd-ng|n-ng'.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
==== USE ====
|
||||||
|
|
||||||
|
To specify the template descriptor to be used to generate measurement entries,
|
||||||
|
currently the following methods are supported:
|
||||||
|
|
||||||
|
- select a template descriptor among those supported in the kernel
|
||||||
|
configuration ('ima-ng' is the default choice);
|
||||||
|
- specify a template descriptor name from the kernel command line through
|
||||||
|
the 'ima_template=' parameter.
|
@ -865,15 +865,14 @@ encountered:
|
|||||||
calling processes has a searchable link to the key from one of its
|
calling processes has a searchable link to the key from one of its
|
||||||
keyrings. There are three functions for dealing with these:
|
keyrings. There are three functions for dealing with these:
|
||||||
|
|
||||||
key_ref_t make_key_ref(const struct key *key,
|
key_ref_t make_key_ref(const struct key *key, bool possession);
|
||||||
unsigned long possession);
|
|
||||||
|
|
||||||
struct key *key_ref_to_ptr(const key_ref_t key_ref);
|
struct key *key_ref_to_ptr(const key_ref_t key_ref);
|
||||||
|
|
||||||
unsigned long is_key_possessed(const key_ref_t key_ref);
|
bool is_key_possessed(const key_ref_t key_ref);
|
||||||
|
|
||||||
The first function constructs a key reference from a key pointer and
|
The first function constructs a key reference from a key pointer and
|
||||||
possession information (which must be 0 or 1 and not any other value).
|
possession information (which must be true or false).
|
||||||
|
|
||||||
The second function retrieves the key pointer from a reference and the
|
The second function retrieves the key pointer from a reference and the
|
||||||
third retrieves the possession flag.
|
third retrieves the possession flag.
|
||||||
@ -961,14 +960,17 @@ payload contents" for more information.
|
|||||||
the argument will not be parsed.
|
the argument will not be parsed.
|
||||||
|
|
||||||
|
|
||||||
(*) Extra references can be made to a key by calling the following function:
|
(*) Extra references can be made to a key by calling one of the following
|
||||||
|
functions:
|
||||||
|
|
||||||
|
struct key *__key_get(struct key *key);
|
||||||
struct key *key_get(struct key *key);
|
struct key *key_get(struct key *key);
|
||||||
|
|
||||||
These need to be disposed of by calling key_put() when they've been
|
Keys so references will need to be disposed of by calling key_put() when
|
||||||
finished with. The key pointer passed in will be returned. If the pointer
|
they've been finished with. The key pointer passed in will be returned.
|
||||||
is NULL or CONFIG_KEYS is not set then the key will not be dereferenced and
|
|
||||||
no increment will take place.
|
In the case of key_get(), if the pointer is NULL or CONFIG_KEYS is not set
|
||||||
|
then the key will not be dereferenced and no increment will take place.
|
||||||
|
|
||||||
|
|
||||||
(*) A key's serial number can be obtained by calling:
|
(*) A key's serial number can be obtained by calling:
|
||||||
|
@ -440,15 +440,15 @@ def tcm_mod_build_configfs(proto_ident, fabric_mod_dir_var, fabric_mod_name):
|
|||||||
buf += " /*\n"
|
buf += " /*\n"
|
||||||
buf += " * Setup default attribute lists for various fabric->tf_cit_tmpl\n"
|
buf += " * Setup default attribute lists for various fabric->tf_cit_tmpl\n"
|
||||||
buf += " */\n"
|
buf += " */\n"
|
||||||
buf += " TF_CIT_TMPL(fabric)->tfc_wwn_cit.ct_attrs = " + fabric_mod_name + "_wwn_attrs;\n"
|
buf += " fabric->tf_cit_tmpl.tfc_wwn_cit.ct_attrs = " + fabric_mod_name + "_wwn_attrs;\n"
|
||||||
buf += " TF_CIT_TMPL(fabric)->tfc_tpg_base_cit.ct_attrs = NULL;\n"
|
buf += " fabric->tf_cit_tmpl.tfc_tpg_base_cit.ct_attrs = NULL;\n"
|
||||||
buf += " TF_CIT_TMPL(fabric)->tfc_tpg_attrib_cit.ct_attrs = NULL;\n"
|
buf += " fabric->tf_cit_tmpl.tfc_tpg_attrib_cit.ct_attrs = NULL;\n"
|
||||||
buf += " TF_CIT_TMPL(fabric)->tfc_tpg_param_cit.ct_attrs = NULL;\n"
|
buf += " fabric->tf_cit_tmpl.tfc_tpg_param_cit.ct_attrs = NULL;\n"
|
||||||
buf += " TF_CIT_TMPL(fabric)->tfc_tpg_np_base_cit.ct_attrs = NULL;\n"
|
buf += " fabric->tf_cit_tmpl.tfc_tpg_np_base_cit.ct_attrs = NULL;\n"
|
||||||
buf += " TF_CIT_TMPL(fabric)->tfc_tpg_nacl_base_cit.ct_attrs = NULL;\n"
|
buf += " fabric->tf_cit_tmpl.tfc_tpg_nacl_base_cit.ct_attrs = NULL;\n"
|
||||||
buf += " TF_CIT_TMPL(fabric)->tfc_tpg_nacl_attrib_cit.ct_attrs = NULL;\n"
|
buf += " fabric->tf_cit_tmpl.tfc_tpg_nacl_attrib_cit.ct_attrs = NULL;\n"
|
||||||
buf += " TF_CIT_TMPL(fabric)->tfc_tpg_nacl_auth_cit.ct_attrs = NULL;\n"
|
buf += " fabric->tf_cit_tmpl.tfc_tpg_nacl_auth_cit.ct_attrs = NULL;\n"
|
||||||
buf += " TF_CIT_TMPL(fabric)->tfc_tpg_nacl_param_cit.ct_attrs = NULL;\n"
|
buf += " fabric->tf_cit_tmpl.tfc_tpg_nacl_param_cit.ct_attrs = NULL;\n"
|
||||||
buf += " /*\n"
|
buf += " /*\n"
|
||||||
buf += " * Register the fabric for use within TCM\n"
|
buf += " * Register the fabric for use within TCM\n"
|
||||||
buf += " */\n"
|
buf += " */\n"
|
||||||
|
@ -63,9 +63,9 @@ levels.
|
|||||||
PMD split lock enabling requires pgtable_pmd_page_ctor() call on PMD table
|
PMD split lock enabling requires pgtable_pmd_page_ctor() call on PMD table
|
||||||
allocation and pgtable_pmd_page_dtor() on freeing.
|
allocation and pgtable_pmd_page_dtor() on freeing.
|
||||||
|
|
||||||
Allocation usually happens in pmd_alloc_one(), freeing in pmd_free(), but
|
Allocation usually happens in pmd_alloc_one(), freeing in pmd_free() and
|
||||||
make sure you cover all PMD table allocation / freeing paths: i.e X86_PAE
|
pmd_free_tlb(), but make sure you cover all PMD table allocation / freeing
|
||||||
preallocate few PMDs on pgd_alloc().
|
paths: i.e X86_PAE preallocate few PMDs on pgd_alloc().
|
||||||
|
|
||||||
With everything in place you can set CONFIG_ARCH_ENABLE_SPLIT_PMD_PTLOCK.
|
With everything in place you can set CONFIG_ARCH_ENABLE_SPLIT_PMD_PTLOCK.
|
||||||
|
|
||||||
|
99
MAINTAINERS
99
MAINTAINERS
@ -893,19 +893,14 @@ F: arch/arm/include/asm/hardware/dec21285.h
|
|||||||
F: arch/arm/mach-footbridge/
|
F: arch/arm/mach-footbridge/
|
||||||
|
|
||||||
ARM/FREESCALE IMX / MXC ARM ARCHITECTURE
|
ARM/FREESCALE IMX / MXC ARM ARCHITECTURE
|
||||||
|
M: Shawn Guo <shawn.guo@linaro.org>
|
||||||
M: Sascha Hauer <kernel@pengutronix.de>
|
M: Sascha Hauer <kernel@pengutronix.de>
|
||||||
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
|
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
|
||||||
S: Maintained
|
S: Maintained
|
||||||
T: git git://git.pengutronix.de/git/imx/linux-2.6.git
|
|
||||||
F: arch/arm/mach-imx/
|
|
||||||
F: arch/arm/configs/imx*_defconfig
|
|
||||||
|
|
||||||
ARM/FREESCALE IMX6
|
|
||||||
M: Shawn Guo <shawn.guo@linaro.org>
|
|
||||||
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
|
|
||||||
S: Maintained
|
|
||||||
T: git git://git.linaro.org/people/shawnguo/linux-2.6.git
|
T: git git://git.linaro.org/people/shawnguo/linux-2.6.git
|
||||||
F: arch/arm/mach-imx/*imx6*
|
F: arch/arm/mach-imx/
|
||||||
|
F: arch/arm/boot/dts/imx*
|
||||||
|
F: arch/arm/configs/imx*_defconfig
|
||||||
|
|
||||||
ARM/FREESCALE MXS ARM ARCHITECTURE
|
ARM/FREESCALE MXS ARM ARCHITECTURE
|
||||||
M: Shawn Guo <shawn.guo@linaro.org>
|
M: Shawn Guo <shawn.guo@linaro.org>
|
||||||
@ -1934,7 +1929,8 @@ S: Maintained
|
|||||||
F: drivers/gpio/gpio-bt8xx.c
|
F: drivers/gpio/gpio-bt8xx.c
|
||||||
|
|
||||||
BTRFS FILE SYSTEM
|
BTRFS FILE SYSTEM
|
||||||
M: Chris Mason <chris.mason@fusionio.com>
|
M: Chris Mason <clm@fb.com>
|
||||||
|
M: Josef Bacik <jbacik@fb.com>
|
||||||
L: linux-btrfs@vger.kernel.org
|
L: linux-btrfs@vger.kernel.org
|
||||||
W: http://btrfs.wiki.kernel.org/
|
W: http://btrfs.wiki.kernel.org/
|
||||||
Q: http://patchwork.kernel.org/project/linux-btrfs/list/
|
Q: http://patchwork.kernel.org/project/linux-btrfs/list/
|
||||||
@ -2137,11 +2133,17 @@ S: Maintained
|
|||||||
F: Documentation/zh_CN/
|
F: Documentation/zh_CN/
|
||||||
|
|
||||||
CHIPIDEA USB HIGH SPEED DUAL ROLE CONTROLLER
|
CHIPIDEA USB HIGH SPEED DUAL ROLE CONTROLLER
|
||||||
M: Alexander Shishkin <alexander.shishkin@linux.intel.com>
|
M: Peter Chen <Peter.Chen@freescale.com>
|
||||||
|
T: git://github.com/hzpeterchen/linux-usb.git
|
||||||
L: linux-usb@vger.kernel.org
|
L: linux-usb@vger.kernel.org
|
||||||
S: Maintained
|
S: Maintained
|
||||||
F: drivers/usb/chipidea/
|
F: drivers/usb/chipidea/
|
||||||
|
|
||||||
|
CHROME HARDWARE PLATFORM SUPPORT
|
||||||
|
M: Olof Johansson <olof@lixom.net>
|
||||||
|
S: Maintained
|
||||||
|
F: drivers/platform/chrome/
|
||||||
|
|
||||||
CISCO VIC ETHERNET NIC DRIVER
|
CISCO VIC ETHERNET NIC DRIVER
|
||||||
M: Christian Benvenuti <benve@cisco.com>
|
M: Christian Benvenuti <benve@cisco.com>
|
||||||
M: Sujith Sankar <ssujith@cisco.com>
|
M: Sujith Sankar <ssujith@cisco.com>
|
||||||
@ -2468,7 +2470,7 @@ S: Maintained
|
|||||||
F: drivers/media/dvb-frontends/cxd2820r*
|
F: drivers/media/dvb-frontends/cxd2820r*
|
||||||
|
|
||||||
CXGB3 ETHERNET DRIVER (CXGB3)
|
CXGB3 ETHERNET DRIVER (CXGB3)
|
||||||
M: Divy Le Ray <divy@chelsio.com>
|
M: Santosh Raspatur <santosh@chelsio.com>
|
||||||
L: netdev@vger.kernel.org
|
L: netdev@vger.kernel.org
|
||||||
W: http://www.chelsio.com
|
W: http://www.chelsio.com
|
||||||
S: Supported
|
S: Supported
|
||||||
@ -4038,12 +4040,26 @@ W: http://artax.karlin.mff.cuni.cz/~mikulas/vyplody/hpfs/index-e.cgi
|
|||||||
S: Maintained
|
S: Maintained
|
||||||
F: fs/hpfs/
|
F: fs/hpfs/
|
||||||
|
|
||||||
|
HSI SUBSYSTEM
|
||||||
|
M: Sebastian Reichel <sre@debian.org>
|
||||||
|
S: Maintained
|
||||||
|
F: Documentation/ABI/testing/sysfs-bus-hsi
|
||||||
|
F: drivers/hsi/
|
||||||
|
F: include/linux/hsi/
|
||||||
|
F: include/uapi/linux/hsi/
|
||||||
|
|
||||||
HSO 3G MODEM DRIVER
|
HSO 3G MODEM DRIVER
|
||||||
M: Jan Dumon <j.dumon@option.com>
|
M: Jan Dumon <j.dumon@option.com>
|
||||||
W: http://www.pharscape.org
|
W: http://www.pharscape.org
|
||||||
S: Maintained
|
S: Maintained
|
||||||
F: drivers/net/usb/hso.c
|
F: drivers/net/usb/hso.c
|
||||||
|
|
||||||
|
HSR NETWORK PROTOCOL
|
||||||
|
M: Arvid Brodin <arvid.brodin@alten.se>
|
||||||
|
L: netdev@vger.kernel.org
|
||||||
|
S: Maintained
|
||||||
|
F: net/hsr/
|
||||||
|
|
||||||
HTCPEN TOUCHSCREEN DRIVER
|
HTCPEN TOUCHSCREEN DRIVER
|
||||||
M: Pau Oliva Fora <pof@eslack.org>
|
M: Pau Oliva Fora <pof@eslack.org>
|
||||||
L: linux-input@vger.kernel.org
|
L: linux-input@vger.kernel.org
|
||||||
@ -4065,6 +4081,7 @@ F: arch/x86/include/uapi/asm/hyperv.h
|
|||||||
F: arch/x86/kernel/cpu/mshyperv.c
|
F: arch/x86/kernel/cpu/mshyperv.c
|
||||||
F: drivers/hid/hid-hyperv.c
|
F: drivers/hid/hid-hyperv.c
|
||||||
F: drivers/hv/
|
F: drivers/hv/
|
||||||
|
F: drivers/input/serio/hyperv-keyboard.c
|
||||||
F: drivers/net/hyperv/
|
F: drivers/net/hyperv/
|
||||||
F: drivers/scsi/storvsc_drv.c
|
F: drivers/scsi/storvsc_drv.c
|
||||||
F: drivers/video/hyperv_fb.c
|
F: drivers/video/hyperv_fb.c
|
||||||
@ -4449,10 +4466,8 @@ M: Bruce Allan <bruce.w.allan@intel.com>
|
|||||||
M: Carolyn Wyborny <carolyn.wyborny@intel.com>
|
M: Carolyn Wyborny <carolyn.wyborny@intel.com>
|
||||||
M: Don Skidmore <donald.c.skidmore@intel.com>
|
M: Don Skidmore <donald.c.skidmore@intel.com>
|
||||||
M: Greg Rose <gregory.v.rose@intel.com>
|
M: Greg Rose <gregory.v.rose@intel.com>
|
||||||
M: Peter P Waskiewicz Jr <peter.p.waskiewicz.jr@intel.com>
|
|
||||||
M: Alex Duyck <alexander.h.duyck@intel.com>
|
M: Alex Duyck <alexander.h.duyck@intel.com>
|
||||||
M: John Ronciak <john.ronciak@intel.com>
|
M: John Ronciak <john.ronciak@intel.com>
|
||||||
M: Tushar Dave <tushar.n.dave@intel.com>
|
|
||||||
L: e1000-devel@lists.sourceforge.net
|
L: e1000-devel@lists.sourceforge.net
|
||||||
W: http://www.intel.com/support/feedback.htm
|
W: http://www.intel.com/support/feedback.htm
|
||||||
W: http://e1000.sourceforge.net/
|
W: http://e1000.sourceforge.net/
|
||||||
@ -5255,7 +5270,7 @@ S: Maintained
|
|||||||
F: Documentation/lockdep*.txt
|
F: Documentation/lockdep*.txt
|
||||||
F: Documentation/lockstat.txt
|
F: Documentation/lockstat.txt
|
||||||
F: include/linux/lockdep.h
|
F: include/linux/lockdep.h
|
||||||
F: kernel/lockdep*
|
F: kernel/locking/
|
||||||
|
|
||||||
LOGICAL DISK MANAGER SUPPORT (LDM, Windows 2000/XP/Vista Dynamic Disks)
|
LOGICAL DISK MANAGER SUPPORT (LDM, Windows 2000/XP/Vista Dynamic Disks)
|
||||||
M: "Richard Russon (FlatCap)" <ldm@flatcap.org>
|
M: "Richard Russon (FlatCap)" <ldm@flatcap.org>
|
||||||
@ -5967,10 +5982,10 @@ F: drivers/nfc/
|
|||||||
F: include/linux/platform_data/pn544.h
|
F: include/linux/platform_data/pn544.h
|
||||||
|
|
||||||
NFS, SUNRPC, AND LOCKD CLIENTS
|
NFS, SUNRPC, AND LOCKD CLIENTS
|
||||||
M: Trond Myklebust <Trond.Myklebust@netapp.com>
|
M: Trond Myklebust <trond.myklebust@primarydata.com>
|
||||||
L: linux-nfs@vger.kernel.org
|
L: linux-nfs@vger.kernel.org
|
||||||
W: http://client.linux-nfs.org
|
W: http://client.linux-nfs.org
|
||||||
T: git git://git.linux-nfs.org/pub/linux/nfs-2.6.git
|
T: git git://git.linux-nfs.org/projects/trondmy/linux-nfs.git
|
||||||
S: Maintained
|
S: Maintained
|
||||||
F: fs/lockd/
|
F: fs/lockd/
|
||||||
F: fs/nfs/
|
F: fs/nfs/
|
||||||
@ -6237,8 +6252,8 @@ OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS
|
|||||||
M: Rob Herring <rob.herring@calxeda.com>
|
M: Rob Herring <rob.herring@calxeda.com>
|
||||||
M: Pawel Moll <pawel.moll@arm.com>
|
M: Pawel Moll <pawel.moll@arm.com>
|
||||||
M: Mark Rutland <mark.rutland@arm.com>
|
M: Mark Rutland <mark.rutland@arm.com>
|
||||||
M: Stephen Warren <swarren@wwwdotorg.org>
|
|
||||||
M: Ian Campbell <ijc+devicetree@hellion.org.uk>
|
M: Ian Campbell <ijc+devicetree@hellion.org.uk>
|
||||||
|
M: Kumar Gala <galak@codeaurora.org>
|
||||||
L: devicetree@vger.kernel.org
|
L: devicetree@vger.kernel.org
|
||||||
S: Maintained
|
S: Maintained
|
||||||
F: Documentation/devicetree/
|
F: Documentation/devicetree/
|
||||||
@ -6448,19 +6463,52 @@ F: drivers/pci/
|
|||||||
F: include/linux/pci*
|
F: include/linux/pci*
|
||||||
F: arch/x86/pci/
|
F: arch/x86/pci/
|
||||||
|
|
||||||
|
PCI DRIVER FOR IMX6
|
||||||
|
M: Richard Zhu <r65037@freescale.com>
|
||||||
|
M: Shawn Guo <shawn.guo@linaro.org>
|
||||||
|
L: linux-pci@vger.kernel.org
|
||||||
|
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
|
||||||
|
S: Maintained
|
||||||
|
F: drivers/pci/host/*imx6*
|
||||||
|
|
||||||
|
PCI DRIVER FOR MVEBU (Marvell Armada 370 and Armada XP SOC support)
|
||||||
|
M: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
|
||||||
|
M: Jason Cooper <jason@lakedaemon.net>
|
||||||
|
L: linux-pci@vger.kernel.org
|
||||||
|
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
|
||||||
|
S: Maintained
|
||||||
|
F: drivers/pci/host/*mvebu*
|
||||||
|
|
||||||
PCI DRIVER FOR NVIDIA TEGRA
|
PCI DRIVER FOR NVIDIA TEGRA
|
||||||
M: Thierry Reding <thierry.reding@gmail.com>
|
M: Thierry Reding <thierry.reding@gmail.com>
|
||||||
L: linux-tegra@vger.kernel.org
|
L: linux-tegra@vger.kernel.org
|
||||||
|
L: linux-pci@vger.kernel.org
|
||||||
S: Supported
|
S: Supported
|
||||||
F: Documentation/devicetree/bindings/pci/nvidia,tegra20-pcie.txt
|
F: Documentation/devicetree/bindings/pci/nvidia,tegra20-pcie.txt
|
||||||
F: drivers/pci/host/pci-tegra.c
|
F: drivers/pci/host/pci-tegra.c
|
||||||
|
|
||||||
|
PCI DRIVER FOR RENESAS R-CAR
|
||||||
|
M: Simon Horman <horms@verge.net.au>
|
||||||
|
L: linux-pci@vger.kernel.org
|
||||||
|
L: linux-sh@vger.kernel.org
|
||||||
|
S: Maintained
|
||||||
|
F: drivers/pci/host/*rcar*
|
||||||
|
|
||||||
PCI DRIVER FOR SAMSUNG EXYNOS
|
PCI DRIVER FOR SAMSUNG EXYNOS
|
||||||
M: Jingoo Han <jg1.han@samsung.com>
|
M: Jingoo Han <jg1.han@samsung.com>
|
||||||
L: linux-pci@vger.kernel.org
|
L: linux-pci@vger.kernel.org
|
||||||
|
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
|
||||||
|
L: linux-samsung-soc@vger.kernel.org (moderated for non-subscribers)
|
||||||
S: Maintained
|
S: Maintained
|
||||||
F: drivers/pci/host/pci-exynos.c
|
F: drivers/pci/host/pci-exynos.c
|
||||||
|
|
||||||
|
PCI DRIVER FOR SYNOPSIS DESIGNWARE
|
||||||
|
M: Mohit Kumar <mohit.kumar@st.com>
|
||||||
|
M: Jingoo Han <jg1.han@samsung.com>
|
||||||
|
L: linux-pci@vger.kernel.org
|
||||||
|
S: Maintained
|
||||||
|
F: drivers/pci/host/*designware*
|
||||||
|
|
||||||
PCMCIA SUBSYSTEM
|
PCMCIA SUBSYSTEM
|
||||||
P: Linux PCMCIA Team
|
P: Linux PCMCIA Team
|
||||||
L: linux-pcmcia@lists.infradead.org
|
L: linux-pcmcia@lists.infradead.org
|
||||||
@ -7379,7 +7427,6 @@ S: Maintained
|
|||||||
F: kernel/sched/
|
F: kernel/sched/
|
||||||
F: include/linux/sched.h
|
F: include/linux/sched.h
|
||||||
F: include/uapi/linux/sched.h
|
F: include/uapi/linux/sched.h
|
||||||
F: kernel/wait.c
|
|
||||||
F: include/linux/wait.h
|
F: include/linux/wait.h
|
||||||
|
|
||||||
SCORE ARCHITECTURE
|
SCORE ARCHITECTURE
|
||||||
@ -7515,9 +7562,10 @@ SELINUX SECURITY MODULE
|
|||||||
M: Stephen Smalley <sds@tycho.nsa.gov>
|
M: Stephen Smalley <sds@tycho.nsa.gov>
|
||||||
M: James Morris <james.l.morris@oracle.com>
|
M: James Morris <james.l.morris@oracle.com>
|
||||||
M: Eric Paris <eparis@parisplace.org>
|
M: Eric Paris <eparis@parisplace.org>
|
||||||
|
M: Paul Moore <paul@paul-moore.com>
|
||||||
L: selinux@tycho.nsa.gov (subscribers-only, general discussion)
|
L: selinux@tycho.nsa.gov (subscribers-only, general discussion)
|
||||||
W: http://selinuxproject.org
|
W: http://selinuxproject.org
|
||||||
T: git git://git.infradead.org/users/eparis/selinux.git
|
T: git git://git.infradead.org/users/pcmoore/selinux
|
||||||
S: Supported
|
S: Supported
|
||||||
F: include/linux/selinux*
|
F: include/linux/selinux*
|
||||||
F: security/selinux/
|
F: security/selinux/
|
||||||
@ -8664,6 +8712,7 @@ F: drivers/media/usb/tm6000/
|
|||||||
TPM DEVICE DRIVER
|
TPM DEVICE DRIVER
|
||||||
M: Leonidas Da Silva Barbosa <leosilva@linux.vnet.ibm.com>
|
M: Leonidas Da Silva Barbosa <leosilva@linux.vnet.ibm.com>
|
||||||
M: Ashley Lai <ashley@ashleylai.com>
|
M: Ashley Lai <ashley@ashleylai.com>
|
||||||
|
M: Peter Huewe <peterhuewe@gmx.de>
|
||||||
M: Rajiv Andrade <mail@srajiv.net>
|
M: Rajiv Andrade <mail@srajiv.net>
|
||||||
W: http://tpmdd.sourceforge.net
|
W: http://tpmdd.sourceforge.net
|
||||||
M: Marcel Selhorst <tpmdd@selhorst.net>
|
M: Marcel Selhorst <tpmdd@selhorst.net>
|
||||||
@ -8960,8 +9009,8 @@ USB PEGASUS DRIVER
|
|||||||
M: Petko Manolov <petkan@nucleusys.com>
|
M: Petko Manolov <petkan@nucleusys.com>
|
||||||
L: linux-usb@vger.kernel.org
|
L: linux-usb@vger.kernel.org
|
||||||
L: netdev@vger.kernel.org
|
L: netdev@vger.kernel.org
|
||||||
T: git git://git.code.sf.net/p/pegasus2/git
|
T: git git://github.com/petkan/pegasus.git
|
||||||
W: http://pegasus2.sourceforge.net/
|
W: https://github.com/petkan/pegasus
|
||||||
S: Maintained
|
S: Maintained
|
||||||
F: drivers/net/usb/pegasus.*
|
F: drivers/net/usb/pegasus.*
|
||||||
|
|
||||||
@ -8982,8 +9031,8 @@ USB RTL8150 DRIVER
|
|||||||
M: Petko Manolov <petkan@nucleusys.com>
|
M: Petko Manolov <petkan@nucleusys.com>
|
||||||
L: linux-usb@vger.kernel.org
|
L: linux-usb@vger.kernel.org
|
||||||
L: netdev@vger.kernel.org
|
L: netdev@vger.kernel.org
|
||||||
T: git git://git.code.sf.net/p/pegasus2/git
|
T: git git://github.com/petkan/rtl8150.git
|
||||||
W: http://pegasus2.sourceforge.net/
|
W: https://github.com/petkan/rtl8150
|
||||||
S: Maintained
|
S: Maintained
|
||||||
F: drivers/net/usb/rtl8150.c
|
F: drivers/net/usb/rtl8150.c
|
||||||
|
|
||||||
@ -9522,8 +9571,8 @@ F: drivers/xen/*swiotlb*
|
|||||||
|
|
||||||
XFS FILESYSTEM
|
XFS FILESYSTEM
|
||||||
P: Silicon Graphics Inc
|
P: Silicon Graphics Inc
|
||||||
|
M: Dave Chinner <dchinner@fromorbit.com>
|
||||||
M: Ben Myers <bpm@sgi.com>
|
M: Ben Myers <bpm@sgi.com>
|
||||||
M: Alex Elder <elder@kernel.org>
|
|
||||||
M: xfs@oss.sgi.com
|
M: xfs@oss.sgi.com
|
||||||
L: xfs@oss.sgi.com
|
L: xfs@oss.sgi.com
|
||||||
W: http://oss.sgi.com/projects/xfs
|
W: http://oss.sgi.com/projects/xfs
|
||||||
|
4
Makefile
4
Makefile
@ -1,7 +1,7 @@
|
|||||||
VERSION = 3
|
VERSION = 3
|
||||||
PATCHLEVEL = 12
|
PATCHLEVEL = 13
|
||||||
SUBLEVEL = 0
|
SUBLEVEL = 0
|
||||||
EXTRAVERSION =
|
EXTRAVERSION = -rc4
|
||||||
NAME = One Giant Leap for Frogkind
|
NAME = One Giant Leap for Frogkind
|
||||||
|
|
||||||
# *DOCUMENTATION*
|
# *DOCUMENTATION*
|
||||||
|
@ -16,8 +16,8 @@ config ALPHA
|
|||||||
select ARCH_WANT_IPC_PARSE_VERSION
|
select ARCH_WANT_IPC_PARSE_VERSION
|
||||||
select ARCH_HAVE_NMI_SAFE_CMPXCHG
|
select ARCH_HAVE_NMI_SAFE_CMPXCHG
|
||||||
select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE
|
select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE
|
||||||
|
select GENERIC_CLOCKEVENTS
|
||||||
select GENERIC_SMP_IDLE_THREAD
|
select GENERIC_SMP_IDLE_THREAD
|
||||||
select GENERIC_CMOS_UPDATE
|
|
||||||
select GENERIC_STRNCPY_FROM_USER
|
select GENERIC_STRNCPY_FROM_USER
|
||||||
select GENERIC_STRNLEN_USER
|
select GENERIC_STRNLEN_USER
|
||||||
select HAVE_MOD_ARCH_SPECIFIC
|
select HAVE_MOD_ARCH_SPECIFIC
|
||||||
@ -488,6 +488,20 @@ config VGA_HOSE
|
|||||||
which always have multiple hoses, and whose consoles support it.
|
which always have multiple hoses, and whose consoles support it.
|
||||||
|
|
||||||
|
|
||||||
|
config ALPHA_QEMU
|
||||||
|
bool "Run under QEMU emulation"
|
||||||
|
depends on !ALPHA_GENERIC
|
||||||
|
---help---
|
||||||
|
Assume the presence of special features supported by QEMU PALcode
|
||||||
|
that reduce the overhead of system emulation.
|
||||||
|
|
||||||
|
Generic kernels will auto-detect QEMU. But when building a
|
||||||
|
system-specific kernel, the assumption is that we want to
|
||||||
|
elimiate as many runtime tests as possible.
|
||||||
|
|
||||||
|
If unsure, say N.
|
||||||
|
|
||||||
|
|
||||||
config ALPHA_SRM
|
config ALPHA_SRM
|
||||||
bool "Use SRM as bootloader" if ALPHA_CABRIOLET || ALPHA_AVANTI_CH || ALPHA_EB64P || ALPHA_PC164 || ALPHA_TAKARA || ALPHA_EB164 || ALPHA_ALCOR || ALPHA_MIATA || ALPHA_LX164 || ALPHA_SX164 || ALPHA_NAUTILUS || ALPHA_NONAME
|
bool "Use SRM as bootloader" if ALPHA_CABRIOLET || ALPHA_AVANTI_CH || ALPHA_EB64P || ALPHA_PC164 || ALPHA_TAKARA || ALPHA_EB164 || ALPHA_ALCOR || ALPHA_MIATA || ALPHA_LX164 || ALPHA_SX164 || ALPHA_NAUTILUS || ALPHA_NONAME
|
||||||
depends on TTY
|
depends on TTY
|
||||||
@ -572,6 +586,30 @@ config NUMA
|
|||||||
Access). This option is for configuring high-end multiprocessor
|
Access). This option is for configuring high-end multiprocessor
|
||||||
server machines. If in doubt, say N.
|
server machines. If in doubt, say N.
|
||||||
|
|
||||||
|
config ALPHA_WTINT
|
||||||
|
bool "Use WTINT" if ALPHA_SRM || ALPHA_GENERIC
|
||||||
|
default y if ALPHA_QEMU
|
||||||
|
default n if ALPHA_EV5 || ALPHA_EV56 || (ALPHA_EV4 && !ALPHA_LCA)
|
||||||
|
default n if !ALPHA_SRM && !ALPHA_GENERIC
|
||||||
|
default y if SMP
|
||||||
|
---help---
|
||||||
|
The Wait for Interrupt (WTINT) PALcall attempts to place the CPU
|
||||||
|
to sleep until the next interrupt. This may reduce the power
|
||||||
|
consumed, and the heat produced by the computer. However, it has
|
||||||
|
the side effect of making the cycle counter unreliable as a timing
|
||||||
|
device across the sleep.
|
||||||
|
|
||||||
|
For emulation under QEMU, definitely say Y here, as we have other
|
||||||
|
mechanisms for measuring time than the cycle counter.
|
||||||
|
|
||||||
|
For EV4 (but not LCA), EV5 and EV56 systems, or for systems running
|
||||||
|
MILO, sleep mode is not supported so you might as well say N here.
|
||||||
|
|
||||||
|
For SMP systems we cannot use the cycle counter for timing anyway,
|
||||||
|
so you might as well say Y here.
|
||||||
|
|
||||||
|
If unsure, say N.
|
||||||
|
|
||||||
config NODES_SHIFT
|
config NODES_SHIFT
|
||||||
int
|
int
|
||||||
default "7"
|
default "7"
|
||||||
@ -613,9 +651,41 @@ config VERBOSE_MCHECK_ON
|
|||||||
|
|
||||||
Take the default (1) unless you want more control or more info.
|
Take the default (1) unless you want more control or more info.
|
||||||
|
|
||||||
|
choice
|
||||||
|
prompt "Timer interrupt frequency (HZ)?"
|
||||||
|
default HZ_128 if ALPHA_QEMU
|
||||||
|
default HZ_1200 if ALPHA_RAWHIDE
|
||||||
|
default HZ_1024
|
||||||
|
---help---
|
||||||
|
The frequency at which timer interrupts occur. A high frequency
|
||||||
|
minimizes latency, whereas a low frequency minimizes overhead of
|
||||||
|
process accounting. The later effect is especially significant
|
||||||
|
when being run under QEMU.
|
||||||
|
|
||||||
|
Note that some Alpha hardware cannot change the interrupt frequency
|
||||||
|
of the timer. If unsure, say 1024 (or 1200 for Rawhide).
|
||||||
|
|
||||||
|
config HZ_32
|
||||||
|
bool "32 Hz"
|
||||||
|
config HZ_64
|
||||||
|
bool "64 Hz"
|
||||||
|
config HZ_128
|
||||||
|
bool "128 Hz"
|
||||||
|
config HZ_256
|
||||||
|
bool "256 Hz"
|
||||||
|
config HZ_1024
|
||||||
|
bool "1024 Hz"
|
||||||
|
config HZ_1200
|
||||||
|
bool "1200 Hz"
|
||||||
|
endchoice
|
||||||
|
|
||||||
config HZ
|
config HZ
|
||||||
int
|
int
|
||||||
default 1200 if ALPHA_RAWHIDE
|
default 32 if HZ_32
|
||||||
|
default 64 if HZ_64
|
||||||
|
default 128 if HZ_128
|
||||||
|
default 256 if HZ_256
|
||||||
|
default 1200 if HZ_1200
|
||||||
default 1024
|
default 1024
|
||||||
|
|
||||||
source "drivers/pci/Kconfig"
|
source "drivers/pci/Kconfig"
|
||||||
|
@ -33,6 +33,7 @@ struct alpha_machine_vector
|
|||||||
|
|
||||||
int nr_irqs;
|
int nr_irqs;
|
||||||
int rtc_port;
|
int rtc_port;
|
||||||
|
int rtc_boot_cpu_only;
|
||||||
unsigned int max_asn;
|
unsigned int max_asn;
|
||||||
unsigned long max_isa_dma_address;
|
unsigned long max_isa_dma_address;
|
||||||
unsigned long irq_probe_mask;
|
unsigned long irq_probe_mask;
|
||||||
@ -95,9 +96,6 @@ struct alpha_machine_vector
|
|||||||
|
|
||||||
struct _alpha_agp_info *(*agp_info)(void);
|
struct _alpha_agp_info *(*agp_info)(void);
|
||||||
|
|
||||||
unsigned int (*rtc_get_time)(struct rtc_time *);
|
|
||||||
int (*rtc_set_time)(struct rtc_time *);
|
|
||||||
|
|
||||||
const char *vector_name;
|
const char *vector_name;
|
||||||
|
|
||||||
/* NUMA information */
|
/* NUMA information */
|
||||||
@ -126,13 +124,19 @@ extern struct alpha_machine_vector alpha_mv;
|
|||||||
|
|
||||||
#ifdef CONFIG_ALPHA_GENERIC
|
#ifdef CONFIG_ALPHA_GENERIC
|
||||||
extern int alpha_using_srm;
|
extern int alpha_using_srm;
|
||||||
|
extern int alpha_using_qemu;
|
||||||
#else
|
#else
|
||||||
#ifdef CONFIG_ALPHA_SRM
|
# ifdef CONFIG_ALPHA_SRM
|
||||||
#define alpha_using_srm 1
|
# define alpha_using_srm 1
|
||||||
#else
|
# else
|
||||||
#define alpha_using_srm 0
|
# define alpha_using_srm 0
|
||||||
#endif
|
# endif
|
||||||
|
# ifdef CONFIG_ALPHA_QEMU
|
||||||
|
# define alpha_using_qemu 1
|
||||||
|
# else
|
||||||
|
# define alpha_using_qemu 0
|
||||||
|
# endif
|
||||||
#endif /* GENERIC */
|
#endif /* GENERIC */
|
||||||
|
|
||||||
#endif
|
#endif /* __KERNEL__ */
|
||||||
#endif /* __ALPHA_MACHVEC_H */
|
#endif /* __ALPHA_MACHVEC_H */
|
||||||
|
@ -89,6 +89,7 @@ __CALL_PAL_W1(wrmces, unsigned long);
|
|||||||
__CALL_PAL_RW2(wrperfmon, unsigned long, unsigned long, unsigned long);
|
__CALL_PAL_RW2(wrperfmon, unsigned long, unsigned long, unsigned long);
|
||||||
__CALL_PAL_W1(wrusp, unsigned long);
|
__CALL_PAL_W1(wrusp, unsigned long);
|
||||||
__CALL_PAL_W1(wrvptptr, unsigned long);
|
__CALL_PAL_W1(wrvptptr, unsigned long);
|
||||||
|
__CALL_PAL_RW1(wtint, unsigned long, unsigned long);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* TB routines..
|
* TB routines..
|
||||||
@ -111,5 +112,75 @@ __CALL_PAL_W1(wrvptptr, unsigned long);
|
|||||||
#define tbiap() __tbi(-1, /* no second argument */)
|
#define tbiap() __tbi(-1, /* no second argument */)
|
||||||
#define tbia() __tbi(-2, /* no second argument */)
|
#define tbia() __tbi(-2, /* no second argument */)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* QEMU Cserv routines..
|
||||||
|
*/
|
||||||
|
|
||||||
|
static inline unsigned long
|
||||||
|
qemu_get_walltime(void)
|
||||||
|
{
|
||||||
|
register unsigned long v0 __asm__("$0");
|
||||||
|
register unsigned long a0 __asm__("$16") = 3;
|
||||||
|
|
||||||
|
asm("call_pal %2 # cserve get_time"
|
||||||
|
: "=r"(v0), "+r"(a0)
|
||||||
|
: "i"(PAL_cserve)
|
||||||
|
: "$17", "$18", "$19", "$20", "$21");
|
||||||
|
|
||||||
|
return v0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline unsigned long
|
||||||
|
qemu_get_alarm(void)
|
||||||
|
{
|
||||||
|
register unsigned long v0 __asm__("$0");
|
||||||
|
register unsigned long a0 __asm__("$16") = 4;
|
||||||
|
|
||||||
|
asm("call_pal %2 # cserve get_alarm"
|
||||||
|
: "=r"(v0), "+r"(a0)
|
||||||
|
: "i"(PAL_cserve)
|
||||||
|
: "$17", "$18", "$19", "$20", "$21");
|
||||||
|
|
||||||
|
return v0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
qemu_set_alarm_rel(unsigned long expire)
|
||||||
|
{
|
||||||
|
register unsigned long a0 __asm__("$16") = 5;
|
||||||
|
register unsigned long a1 __asm__("$17") = expire;
|
||||||
|
|
||||||
|
asm volatile("call_pal %2 # cserve set_alarm_rel"
|
||||||
|
: "+r"(a0), "+r"(a1)
|
||||||
|
: "i"(PAL_cserve)
|
||||||
|
: "$0", "$18", "$19", "$20", "$21");
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
qemu_set_alarm_abs(unsigned long expire)
|
||||||
|
{
|
||||||
|
register unsigned long a0 __asm__("$16") = 6;
|
||||||
|
register unsigned long a1 __asm__("$17") = expire;
|
||||||
|
|
||||||
|
asm volatile("call_pal %2 # cserve set_alarm_abs"
|
||||||
|
: "+r"(a0), "+r"(a1)
|
||||||
|
: "i"(PAL_cserve)
|
||||||
|
: "$0", "$18", "$19", "$20", "$21");
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline unsigned long
|
||||||
|
qemu_get_vmtime(void)
|
||||||
|
{
|
||||||
|
register unsigned long v0 __asm__("$0");
|
||||||
|
register unsigned long a0 __asm__("$16") = 7;
|
||||||
|
|
||||||
|
asm("call_pal %2 # cserve get_time"
|
||||||
|
: "=r"(v0), "+r"(a0)
|
||||||
|
: "i"(PAL_cserve)
|
||||||
|
: "$17", "$18", "$19", "$20", "$21");
|
||||||
|
|
||||||
|
return v0;
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* !__ASSEMBLY__ */
|
#endif /* !__ASSEMBLY__ */
|
||||||
#endif /* __ALPHA_PAL_H */
|
#endif /* __ALPHA_PAL_H */
|
||||||
|
@ -1,12 +1 @@
|
|||||||
#ifndef _ALPHA_RTC_H
|
|
||||||
#define _ALPHA_RTC_H
|
|
||||||
|
|
||||||
#if defined(CONFIG_ALPHA_MARVEL) && defined(CONFIG_SMP) \
|
|
||||||
|| defined(CONFIG_ALPHA_GENERIC)
|
|
||||||
# define get_rtc_time alpha_mv.rtc_get_time
|
|
||||||
# define set_rtc_time alpha_mv.rtc_set_time
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <asm-generic/rtc.h>
|
#include <asm-generic/rtc.h>
|
||||||
|
|
||||||
#endif
|
|
||||||
|
@ -22,15 +22,27 @@ extern void * __memcpy(void *, const void *, size_t);
|
|||||||
|
|
||||||
#define __HAVE_ARCH_MEMSET
|
#define __HAVE_ARCH_MEMSET
|
||||||
extern void * __constant_c_memset(void *, unsigned long, size_t);
|
extern void * __constant_c_memset(void *, unsigned long, size_t);
|
||||||
|
extern void * ___memset(void *, int, size_t);
|
||||||
extern void * __memset(void *, int, size_t);
|
extern void * __memset(void *, int, size_t);
|
||||||
extern void * memset(void *, int, size_t);
|
extern void * memset(void *, int, size_t);
|
||||||
|
|
||||||
#define memset(s, c, n) \
|
/* For gcc 3.x, we cannot have the inline function named "memset" because
|
||||||
(__builtin_constant_p(c) \
|
the __builtin_memset will attempt to resolve to the inline as well,
|
||||||
? (__builtin_constant_p(n) && (c) == 0 \
|
leading to a "sorry" about unimplemented recursive inlining. */
|
||||||
? __builtin_memset((s),0,(n)) \
|
extern inline void *__memset(void *s, int c, size_t n)
|
||||||
: __constant_c_memset((s),0x0101010101010101UL*(unsigned char)(c),(n))) \
|
{
|
||||||
: __memset((s),(c),(n)))
|
if (__builtin_constant_p(c)) {
|
||||||
|
if (__builtin_constant_p(n)) {
|
||||||
|
return __builtin_memset(s, c, n);
|
||||||
|
} else {
|
||||||
|
unsigned long c8 = (c & 0xff) * 0x0101010101010101UL;
|
||||||
|
return __constant_c_memset(s, c8, n);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ___memset(s, c, n);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define memset __memset
|
||||||
|
|
||||||
#define __HAVE_ARCH_STRCPY
|
#define __HAVE_ARCH_STRCPY
|
||||||
extern char * strcpy(char *,const char *);
|
extern char * strcpy(char *,const char *);
|
||||||
|
@ -58,8 +58,6 @@ register struct thread_info *__current_thread_info __asm__("$8");
|
|||||||
#define THREAD_SIZE_ORDER 1
|
#define THREAD_SIZE_ORDER 1
|
||||||
#define THREAD_SIZE (2*PAGE_SIZE)
|
#define THREAD_SIZE (2*PAGE_SIZE)
|
||||||
|
|
||||||
#define PREEMPT_ACTIVE 0x40000000
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Thread information flags:
|
* Thread information flags:
|
||||||
* - these are process state flags and used from assembly
|
* - these are process state flags and used from assembly
|
||||||
|
@ -46,6 +46,7 @@
|
|||||||
#define PAL_rdusp 58
|
#define PAL_rdusp 58
|
||||||
#define PAL_whami 60
|
#define PAL_whami 60
|
||||||
#define PAL_retsys 61
|
#define PAL_retsys 61
|
||||||
|
#define PAL_wtint 62
|
||||||
#define PAL_rti 63
|
#define PAL_rti 63
|
||||||
|
|
||||||
|
|
||||||
|
@ -16,6 +16,7 @@ obj-$(CONFIG_PCI) += pci.o pci_iommu.o pci-sysfs.o
|
|||||||
obj-$(CONFIG_SRM_ENV) += srm_env.o
|
obj-$(CONFIG_SRM_ENV) += srm_env.o
|
||||||
obj-$(CONFIG_MODULES) += module.o
|
obj-$(CONFIG_MODULES) += module.o
|
||||||
obj-$(CONFIG_PERF_EVENTS) += perf_event.o
|
obj-$(CONFIG_PERF_EVENTS) += perf_event.o
|
||||||
|
obj-$(CONFIG_RTC_DRV_ALPHA) += rtc.o
|
||||||
|
|
||||||
ifdef CONFIG_ALPHA_GENERIC
|
ifdef CONFIG_ALPHA_GENERIC
|
||||||
|
|
||||||
|
@ -40,6 +40,7 @@ EXPORT_SYMBOL(strrchr);
|
|||||||
EXPORT_SYMBOL(memmove);
|
EXPORT_SYMBOL(memmove);
|
||||||
EXPORT_SYMBOL(__memcpy);
|
EXPORT_SYMBOL(__memcpy);
|
||||||
EXPORT_SYMBOL(__memset);
|
EXPORT_SYMBOL(__memset);
|
||||||
|
EXPORT_SYMBOL(___memset);
|
||||||
EXPORT_SYMBOL(__memsetw);
|
EXPORT_SYMBOL(__memsetw);
|
||||||
EXPORT_SYMBOL(__constant_c_memset);
|
EXPORT_SYMBOL(__constant_c_memset);
|
||||||
EXPORT_SYMBOL(copy_page);
|
EXPORT_SYMBOL(copy_page);
|
||||||
|
@ -66,21 +66,7 @@ do_entInt(unsigned long type, unsigned long vector,
|
|||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
old_regs = set_irq_regs(regs);
|
old_regs = set_irq_regs(regs);
|
||||||
#ifdef CONFIG_SMP
|
|
||||||
{
|
|
||||||
long cpu;
|
|
||||||
|
|
||||||
smp_percpu_timer_interrupt(regs);
|
|
||||||
cpu = smp_processor_id();
|
|
||||||
if (cpu != boot_cpuid) {
|
|
||||||
kstat_incr_irqs_this_cpu(RTC_IRQ, irq_to_desc(RTC_IRQ));
|
|
||||||
} else {
|
|
||||||
handle_irq(RTC_IRQ);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
handle_irq(RTC_IRQ);
|
handle_irq(RTC_IRQ);
|
||||||
#endif
|
|
||||||
set_irq_regs(old_regs);
|
set_irq_regs(old_regs);
|
||||||
return;
|
return;
|
||||||
case 2:
|
case 2:
|
||||||
@ -228,7 +214,7 @@ process_mcheck_info(unsigned long vector, unsigned long la_ptr,
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
struct irqaction timer_irqaction = {
|
struct irqaction timer_irqaction = {
|
||||||
.handler = timer_interrupt,
|
.handler = rtc_timer_interrupt,
|
||||||
.name = "timer",
|
.name = "timer",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -43,10 +43,7 @@
|
|||||||
#define CAT1(x,y) x##y
|
#define CAT1(x,y) x##y
|
||||||
#define CAT(x,y) CAT1(x,y)
|
#define CAT(x,y) CAT1(x,y)
|
||||||
|
|
||||||
#define DO_DEFAULT_RTC \
|
#define DO_DEFAULT_RTC .rtc_port = 0x70
|
||||||
.rtc_port = 0x70, \
|
|
||||||
.rtc_get_time = common_get_rtc_time, \
|
|
||||||
.rtc_set_time = common_set_rtc_time
|
|
||||||
|
|
||||||
#define DO_EV4_MMU \
|
#define DO_EV4_MMU \
|
||||||
.max_asn = EV4_MAX_ASN, \
|
.max_asn = EV4_MAX_ASN, \
|
||||||
|
@ -83,6 +83,8 @@ struct alpha_pmu_t {
|
|||||||
long pmc_left[3];
|
long pmc_left[3];
|
||||||
/* Subroutine for allocation of PMCs. Enforces constraints. */
|
/* Subroutine for allocation of PMCs. Enforces constraints. */
|
||||||
int (*check_constraints)(struct perf_event **, unsigned long *, int);
|
int (*check_constraints)(struct perf_event **, unsigned long *, int);
|
||||||
|
/* Subroutine for checking validity of a raw event for this PMU. */
|
||||||
|
int (*raw_event_valid)(u64 config);
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -203,6 +205,12 @@ success:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int ev67_raw_event_valid(u64 config)
|
||||||
|
{
|
||||||
|
return config >= EV67_CYCLES && config < EV67_LAST_ET;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
static const struct alpha_pmu_t ev67_pmu = {
|
static const struct alpha_pmu_t ev67_pmu = {
|
||||||
.event_map = ev67_perfmon_event_map,
|
.event_map = ev67_perfmon_event_map,
|
||||||
.max_events = ARRAY_SIZE(ev67_perfmon_event_map),
|
.max_events = ARRAY_SIZE(ev67_perfmon_event_map),
|
||||||
@ -211,7 +219,8 @@ static const struct alpha_pmu_t ev67_pmu = {
|
|||||||
.pmc_count_mask = {EV67_PCTR_0_COUNT_MASK, EV67_PCTR_1_COUNT_MASK, 0},
|
.pmc_count_mask = {EV67_PCTR_0_COUNT_MASK, EV67_PCTR_1_COUNT_MASK, 0},
|
||||||
.pmc_max_period = {(1UL<<20) - 1, (1UL<<20) - 1, 0},
|
.pmc_max_period = {(1UL<<20) - 1, (1UL<<20) - 1, 0},
|
||||||
.pmc_left = {16, 4, 0},
|
.pmc_left = {16, 4, 0},
|
||||||
.check_constraints = ev67_check_constraints
|
.check_constraints = ev67_check_constraints,
|
||||||
|
.raw_event_valid = ev67_raw_event_valid,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -609,7 +618,9 @@ static int __hw_perf_event_init(struct perf_event *event)
|
|||||||
} else if (attr->type == PERF_TYPE_HW_CACHE) {
|
} else if (attr->type == PERF_TYPE_HW_CACHE) {
|
||||||
return -EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
} else if (attr->type == PERF_TYPE_RAW) {
|
} else if (attr->type == PERF_TYPE_RAW) {
|
||||||
ev = attr->config & 0xff;
|
if (!alpha_pmu->raw_event_valid(attr->config))
|
||||||
|
return -EINVAL;
|
||||||
|
ev = attr->config;
|
||||||
} else {
|
} else {
|
||||||
return -EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
}
|
}
|
||||||
|
@ -46,6 +46,23 @@
|
|||||||
void (*pm_power_off)(void) = machine_power_off;
|
void (*pm_power_off)(void) = machine_power_off;
|
||||||
EXPORT_SYMBOL(pm_power_off);
|
EXPORT_SYMBOL(pm_power_off);
|
||||||
|
|
||||||
|
#ifdef CONFIG_ALPHA_WTINT
|
||||||
|
/*
|
||||||
|
* Sleep the CPU.
|
||||||
|
* EV6, LCA45 and QEMU know how to power down, skipping N timer interrupts.
|
||||||
|
*/
|
||||||
|
void arch_cpu_idle(void)
|
||||||
|
{
|
||||||
|
wtint(0);
|
||||||
|
local_irq_enable();
|
||||||
|
}
|
||||||
|
|
||||||
|
void arch_cpu_idle_dead(void)
|
||||||
|
{
|
||||||
|
wtint(INT_MAX);
|
||||||
|
}
|
||||||
|
#endif /* ALPHA_WTINT */
|
||||||
|
|
||||||
struct halt_info {
|
struct halt_info {
|
||||||
int mode;
|
int mode;
|
||||||
char *restart_cmd;
|
char *restart_cmd;
|
||||||
|
@ -135,17 +135,15 @@ extern void unregister_srm_console(void);
|
|||||||
/* smp.c */
|
/* smp.c */
|
||||||
extern void setup_smp(void);
|
extern void setup_smp(void);
|
||||||
extern void handle_ipi(struct pt_regs *);
|
extern void handle_ipi(struct pt_regs *);
|
||||||
extern void smp_percpu_timer_interrupt(struct pt_regs *);
|
|
||||||
|
|
||||||
/* bios32.c */
|
/* bios32.c */
|
||||||
/* extern void reset_for_srm(void); */
|
/* extern void reset_for_srm(void); */
|
||||||
|
|
||||||
/* time.c */
|
/* time.c */
|
||||||
extern irqreturn_t timer_interrupt(int irq, void *dev);
|
extern irqreturn_t rtc_timer_interrupt(int irq, void *dev);
|
||||||
|
extern void init_clockevent(void);
|
||||||
extern void common_init_rtc(void);
|
extern void common_init_rtc(void);
|
||||||
extern unsigned long est_cycle_freq;
|
extern unsigned long est_cycle_freq;
|
||||||
extern unsigned int common_get_rtc_time(struct rtc_time *time);
|
|
||||||
extern int common_set_rtc_time(struct rtc_time *time);
|
|
||||||
|
|
||||||
/* smc37c93x.c */
|
/* smc37c93x.c */
|
||||||
extern void SMC93x_Init(void);
|
extern void SMC93x_Init(void);
|
||||||
|
323
arch/alpha/kernel/rtc.c
Normal file
323
arch/alpha/kernel/rtc.c
Normal file
@ -0,0 +1,323 @@
|
|||||||
|
/*
|
||||||
|
* linux/arch/alpha/kernel/rtc.c
|
||||||
|
*
|
||||||
|
* Copyright (C) 1991, 1992, 1995, 1999, 2000 Linus Torvalds
|
||||||
|
*
|
||||||
|
* This file contains date handling.
|
||||||
|
*/
|
||||||
|
#include <linux/errno.h>
|
||||||
|
#include <linux/init.h>
|
||||||
|
#include <linux/kernel.h>
|
||||||
|
#include <linux/param.h>
|
||||||
|
#include <linux/string.h>
|
||||||
|
#include <linux/mc146818rtc.h>
|
||||||
|
#include <linux/bcd.h>
|
||||||
|
#include <linux/rtc.h>
|
||||||
|
#include <linux/platform_device.h>
|
||||||
|
|
||||||
|
#include <asm/rtc.h>
|
||||||
|
|
||||||
|
#include "proto.h"
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Support for the RTC device.
|
||||||
|
*
|
||||||
|
* We don't want to use the rtc-cmos driver, because we don't want to support
|
||||||
|
* alarms, as that would be indistinguishable from timer interrupts.
|
||||||
|
*
|
||||||
|
* Further, generic code is really, really tied to a 1900 epoch. This is
|
||||||
|
* true in __get_rtc_time as well as the users of struct rtc_time e.g.
|
||||||
|
* rtc_tm_to_time. Thankfully all of the other epochs in use are later
|
||||||
|
* than 1900, and so it's easy to adjust.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static unsigned long rtc_epoch;
|
||||||
|
|
||||||
|
static int __init
|
||||||
|
specifiy_epoch(char *str)
|
||||||
|
{
|
||||||
|
unsigned long epoch = simple_strtoul(str, NULL, 0);
|
||||||
|
if (epoch < 1900)
|
||||||
|
printk("Ignoring invalid user specified epoch %lu\n", epoch);
|
||||||
|
else
|
||||||
|
rtc_epoch = epoch;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
__setup("epoch=", specifiy_epoch);
|
||||||
|
|
||||||
|
static void __init
|
||||||
|
init_rtc_epoch(void)
|
||||||
|
{
|
||||||
|
int epoch, year, ctrl;
|
||||||
|
|
||||||
|
if (rtc_epoch != 0) {
|
||||||
|
/* The epoch was specified on the command-line. */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Detect the epoch in use on this computer. */
|
||||||
|
ctrl = CMOS_READ(RTC_CONTROL);
|
||||||
|
year = CMOS_READ(RTC_YEAR);
|
||||||
|
if (!(ctrl & RTC_DM_BINARY) || RTC_ALWAYS_BCD)
|
||||||
|
year = bcd2bin(year);
|
||||||
|
|
||||||
|
/* PC-like is standard; used for year >= 70 */
|
||||||
|
epoch = 1900;
|
||||||
|
if (year < 20) {
|
||||||
|
epoch = 2000;
|
||||||
|
} else if (year >= 20 && year < 48) {
|
||||||
|
/* NT epoch */
|
||||||
|
epoch = 1980;
|
||||||
|
} else if (year >= 48 && year < 70) {
|
||||||
|
/* Digital UNIX epoch */
|
||||||
|
epoch = 1952;
|
||||||
|
}
|
||||||
|
rtc_epoch = epoch;
|
||||||
|
|
||||||
|
printk(KERN_INFO "Using epoch %d for rtc year %d\n", epoch, year);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
alpha_rtc_read_time(struct device *dev, struct rtc_time *tm)
|
||||||
|
{
|
||||||
|
__get_rtc_time(tm);
|
||||||
|
|
||||||
|
/* Adjust for non-default epochs. It's easier to depend on the
|
||||||
|
generic __get_rtc_time and adjust the epoch here than create
|
||||||
|
a copy of __get_rtc_time with the edits we need. */
|
||||||
|
if (rtc_epoch != 1900) {
|
||||||
|
int year = tm->tm_year;
|
||||||
|
/* Undo the century adjustment made in __get_rtc_time. */
|
||||||
|
if (year >= 100)
|
||||||
|
year -= 100;
|
||||||
|
year += rtc_epoch - 1900;
|
||||||
|
/* Redo the century adjustment with the epoch in place. */
|
||||||
|
if (year <= 69)
|
||||||
|
year += 100;
|
||||||
|
tm->tm_year = year;
|
||||||
|
}
|
||||||
|
|
||||||
|
return rtc_valid_tm(tm);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
alpha_rtc_set_time(struct device *dev, struct rtc_time *tm)
|
||||||
|
{
|
||||||
|
struct rtc_time xtm;
|
||||||
|
|
||||||
|
if (rtc_epoch != 1900) {
|
||||||
|
xtm = *tm;
|
||||||
|
xtm.tm_year -= rtc_epoch - 1900;
|
||||||
|
tm = &xtm;
|
||||||
|
}
|
||||||
|
|
||||||
|
return __set_rtc_time(tm);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
alpha_rtc_set_mmss(struct device *dev, unsigned long nowtime)
|
||||||
|
{
|
||||||
|
int retval = 0;
|
||||||
|
int real_seconds, real_minutes, cmos_minutes;
|
||||||
|
unsigned char save_control, save_freq_select;
|
||||||
|
|
||||||
|
/* Note: This code only updates minutes and seconds. Comments
|
||||||
|
indicate this was to avoid messing with unknown time zones,
|
||||||
|
and with the epoch nonsense described above. In order for
|
||||||
|
this to work, the existing clock cannot be off by more than
|
||||||
|
15 minutes.
|
||||||
|
|
||||||
|
??? This choice is may be out of date. The x86 port does
|
||||||
|
not have problems with timezones, and the epoch processing has
|
||||||
|
now been fixed in alpha_set_rtc_time.
|
||||||
|
|
||||||
|
In either case, one can always force a full rtc update with
|
||||||
|
the userland hwclock program, so surely 15 minute accuracy
|
||||||
|
is no real burden. */
|
||||||
|
|
||||||
|
/* In order to set the CMOS clock precisely, we have to be called
|
||||||
|
500 ms after the second nowtime has started, because when
|
||||||
|
nowtime is written into the registers of the CMOS clock, it will
|
||||||
|
jump to the next second precisely 500 ms later. Check the Motorola
|
||||||
|
MC146818A or Dallas DS12887 data sheet for details. */
|
||||||
|
|
||||||
|
/* irq are locally disabled here */
|
||||||
|
spin_lock(&rtc_lock);
|
||||||
|
/* Tell the clock it's being set */
|
||||||
|
save_control = CMOS_READ(RTC_CONTROL);
|
||||||
|
CMOS_WRITE((save_control|RTC_SET), RTC_CONTROL);
|
||||||
|
|
||||||
|
/* Stop and reset prescaler */
|
||||||
|
save_freq_select = CMOS_READ(RTC_FREQ_SELECT);
|
||||||
|
CMOS_WRITE((save_freq_select|RTC_DIV_RESET2), RTC_FREQ_SELECT);
|
||||||
|
|
||||||
|
cmos_minutes = CMOS_READ(RTC_MINUTES);
|
||||||
|
if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD)
|
||||||
|
cmos_minutes = bcd2bin(cmos_minutes);
|
||||||
|
|
||||||
|
real_seconds = nowtime % 60;
|
||||||
|
real_minutes = nowtime / 60;
|
||||||
|
if (((abs(real_minutes - cmos_minutes) + 15) / 30) & 1) {
|
||||||
|
/* correct for half hour time zone */
|
||||||
|
real_minutes += 30;
|
||||||
|
}
|
||||||
|
real_minutes %= 60;
|
||||||
|
|
||||||
|
if (abs(real_minutes - cmos_minutes) < 30) {
|
||||||
|
if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) {
|
||||||
|
real_seconds = bin2bcd(real_seconds);
|
||||||
|
real_minutes = bin2bcd(real_minutes);
|
||||||
|
}
|
||||||
|
CMOS_WRITE(real_seconds,RTC_SECONDS);
|
||||||
|
CMOS_WRITE(real_minutes,RTC_MINUTES);
|
||||||
|
} else {
|
||||||
|
printk_once(KERN_NOTICE
|
||||||
|
"set_rtc_mmss: can't update from %d to %d\n",
|
||||||
|
cmos_minutes, real_minutes);
|
||||||
|
retval = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The following flags have to be released exactly in this order,
|
||||||
|
* otherwise the DS12887 (popular MC146818A clone with integrated
|
||||||
|
* battery and quartz) will not reset the oscillator and will not
|
||||||
|
* update precisely 500 ms later. You won't find this mentioned in
|
||||||
|
* the Dallas Semiconductor data sheets, but who believes data
|
||||||
|
* sheets anyway ... -- Markus Kuhn
|
||||||
|
*/
|
||||||
|
CMOS_WRITE(save_control, RTC_CONTROL);
|
||||||
|
CMOS_WRITE(save_freq_select, RTC_FREQ_SELECT);
|
||||||
|
spin_unlock(&rtc_lock);
|
||||||
|
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
alpha_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
|
||||||
|
{
|
||||||
|
switch (cmd) {
|
||||||
|
case RTC_EPOCH_READ:
|
||||||
|
return put_user(rtc_epoch, (unsigned long __user *)arg);
|
||||||
|
case RTC_EPOCH_SET:
|
||||||
|
if (arg < 1900)
|
||||||
|
return -EINVAL;
|
||||||
|
rtc_epoch = arg;
|
||||||
|
return 0;
|
||||||
|
default:
|
||||||
|
return -ENOIOCTLCMD;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct rtc_class_ops alpha_rtc_ops = {
|
||||||
|
.read_time = alpha_rtc_read_time,
|
||||||
|
.set_time = alpha_rtc_set_time,
|
||||||
|
.set_mmss = alpha_rtc_set_mmss,
|
||||||
|
.ioctl = alpha_rtc_ioctl,
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Similarly, except do the actual CMOS access on the boot cpu only.
|
||||||
|
* This requires marshalling the data across an interprocessor call.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if defined(CONFIG_SMP) && \
|
||||||
|
(defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_MARVEL))
|
||||||
|
# define HAVE_REMOTE_RTC 1
|
||||||
|
|
||||||
|
union remote_data {
|
||||||
|
struct rtc_time *tm;
|
||||||
|
unsigned long now;
|
||||||
|
long retval;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
do_remote_read(void *data)
|
||||||
|
{
|
||||||
|
union remote_data *x = data;
|
||||||
|
x->retval = alpha_rtc_read_time(NULL, x->tm);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
remote_read_time(struct device *dev, struct rtc_time *tm)
|
||||||
|
{
|
||||||
|
union remote_data x;
|
||||||
|
if (smp_processor_id() != boot_cpuid) {
|
||||||
|
x.tm = tm;
|
||||||
|
smp_call_function_single(boot_cpuid, do_remote_read, &x, 1);
|
||||||
|
return x.retval;
|
||||||
|
}
|
||||||
|
return alpha_rtc_read_time(NULL, tm);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
do_remote_set(void *data)
|
||||||
|
{
|
||||||
|
union remote_data *x = data;
|
||||||
|
x->retval = alpha_rtc_set_time(NULL, x->tm);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
remote_set_time(struct device *dev, struct rtc_time *tm)
|
||||||
|
{
|
||||||
|
union remote_data x;
|
||||||
|
if (smp_processor_id() != boot_cpuid) {
|
||||||
|
x.tm = tm;
|
||||||
|
smp_call_function_single(boot_cpuid, do_remote_set, &x, 1);
|
||||||
|
return x.retval;
|
||||||
|
}
|
||||||
|
return alpha_rtc_set_time(NULL, tm);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
do_remote_mmss(void *data)
|
||||||
|
{
|
||||||
|
union remote_data *x = data;
|
||||||
|
x->retval = alpha_rtc_set_mmss(NULL, x->now);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
remote_set_mmss(struct device *dev, unsigned long now)
|
||||||
|
{
|
||||||
|
union remote_data x;
|
||||||
|
if (smp_processor_id() != boot_cpuid) {
|
||||||
|
x.now = now;
|
||||||
|
smp_call_function_single(boot_cpuid, do_remote_mmss, &x, 1);
|
||||||
|
return x.retval;
|
||||||
|
}
|
||||||
|
return alpha_rtc_set_mmss(NULL, now);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct rtc_class_ops remote_rtc_ops = {
|
||||||
|
.read_time = remote_read_time,
|
||||||
|
.set_time = remote_set_time,
|
||||||
|
.set_mmss = remote_set_mmss,
|
||||||
|
.ioctl = alpha_rtc_ioctl,
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static int __init
|
||||||
|
alpha_rtc_init(void)
|
||||||
|
{
|
||||||
|
const struct rtc_class_ops *ops;
|
||||||
|
struct platform_device *pdev;
|
||||||
|
struct rtc_device *rtc;
|
||||||
|
const char *name;
|
||||||
|
|
||||||
|
init_rtc_epoch();
|
||||||
|
name = "rtc-alpha";
|
||||||
|
ops = &alpha_rtc_ops;
|
||||||
|
|
||||||
|
#ifdef HAVE_REMOTE_RTC
|
||||||
|
if (alpha_mv.rtc_boot_cpu_only)
|
||||||
|
ops = &remote_rtc_ops;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
pdev = platform_device_register_simple(name, -1, NULL, 0);
|
||||||
|
rtc = devm_rtc_device_register(&pdev->dev, name, ops, THIS_MODULE);
|
||||||
|
if (IS_ERR(rtc))
|
||||||
|
return PTR_ERR(rtc);
|
||||||
|
|
||||||
|
platform_set_drvdata(pdev, rtc);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
device_initcall(alpha_rtc_init);
|
@ -115,10 +115,17 @@ unsigned long alpha_agpgart_size = DEFAULT_AGP_APER_SIZE;
|
|||||||
|
|
||||||
#ifdef CONFIG_ALPHA_GENERIC
|
#ifdef CONFIG_ALPHA_GENERIC
|
||||||
struct alpha_machine_vector alpha_mv;
|
struct alpha_machine_vector alpha_mv;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef alpha_using_srm
|
||||||
int alpha_using_srm;
|
int alpha_using_srm;
|
||||||
EXPORT_SYMBOL(alpha_using_srm);
|
EXPORT_SYMBOL(alpha_using_srm);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef alpha_using_qemu
|
||||||
|
int alpha_using_qemu;
|
||||||
|
#endif
|
||||||
|
|
||||||
static struct alpha_machine_vector *get_sysvec(unsigned long, unsigned long,
|
static struct alpha_machine_vector *get_sysvec(unsigned long, unsigned long,
|
||||||
unsigned long);
|
unsigned long);
|
||||||
static struct alpha_machine_vector *get_sysvec_byname(const char *);
|
static struct alpha_machine_vector *get_sysvec_byname(const char *);
|
||||||
@ -529,11 +536,15 @@ setup_arch(char **cmdline_p)
|
|||||||
atomic_notifier_chain_register(&panic_notifier_list,
|
atomic_notifier_chain_register(&panic_notifier_list,
|
||||||
&alpha_panic_block);
|
&alpha_panic_block);
|
||||||
|
|
||||||
#ifdef CONFIG_ALPHA_GENERIC
|
#ifndef alpha_using_srm
|
||||||
/* Assume that we've booted from SRM if we haven't booted from MILO.
|
/* Assume that we've booted from SRM if we haven't booted from MILO.
|
||||||
Detect the later by looking for "MILO" in the system serial nr. */
|
Detect the later by looking for "MILO" in the system serial nr. */
|
||||||
alpha_using_srm = strncmp((const char *)hwrpb->ssn, "MILO", 4) != 0;
|
alpha_using_srm = strncmp((const char *)hwrpb->ssn, "MILO", 4) != 0;
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef alpha_using_qemu
|
||||||
|
/* Similarly, look for QEMU. */
|
||||||
|
alpha_using_qemu = strstr((const char *)hwrpb->ssn, "QEMU") != 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
/* If we are using SRM, we want to allow callbacks
|
/* If we are using SRM, we want to allow callbacks
|
||||||
as early as possible, so do this NOW, and then
|
as early as possible, so do this NOW, and then
|
||||||
@ -1207,6 +1218,7 @@ show_cpuinfo(struct seq_file *f, void *slot)
|
|||||||
char *systype_name;
|
char *systype_name;
|
||||||
char *sysvariation_name;
|
char *sysvariation_name;
|
||||||
int nr_processors;
|
int nr_processors;
|
||||||
|
unsigned long timer_freq;
|
||||||
|
|
||||||
cpu_index = (unsigned) (cpu->type - 1);
|
cpu_index = (unsigned) (cpu->type - 1);
|
||||||
cpu_name = "Unknown";
|
cpu_name = "Unknown";
|
||||||
@ -1218,6 +1230,12 @@ show_cpuinfo(struct seq_file *f, void *slot)
|
|||||||
|
|
||||||
nr_processors = get_nr_processors(cpu, hwrpb->nr_processors);
|
nr_processors = get_nr_processors(cpu, hwrpb->nr_processors);
|
||||||
|
|
||||||
|
#if CONFIG_HZ == 1024 || CONFIG_HZ == 1200
|
||||||
|
timer_freq = (100UL * hwrpb->intr_freq) / 4096;
|
||||||
|
#else
|
||||||
|
timer_freq = 100UL * CONFIG_HZ;
|
||||||
|
#endif
|
||||||
|
|
||||||
seq_printf(f, "cpu\t\t\t: Alpha\n"
|
seq_printf(f, "cpu\t\t\t: Alpha\n"
|
||||||
"cpu model\t\t: %s\n"
|
"cpu model\t\t: %s\n"
|
||||||
"cpu variation\t\t: %ld\n"
|
"cpu variation\t\t: %ld\n"
|
||||||
@ -1243,8 +1261,7 @@ show_cpuinfo(struct seq_file *f, void *slot)
|
|||||||
(char*)hwrpb->ssn,
|
(char*)hwrpb->ssn,
|
||||||
est_cycle_freq ? : hwrpb->cycle_freq,
|
est_cycle_freq ? : hwrpb->cycle_freq,
|
||||||
est_cycle_freq ? "est." : "",
|
est_cycle_freq ? "est." : "",
|
||||||
hwrpb->intr_freq / 4096,
|
timer_freq / 100, timer_freq % 100,
|
||||||
(100 * hwrpb->intr_freq / 4096) % 100,
|
|
||||||
hwrpb->pagesize,
|
hwrpb->pagesize,
|
||||||
hwrpb->pa_bits,
|
hwrpb->pa_bits,
|
||||||
hwrpb->max_asn,
|
hwrpb->max_asn,
|
||||||
|
@ -138,9 +138,11 @@ smp_callin(void)
|
|||||||
|
|
||||||
/* Get our local ticker going. */
|
/* Get our local ticker going. */
|
||||||
smp_setup_percpu_timer(cpuid);
|
smp_setup_percpu_timer(cpuid);
|
||||||
|
init_clockevent();
|
||||||
|
|
||||||
/* Call platform-specific callin, if specified */
|
/* Call platform-specific callin, if specified */
|
||||||
if (alpha_mv.smp_callin) alpha_mv.smp_callin();
|
if (alpha_mv.smp_callin)
|
||||||
|
alpha_mv.smp_callin();
|
||||||
|
|
||||||
/* All kernel threads share the same mm context. */
|
/* All kernel threads share the same mm context. */
|
||||||
atomic_inc(&init_mm.mm_count);
|
atomic_inc(&init_mm.mm_count);
|
||||||
@ -498,35 +500,6 @@ smp_cpus_done(unsigned int max_cpus)
|
|||||||
((bogosum + 2500) / (5000/HZ)) % 100);
|
((bogosum + 2500) / (5000/HZ)) % 100);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
smp_percpu_timer_interrupt(struct pt_regs *regs)
|
|
||||||
{
|
|
||||||
struct pt_regs *old_regs;
|
|
||||||
int cpu = smp_processor_id();
|
|
||||||
unsigned long user = user_mode(regs);
|
|
||||||
struct cpuinfo_alpha *data = &cpu_data[cpu];
|
|
||||||
|
|
||||||
old_regs = set_irq_regs(regs);
|
|
||||||
|
|
||||||
/* Record kernel PC. */
|
|
||||||
profile_tick(CPU_PROFILING);
|
|
||||||
|
|
||||||
if (!--data->prof_counter) {
|
|
||||||
/* We need to make like a normal interrupt -- otherwise
|
|
||||||
timer interrupts ignore the global interrupt lock,
|
|
||||||
which would be a Bad Thing. */
|
|
||||||
irq_enter();
|
|
||||||
|
|
||||||
update_process_times(user);
|
|
||||||
|
|
||||||
data->prof_counter = data->prof_multiplier;
|
|
||||||
|
|
||||||
irq_exit();
|
|
||||||
}
|
|
||||||
set_irq_regs(old_regs);
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
int
|
||||||
setup_profiling_timer(unsigned int multiplier)
|
setup_profiling_timer(unsigned int multiplier)
|
||||||
{
|
{
|
||||||
|
@ -224,8 +224,6 @@ struct alpha_machine_vector jensen_mv __initmv = {
|
|||||||
.machine_check = jensen_machine_check,
|
.machine_check = jensen_machine_check,
|
||||||
.max_isa_dma_address = ALPHA_MAX_ISA_DMA_ADDRESS,
|
.max_isa_dma_address = ALPHA_MAX_ISA_DMA_ADDRESS,
|
||||||
.rtc_port = 0x170,
|
.rtc_port = 0x170,
|
||||||
.rtc_get_time = common_get_rtc_time,
|
|
||||||
.rtc_set_time = common_set_rtc_time,
|
|
||||||
|
|
||||||
.nr_irqs = 16,
|
.nr_irqs = 16,
|
||||||
.device_interrupt = jensen_device_interrupt,
|
.device_interrupt = jensen_device_interrupt,
|
||||||
|
@ -22,7 +22,6 @@
|
|||||||
#include <asm/hwrpb.h>
|
#include <asm/hwrpb.h>
|
||||||
#include <asm/tlbflush.h>
|
#include <asm/tlbflush.h>
|
||||||
#include <asm/vga.h>
|
#include <asm/vga.h>
|
||||||
#include <asm/rtc.h>
|
|
||||||
|
|
||||||
#include "proto.h"
|
#include "proto.h"
|
||||||
#include "err_impl.h"
|
#include "err_impl.h"
|
||||||
@ -400,57 +399,6 @@ marvel_init_rtc(void)
|
|||||||
init_rtc_irq();
|
init_rtc_irq();
|
||||||
}
|
}
|
||||||
|
|
||||||
struct marvel_rtc_time {
|
|
||||||
struct rtc_time *time;
|
|
||||||
int retval;
|
|
||||||
};
|
|
||||||
|
|
||||||
#ifdef CONFIG_SMP
|
|
||||||
static void
|
|
||||||
smp_get_rtc_time(void *data)
|
|
||||||
{
|
|
||||||
struct marvel_rtc_time *mrt = data;
|
|
||||||
mrt->retval = __get_rtc_time(mrt->time);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
smp_set_rtc_time(void *data)
|
|
||||||
{
|
|
||||||
struct marvel_rtc_time *mrt = data;
|
|
||||||
mrt->retval = __set_rtc_time(mrt->time);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static unsigned int
|
|
||||||
marvel_get_rtc_time(struct rtc_time *time)
|
|
||||||
{
|
|
||||||
#ifdef CONFIG_SMP
|
|
||||||
struct marvel_rtc_time mrt;
|
|
||||||
|
|
||||||
if (smp_processor_id() != boot_cpuid) {
|
|
||||||
mrt.time = time;
|
|
||||||
smp_call_function_single(boot_cpuid, smp_get_rtc_time, &mrt, 1);
|
|
||||||
return mrt.retval;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
return __get_rtc_time(time);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
marvel_set_rtc_time(struct rtc_time *time)
|
|
||||||
{
|
|
||||||
#ifdef CONFIG_SMP
|
|
||||||
struct marvel_rtc_time mrt;
|
|
||||||
|
|
||||||
if (smp_processor_id() != boot_cpuid) {
|
|
||||||
mrt.time = time;
|
|
||||||
smp_call_function_single(boot_cpuid, smp_set_rtc_time, &mrt, 1);
|
|
||||||
return mrt.retval;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
return __set_rtc_time(time);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
marvel_smp_callin(void)
|
marvel_smp_callin(void)
|
||||||
{
|
{
|
||||||
@ -492,8 +440,7 @@ struct alpha_machine_vector marvel_ev7_mv __initmv = {
|
|||||||
.vector_name = "MARVEL/EV7",
|
.vector_name = "MARVEL/EV7",
|
||||||
DO_EV7_MMU,
|
DO_EV7_MMU,
|
||||||
.rtc_port = 0x70,
|
.rtc_port = 0x70,
|
||||||
.rtc_get_time = marvel_get_rtc_time,
|
.rtc_boot_cpu_only = 1,
|
||||||
.rtc_set_time = marvel_set_rtc_time,
|
|
||||||
DO_MARVEL_IO,
|
DO_MARVEL_IO,
|
||||||
.machine_check = marvel_machine_check,
|
.machine_check = marvel_machine_check,
|
||||||
.max_isa_dma_address = ALPHA_MAX_ISA_DMA_ADDRESS,
|
.max_isa_dma_address = ALPHA_MAX_ISA_DMA_ADDRESS,
|
||||||
|
@ -3,13 +3,7 @@
|
|||||||
*
|
*
|
||||||
* Copyright (C) 1991, 1992, 1995, 1999, 2000 Linus Torvalds
|
* Copyright (C) 1991, 1992, 1995, 1999, 2000 Linus Torvalds
|
||||||
*
|
*
|
||||||
* This file contains the PC-specific time handling details:
|
* This file contains the clocksource time handling.
|
||||||
* reading the RTC at bootup, etc..
|
|
||||||
* 1994-07-02 Alan Modra
|
|
||||||
* fixed set_rtc_mmss, fixed time.year for >= 2000, new mktime
|
|
||||||
* 1995-03-26 Markus Kuhn
|
|
||||||
* fixed 500 ms bug at call to set_rtc_mmss, fixed DS12887
|
|
||||||
* precision CMOS clock update
|
|
||||||
* 1997-09-10 Updated NTP code according to technical memorandum Jan '96
|
* 1997-09-10 Updated NTP code according to technical memorandum Jan '96
|
||||||
* "A Kernel Model for Precision Timekeeping" by Dave Mills
|
* "A Kernel Model for Precision Timekeeping" by Dave Mills
|
||||||
* 1997-01-09 Adrian Sun
|
* 1997-01-09 Adrian Sun
|
||||||
@ -21,9 +15,6 @@
|
|||||||
* 1999-04-16 Thorsten Kranzkowski (dl8bcu@gmx.net)
|
* 1999-04-16 Thorsten Kranzkowski (dl8bcu@gmx.net)
|
||||||
* fixed algorithm in do_gettimeofday() for calculating the precise time
|
* fixed algorithm in do_gettimeofday() for calculating the precise time
|
||||||
* from processor cycle counter (now taking lost_ticks into account)
|
* from processor cycle counter (now taking lost_ticks into account)
|
||||||
* 2000-08-13 Jan-Benedict Glaw <jbglaw@lug-owl.de>
|
|
||||||
* Fixed time_init to be aware of epoches != 1900. This prevents
|
|
||||||
* booting up in 2048 for me;) Code is stolen from rtc.c.
|
|
||||||
* 2003-06-03 R. Scott Bailey <scott.bailey@eds.com>
|
* 2003-06-03 R. Scott Bailey <scott.bailey@eds.com>
|
||||||
* Tighten sanity in time_init from 1% (10,000 PPM) to 250 PPM
|
* Tighten sanity in time_init from 1% (10,000 PPM) to 250 PPM
|
||||||
*/
|
*/
|
||||||
@ -46,40 +37,19 @@
|
|||||||
#include <asm/uaccess.h>
|
#include <asm/uaccess.h>
|
||||||
#include <asm/io.h>
|
#include <asm/io.h>
|
||||||
#include <asm/hwrpb.h>
|
#include <asm/hwrpb.h>
|
||||||
#include <asm/rtc.h>
|
|
||||||
|
|
||||||
#include <linux/mc146818rtc.h>
|
#include <linux/mc146818rtc.h>
|
||||||
#include <linux/time.h>
|
#include <linux/time.h>
|
||||||
#include <linux/timex.h>
|
#include <linux/timex.h>
|
||||||
#include <linux/clocksource.h>
|
#include <linux/clocksource.h>
|
||||||
|
#include <linux/clockchips.h>
|
||||||
|
|
||||||
#include "proto.h"
|
#include "proto.h"
|
||||||
#include "irq_impl.h"
|
#include "irq_impl.h"
|
||||||
|
|
||||||
static int set_rtc_mmss(unsigned long);
|
|
||||||
|
|
||||||
DEFINE_SPINLOCK(rtc_lock);
|
DEFINE_SPINLOCK(rtc_lock);
|
||||||
EXPORT_SYMBOL(rtc_lock);
|
EXPORT_SYMBOL(rtc_lock);
|
||||||
|
|
||||||
#define TICK_SIZE (tick_nsec / 1000)
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Shift amount by which scaled_ticks_per_cycle is scaled. Shifting
|
|
||||||
* by 48 gives us 16 bits for HZ while keeping the accuracy good even
|
|
||||||
* for large CPU clock rates.
|
|
||||||
*/
|
|
||||||
#define FIX_SHIFT 48
|
|
||||||
|
|
||||||
/* lump static variables together for more efficient access: */
|
|
||||||
static struct {
|
|
||||||
/* cycle counter last time it got invoked */
|
|
||||||
__u32 last_time;
|
|
||||||
/* ticks/cycle * 2^48 */
|
|
||||||
unsigned long scaled_ticks_per_cycle;
|
|
||||||
/* partial unused tick */
|
|
||||||
unsigned long partial_tick;
|
|
||||||
} state;
|
|
||||||
|
|
||||||
unsigned long est_cycle_freq;
|
unsigned long est_cycle_freq;
|
||||||
|
|
||||||
#ifdef CONFIG_IRQ_WORK
|
#ifdef CONFIG_IRQ_WORK
|
||||||
@ -108,109 +78,156 @@ static inline __u32 rpcc(void)
|
|||||||
return __builtin_alpha_rpcc();
|
return __builtin_alpha_rpcc();
|
||||||
}
|
}
|
||||||
|
|
||||||
int update_persistent_clock(struct timespec now)
|
|
||||||
{
|
|
||||||
return set_rtc_mmss(now.tv_sec);
|
|
||||||
}
|
|
||||||
|
|
||||||
void read_persistent_clock(struct timespec *ts)
|
|
||||||
{
|
|
||||||
unsigned int year, mon, day, hour, min, sec, epoch;
|
|
||||||
|
|
||||||
sec = CMOS_READ(RTC_SECONDS);
|
|
||||||
min = CMOS_READ(RTC_MINUTES);
|
|
||||||
hour = CMOS_READ(RTC_HOURS);
|
|
||||||
day = CMOS_READ(RTC_DAY_OF_MONTH);
|
|
||||||
mon = CMOS_READ(RTC_MONTH);
|
|
||||||
year = CMOS_READ(RTC_YEAR);
|
|
||||||
|
|
||||||
if (!(CMOS_READ(RTC_CONTROL) & RTC_DM_BINARY) || RTC_ALWAYS_BCD) {
|
|
||||||
sec = bcd2bin(sec);
|
|
||||||
min = bcd2bin(min);
|
|
||||||
hour = bcd2bin(hour);
|
|
||||||
day = bcd2bin(day);
|
|
||||||
mon = bcd2bin(mon);
|
|
||||||
year = bcd2bin(year);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* PC-like is standard; used for year >= 70 */
|
|
||||||
epoch = 1900;
|
|
||||||
if (year < 20)
|
|
||||||
epoch = 2000;
|
|
||||||
else if (year >= 20 && year < 48)
|
|
||||||
/* NT epoch */
|
|
||||||
epoch = 1980;
|
|
||||||
else if (year >= 48 && year < 70)
|
|
||||||
/* Digital UNIX epoch */
|
|
||||||
epoch = 1952;
|
|
||||||
|
|
||||||
printk(KERN_INFO "Using epoch = %d\n", epoch);
|
|
||||||
|
|
||||||
if ((year += epoch) < 1970)
|
|
||||||
year += 100;
|
|
||||||
|
|
||||||
ts->tv_sec = mktime(year, mon, day, hour, min, sec);
|
|
||||||
ts->tv_nsec = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* timer_interrupt() needs to keep up the real-time clock,
|
* The RTC as a clock_event_device primitive.
|
||||||
* as well as call the "xtime_update()" routine every clocktick
|
|
||||||
*/
|
*/
|
||||||
irqreturn_t timer_interrupt(int irq, void *dev)
|
|
||||||
|
static DEFINE_PER_CPU(struct clock_event_device, cpu_ce);
|
||||||
|
|
||||||
|
irqreturn_t
|
||||||
|
rtc_timer_interrupt(int irq, void *dev)
|
||||||
{
|
{
|
||||||
unsigned long delta;
|
int cpu = smp_processor_id();
|
||||||
__u32 now;
|
struct clock_event_device *ce = &per_cpu(cpu_ce, cpu);
|
||||||
long nticks;
|
|
||||||
|
|
||||||
#ifndef CONFIG_SMP
|
/* Don't run the hook for UNUSED or SHUTDOWN. */
|
||||||
/* Not SMP, do kernel PC profiling here. */
|
if (likely(ce->mode == CLOCK_EVT_MODE_PERIODIC))
|
||||||
profile_tick(CPU_PROFILING);
|
ce->event_handler(ce);
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Calculate how many ticks have passed since the last update,
|
|
||||||
* including any previous partial leftover. Save any resulting
|
|
||||||
* fraction for the next pass.
|
|
||||||
*/
|
|
||||||
now = rpcc();
|
|
||||||
delta = now - state.last_time;
|
|
||||||
state.last_time = now;
|
|
||||||
delta = delta * state.scaled_ticks_per_cycle + state.partial_tick;
|
|
||||||
state.partial_tick = delta & ((1UL << FIX_SHIFT) - 1);
|
|
||||||
nticks = delta >> FIX_SHIFT;
|
|
||||||
|
|
||||||
if (nticks)
|
|
||||||
xtime_update(nticks);
|
|
||||||
|
|
||||||
if (test_irq_work_pending()) {
|
if (test_irq_work_pending()) {
|
||||||
clear_irq_work_pending();
|
clear_irq_work_pending();
|
||||||
irq_work_run();
|
irq_work_run();
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef CONFIG_SMP
|
|
||||||
while (nticks--)
|
|
||||||
update_process_times(user_mode(get_irq_regs()));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return IRQ_HANDLED;
|
return IRQ_HANDLED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
rtc_ce_set_mode(enum clock_event_mode mode, struct clock_event_device *ce)
|
||||||
|
{
|
||||||
|
/* The mode member of CE is updated in generic code.
|
||||||
|
Since we only support periodic events, nothing to do. */
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
rtc_ce_set_next_event(unsigned long evt, struct clock_event_device *ce)
|
||||||
|
{
|
||||||
|
/* This hook is for oneshot mode, which we don't support. */
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void __init
|
||||||
|
init_rtc_clockevent(void)
|
||||||
|
{
|
||||||
|
int cpu = smp_processor_id();
|
||||||
|
struct clock_event_device *ce = &per_cpu(cpu_ce, cpu);
|
||||||
|
|
||||||
|
*ce = (struct clock_event_device){
|
||||||
|
.name = "rtc",
|
||||||
|
.features = CLOCK_EVT_FEAT_PERIODIC,
|
||||||
|
.rating = 100,
|
||||||
|
.cpumask = cpumask_of(cpu),
|
||||||
|
.set_mode = rtc_ce_set_mode,
|
||||||
|
.set_next_event = rtc_ce_set_next_event,
|
||||||
|
};
|
||||||
|
|
||||||
|
clockevents_config_and_register(ce, CONFIG_HZ, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The QEMU clock as a clocksource primitive.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static cycle_t
|
||||||
|
qemu_cs_read(struct clocksource *cs)
|
||||||
|
{
|
||||||
|
return qemu_get_vmtime();
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct clocksource qemu_cs = {
|
||||||
|
.name = "qemu",
|
||||||
|
.rating = 400,
|
||||||
|
.read = qemu_cs_read,
|
||||||
|
.mask = CLOCKSOURCE_MASK(64),
|
||||||
|
.flags = CLOCK_SOURCE_IS_CONTINUOUS,
|
||||||
|
.max_idle_ns = LONG_MAX
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The QEMU alarm as a clock_event_device primitive.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static void
|
||||||
|
qemu_ce_set_mode(enum clock_event_mode mode, struct clock_event_device *ce)
|
||||||
|
{
|
||||||
|
/* The mode member of CE is updated for us in generic code.
|
||||||
|
Just make sure that the event is disabled. */
|
||||||
|
qemu_set_alarm_abs(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
qemu_ce_set_next_event(unsigned long evt, struct clock_event_device *ce)
|
||||||
|
{
|
||||||
|
qemu_set_alarm_rel(evt);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static irqreturn_t
|
||||||
|
qemu_timer_interrupt(int irq, void *dev)
|
||||||
|
{
|
||||||
|
int cpu = smp_processor_id();
|
||||||
|
struct clock_event_device *ce = &per_cpu(cpu_ce, cpu);
|
||||||
|
|
||||||
|
ce->event_handler(ce);
|
||||||
|
return IRQ_HANDLED;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void __init
|
||||||
|
init_qemu_clockevent(void)
|
||||||
|
{
|
||||||
|
int cpu = smp_processor_id();
|
||||||
|
struct clock_event_device *ce = &per_cpu(cpu_ce, cpu);
|
||||||
|
|
||||||
|
*ce = (struct clock_event_device){
|
||||||
|
.name = "qemu",
|
||||||
|
.features = CLOCK_EVT_FEAT_ONESHOT,
|
||||||
|
.rating = 400,
|
||||||
|
.cpumask = cpumask_of(cpu),
|
||||||
|
.set_mode = qemu_ce_set_mode,
|
||||||
|
.set_next_event = qemu_ce_set_next_event,
|
||||||
|
};
|
||||||
|
|
||||||
|
clockevents_config_and_register(ce, NSEC_PER_SEC, 1000, LONG_MAX);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void __init
|
void __init
|
||||||
common_init_rtc(void)
|
common_init_rtc(void)
|
||||||
{
|
{
|
||||||
unsigned char x;
|
unsigned char x, sel = 0;
|
||||||
|
|
||||||
/* Reset periodic interrupt frequency. */
|
/* Reset periodic interrupt frequency. */
|
||||||
x = CMOS_READ(RTC_FREQ_SELECT) & 0x3f;
|
#if CONFIG_HZ == 1024 || CONFIG_HZ == 1200
|
||||||
/* Test includes known working values on various platforms
|
x = CMOS_READ(RTC_FREQ_SELECT) & 0x3f;
|
||||||
where 0x26 is wrong; we refuse to change those. */
|
/* Test includes known working values on various platforms
|
||||||
if (x != 0x26 && x != 0x25 && x != 0x19 && x != 0x06) {
|
where 0x26 is wrong; we refuse to change those. */
|
||||||
printk("Setting RTC_FREQ to 1024 Hz (%x)\n", x);
|
if (x != 0x26 && x != 0x25 && x != 0x19 && x != 0x06) {
|
||||||
CMOS_WRITE(0x26, RTC_FREQ_SELECT);
|
sel = RTC_REF_CLCK_32KHZ + 6;
|
||||||
}
|
}
|
||||||
|
#elif CONFIG_HZ == 256 || CONFIG_HZ == 128 || CONFIG_HZ == 64 || CONFIG_HZ == 32
|
||||||
|
sel = RTC_REF_CLCK_32KHZ + __builtin_ffs(32768 / CONFIG_HZ);
|
||||||
|
#else
|
||||||
|
# error "Unknown HZ from arch/alpha/Kconfig"
|
||||||
|
#endif
|
||||||
|
if (sel) {
|
||||||
|
printk(KERN_INFO "Setting RTC_FREQ to %d Hz (%x)\n",
|
||||||
|
CONFIG_HZ, sel);
|
||||||
|
CMOS_WRITE(sel, RTC_FREQ_SELECT);
|
||||||
|
}
|
||||||
|
|
||||||
/* Turn on periodic interrupts. */
|
/* Turn on periodic interrupts. */
|
||||||
x = CMOS_READ(RTC_CONTROL);
|
x = CMOS_READ(RTC_CONTROL);
|
||||||
@ -233,16 +250,37 @@ common_init_rtc(void)
|
|||||||
init_rtc_irq();
|
init_rtc_irq();
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int common_get_rtc_time(struct rtc_time *time)
|
|
||||||
|
#ifndef CONFIG_ALPHA_WTINT
|
||||||
|
/*
|
||||||
|
* The RPCC as a clocksource primitive.
|
||||||
|
*
|
||||||
|
* While we have free-running timecounters running on all CPUs, and we make
|
||||||
|
* a half-hearted attempt in init_rtc_rpcc_info to sync the timecounter
|
||||||
|
* with the wall clock, that initialization isn't kept up-to-date across
|
||||||
|
* different time counters in SMP mode. Therefore we can only use this
|
||||||
|
* method when there's only one CPU enabled.
|
||||||
|
*
|
||||||
|
* When using the WTINT PALcall, the RPCC may shift to a lower frequency,
|
||||||
|
* or stop altogether, while waiting for the interrupt. Therefore we cannot
|
||||||
|
* use this method when WTINT is in use.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static cycle_t read_rpcc(struct clocksource *cs)
|
||||||
{
|
{
|
||||||
return __get_rtc_time(time);
|
return rpcc();
|
||||||
}
|
}
|
||||||
|
|
||||||
int common_set_rtc_time(struct rtc_time *time)
|
static struct clocksource clocksource_rpcc = {
|
||||||
{
|
.name = "rpcc",
|
||||||
return __set_rtc_time(time);
|
.rating = 300,
|
||||||
}
|
.read = read_rpcc,
|
||||||
|
.mask = CLOCKSOURCE_MASK(32),
|
||||||
|
.flags = CLOCK_SOURCE_IS_CONTINUOUS
|
||||||
|
};
|
||||||
|
#endif /* ALPHA_WTINT */
|
||||||
|
|
||||||
|
|
||||||
/* Validate a computed cycle counter result against the known bounds for
|
/* Validate a computed cycle counter result against the known bounds for
|
||||||
the given processor core. There's too much brokenness in the way of
|
the given processor core. There's too much brokenness in the way of
|
||||||
timing hardware for any one method to work everywhere. :-(
|
timing hardware for any one method to work everywhere. :-(
|
||||||
@ -353,33 +391,6 @@ rpcc_after_update_in_progress(void)
|
|||||||
return rpcc();
|
return rpcc();
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef CONFIG_SMP
|
|
||||||
/* Until and unless we figure out how to get cpu cycle counters
|
|
||||||
in sync and keep them there, we can't use the rpcc. */
|
|
||||||
static cycle_t read_rpcc(struct clocksource *cs)
|
|
||||||
{
|
|
||||||
cycle_t ret = (cycle_t)rpcc();
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct clocksource clocksource_rpcc = {
|
|
||||||
.name = "rpcc",
|
|
||||||
.rating = 300,
|
|
||||||
.read = read_rpcc,
|
|
||||||
.mask = CLOCKSOURCE_MASK(32),
|
|
||||||
.flags = CLOCK_SOURCE_IS_CONTINUOUS
|
|
||||||
};
|
|
||||||
|
|
||||||
static inline void register_rpcc_clocksource(long cycle_freq)
|
|
||||||
{
|
|
||||||
clocksource_register_hz(&clocksource_rpcc, cycle_freq);
|
|
||||||
}
|
|
||||||
#else /* !CONFIG_SMP */
|
|
||||||
static inline void register_rpcc_clocksource(long cycle_freq)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
#endif /* !CONFIG_SMP */
|
|
||||||
|
|
||||||
void __init
|
void __init
|
||||||
time_init(void)
|
time_init(void)
|
||||||
{
|
{
|
||||||
@ -387,6 +398,15 @@ time_init(void)
|
|||||||
unsigned long cycle_freq, tolerance;
|
unsigned long cycle_freq, tolerance;
|
||||||
long diff;
|
long diff;
|
||||||
|
|
||||||
|
if (alpha_using_qemu) {
|
||||||
|
clocksource_register_hz(&qemu_cs, NSEC_PER_SEC);
|
||||||
|
init_qemu_clockevent();
|
||||||
|
|
||||||
|
timer_irqaction.handler = qemu_timer_interrupt;
|
||||||
|
init_rtc_irq();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/* Calibrate CPU clock -- attempt #1. */
|
/* Calibrate CPU clock -- attempt #1. */
|
||||||
if (!est_cycle_freq)
|
if (!est_cycle_freq)
|
||||||
est_cycle_freq = validate_cc_value(calibrate_cc_with_pit());
|
est_cycle_freq = validate_cc_value(calibrate_cc_with_pit());
|
||||||
@ -421,100 +441,25 @@ time_init(void)
|
|||||||
"and unable to estimate a proper value!\n");
|
"and unable to estimate a proper value!\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* From John Bowman <bowman@math.ualberta.ca>: allow the values
|
/* See above for restrictions on using clocksource_rpcc. */
|
||||||
to settle, as the Update-In-Progress bit going low isn't good
|
#ifndef CONFIG_ALPHA_WTINT
|
||||||
enough on some hardware. 2ms is our guess; we haven't found
|
if (hwrpb->nr_processors == 1)
|
||||||
bogomips yet, but this is close on a 500Mhz box. */
|
clocksource_register_hz(&clocksource_rpcc, cycle_freq);
|
||||||
__delay(1000000);
|
#endif
|
||||||
|
|
||||||
|
|
||||||
if (HZ > (1<<16)) {
|
|
||||||
extern void __you_loose (void);
|
|
||||||
__you_loose();
|
|
||||||
}
|
|
||||||
|
|
||||||
register_rpcc_clocksource(cycle_freq);
|
|
||||||
|
|
||||||
state.last_time = cc1;
|
|
||||||
state.scaled_ticks_per_cycle
|
|
||||||
= ((unsigned long) HZ << FIX_SHIFT) / cycle_freq;
|
|
||||||
state.partial_tick = 0L;
|
|
||||||
|
|
||||||
/* Startup the timer source. */
|
/* Startup the timer source. */
|
||||||
alpha_mv.init_rtc();
|
alpha_mv.init_rtc();
|
||||||
|
init_rtc_clockevent();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/* Initialize the clock_event_device for secondary cpus. */
|
||||||
* In order to set the CMOS clock precisely, set_rtc_mmss has to be
|
#ifdef CONFIG_SMP
|
||||||
* called 500 ms after the second nowtime has started, because when
|
void __init
|
||||||
* nowtime is written into the registers of the CMOS clock, it will
|
init_clockevent(void)
|
||||||
* jump to the next second precisely 500 ms later. Check the Motorola
|
|
||||||
* MC146818A or Dallas DS12887 data sheet for details.
|
|
||||||
*
|
|
||||||
* BUG: This routine does not handle hour overflow properly; it just
|
|
||||||
* sets the minutes. Usually you won't notice until after reboot!
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
static int
|
|
||||||
set_rtc_mmss(unsigned long nowtime)
|
|
||||||
{
|
{
|
||||||
int retval = 0;
|
if (alpha_using_qemu)
|
||||||
int real_seconds, real_minutes, cmos_minutes;
|
init_qemu_clockevent();
|
||||||
unsigned char save_control, save_freq_select;
|
else
|
||||||
|
init_rtc_clockevent();
|
||||||
/* irq are locally disabled here */
|
|
||||||
spin_lock(&rtc_lock);
|
|
||||||
/* Tell the clock it's being set */
|
|
||||||
save_control = CMOS_READ(RTC_CONTROL);
|
|
||||||
CMOS_WRITE((save_control|RTC_SET), RTC_CONTROL);
|
|
||||||
|
|
||||||
/* Stop and reset prescaler */
|
|
||||||
save_freq_select = CMOS_READ(RTC_FREQ_SELECT);
|
|
||||||
CMOS_WRITE((save_freq_select|RTC_DIV_RESET2), RTC_FREQ_SELECT);
|
|
||||||
|
|
||||||
cmos_minutes = CMOS_READ(RTC_MINUTES);
|
|
||||||
if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD)
|
|
||||||
cmos_minutes = bcd2bin(cmos_minutes);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* since we're only adjusting minutes and seconds,
|
|
||||||
* don't interfere with hour overflow. This avoids
|
|
||||||
* messing with unknown time zones but requires your
|
|
||||||
* RTC not to be off by more than 15 minutes
|
|
||||||
*/
|
|
||||||
real_seconds = nowtime % 60;
|
|
||||||
real_minutes = nowtime / 60;
|
|
||||||
if (((abs(real_minutes - cmos_minutes) + 15)/30) & 1) {
|
|
||||||
/* correct for half hour time zone */
|
|
||||||
real_minutes += 30;
|
|
||||||
}
|
|
||||||
real_minutes %= 60;
|
|
||||||
|
|
||||||
if (abs(real_minutes - cmos_minutes) < 30) {
|
|
||||||
if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) {
|
|
||||||
real_seconds = bin2bcd(real_seconds);
|
|
||||||
real_minutes = bin2bcd(real_minutes);
|
|
||||||
}
|
|
||||||
CMOS_WRITE(real_seconds,RTC_SECONDS);
|
|
||||||
CMOS_WRITE(real_minutes,RTC_MINUTES);
|
|
||||||
} else {
|
|
||||||
printk_once(KERN_NOTICE
|
|
||||||
"set_rtc_mmss: can't update from %d to %d\n",
|
|
||||||
cmos_minutes, real_minutes);
|
|
||||||
retval = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* The following flags have to be released exactly in this order,
|
|
||||||
* otherwise the DS12887 (popular MC146818A clone with integrated
|
|
||||||
* battery and quartz) will not reset the oscillator and will not
|
|
||||||
* update precisely 500 ms later. You won't find this mentioned in
|
|
||||||
* the Dallas Semiconductor data sheets, but who believes data
|
|
||||||
* sheets anyway ... -- Markus Kuhn
|
|
||||||
*/
|
|
||||||
CMOS_WRITE(save_control, RTC_CONTROL);
|
|
||||||
CMOS_WRITE(save_freq_select, RTC_FREQ_SELECT);
|
|
||||||
spin_unlock(&rtc_lock);
|
|
||||||
|
|
||||||
return retval;
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
@ -241,6 +241,21 @@ do_entIF(unsigned long type, struct pt_regs *regs)
|
|||||||
(const char *)(data[1] | (long)data[2] << 32),
|
(const char *)(data[1] | (long)data[2] << 32),
|
||||||
data[0]);
|
data[0]);
|
||||||
}
|
}
|
||||||
|
#ifdef CONFIG_ALPHA_WTINT
|
||||||
|
if (type == 4) {
|
||||||
|
/* If CALL_PAL WTINT is totally unsupported by the
|
||||||
|
PALcode, e.g. MILO, "emulate" it by overwriting
|
||||||
|
the insn. */
|
||||||
|
unsigned int *pinsn
|
||||||
|
= (unsigned int *) regs->pc - 1;
|
||||||
|
if (*pinsn == PAL_wtint) {
|
||||||
|
*pinsn = 0x47e01400; /* mov 0,$0 */
|
||||||
|
imb();
|
||||||
|
regs->r0 = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* ALPHA_WTINT */
|
||||||
die_if_kernel((type == 1 ? "Kernel Bug" : "Instruction fault"),
|
die_if_kernel((type == 1 ? "Kernel Bug" : "Instruction fault"),
|
||||||
regs, type, NULL);
|
regs, type, NULL);
|
||||||
}
|
}
|
||||||
|
@ -130,7 +130,7 @@ csum_partial_cfu_aligned(const unsigned long __user *src, unsigned long *dst,
|
|||||||
*dst = word | tmp;
|
*dst = word | tmp;
|
||||||
checksum += carry;
|
checksum += carry;
|
||||||
}
|
}
|
||||||
if (err) *errp = err;
|
if (err && errp) *errp = err;
|
||||||
return checksum;
|
return checksum;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -185,7 +185,7 @@ csum_partial_cfu_dest_aligned(const unsigned long __user *src,
|
|||||||
*dst = word | tmp;
|
*dst = word | tmp;
|
||||||
checksum += carry;
|
checksum += carry;
|
||||||
}
|
}
|
||||||
if (err) *errp = err;
|
if (err && errp) *errp = err;
|
||||||
return checksum;
|
return checksum;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -242,7 +242,7 @@ csum_partial_cfu_src_aligned(const unsigned long __user *src,
|
|||||||
stq_u(partial_dest | second_dest, dst);
|
stq_u(partial_dest | second_dest, dst);
|
||||||
out:
|
out:
|
||||||
checksum += carry;
|
checksum += carry;
|
||||||
if (err) *errp = err;
|
if (err && errp) *errp = err;
|
||||||
return checksum;
|
return checksum;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -325,7 +325,7 @@ csum_partial_cfu_unaligned(const unsigned long __user * src,
|
|||||||
stq_u(partial_dest | word | second_dest, dst);
|
stq_u(partial_dest | word | second_dest, dst);
|
||||||
checksum += carry;
|
checksum += carry;
|
||||||
}
|
}
|
||||||
if (err) *errp = err;
|
if (err && errp) *errp = err;
|
||||||
return checksum;
|
return checksum;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -339,7 +339,7 @@ csum_partial_copy_from_user(const void __user *src, void *dst, int len,
|
|||||||
|
|
||||||
if (len) {
|
if (len) {
|
||||||
if (!access_ok(VERIFY_READ, src, len)) {
|
if (!access_ok(VERIFY_READ, src, len)) {
|
||||||
*errp = -EFAULT;
|
if (errp) *errp = -EFAULT;
|
||||||
memset(dst, 0, len);
|
memset(dst, 0, len);
|
||||||
return sum;
|
return sum;
|
||||||
}
|
}
|
||||||
|
@ -30,14 +30,15 @@
|
|||||||
.set noat
|
.set noat
|
||||||
.set noreorder
|
.set noreorder
|
||||||
.text
|
.text
|
||||||
|
.globl memset
|
||||||
.globl __memset
|
.globl __memset
|
||||||
|
.globl ___memset
|
||||||
.globl __memsetw
|
.globl __memsetw
|
||||||
.globl __constant_c_memset
|
.globl __constant_c_memset
|
||||||
.globl memset
|
|
||||||
|
|
||||||
.ent __memset
|
.ent ___memset
|
||||||
.align 5
|
.align 5
|
||||||
__memset:
|
___memset:
|
||||||
.frame $30,0,$26,0
|
.frame $30,0,$26,0
|
||||||
.prologue 0
|
.prologue 0
|
||||||
|
|
||||||
@ -227,7 +228,7 @@ end_b:
|
|||||||
nop
|
nop
|
||||||
nop
|
nop
|
||||||
ret $31,($26),1 # L0 :
|
ret $31,($26),1 # L0 :
|
||||||
.end __memset
|
.end ___memset
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This is the original body of code, prior to replication and
|
* This is the original body of code, prior to replication and
|
||||||
@ -594,4 +595,5 @@ end_w:
|
|||||||
|
|
||||||
.end __memsetw
|
.end __memsetw
|
||||||
|
|
||||||
memset = __memset
|
memset = ___memset
|
||||||
|
__memset = ___memset
|
||||||
|
@ -19,11 +19,13 @@
|
|||||||
.text
|
.text
|
||||||
.globl memset
|
.globl memset
|
||||||
.globl __memset
|
.globl __memset
|
||||||
|
.globl ___memset
|
||||||
.globl __memsetw
|
.globl __memsetw
|
||||||
.globl __constant_c_memset
|
.globl __constant_c_memset
|
||||||
.ent __memset
|
|
||||||
|
.ent ___memset
|
||||||
.align 5
|
.align 5
|
||||||
__memset:
|
___memset:
|
||||||
.frame $30,0,$26,0
|
.frame $30,0,$26,0
|
||||||
.prologue 0
|
.prologue 0
|
||||||
|
|
||||||
@ -103,7 +105,7 @@ within_one_quad:
|
|||||||
|
|
||||||
end:
|
end:
|
||||||
ret $31,($26),1 /* E1 */
|
ret $31,($26),1 /* E1 */
|
||||||
.end __memset
|
.end ___memset
|
||||||
|
|
||||||
.align 5
|
.align 5
|
||||||
.ent __memsetw
|
.ent __memsetw
|
||||||
@ -121,4 +123,5 @@ __memsetw:
|
|||||||
|
|
||||||
.end __memsetw
|
.end __memsetw
|
||||||
|
|
||||||
memset = __memset
|
memset = ___memset
|
||||||
|
__memset = ___memset
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
config ARC
|
config ARC
|
||||||
def_bool y
|
def_bool y
|
||||||
|
select BUILDTIME_EXTABLE_SORT
|
||||||
select CLONE_BACKWARDS
|
select CLONE_BACKWARDS
|
||||||
# ARC Busybox based initramfs absolutely relies on DEVTMPFS for /dev
|
# ARC Busybox based initramfs absolutely relies on DEVTMPFS for /dev
|
||||||
select DEVTMPFS if !INITRAMFS_SOURCE=""
|
select DEVTMPFS if !INITRAMFS_SOURCE=""
|
||||||
|
@ -43,124 +43,124 @@
|
|||||||
iomux: iomux@FF10601c {
|
iomux: iomux@FF10601c {
|
||||||
/* Port 1 */
|
/* Port 1 */
|
||||||
pctl_tsin_s0: pctl-tsin-s0 { /* Serial TS-in 0 */
|
pctl_tsin_s0: pctl-tsin-s0 { /* Serial TS-in 0 */
|
||||||
pingrp = "mis0_pins";
|
abilis,function = "mis0";
|
||||||
};
|
};
|
||||||
pctl_tsin_s1: pctl-tsin-s1 { /* Serial TS-in 1 */
|
pctl_tsin_s1: pctl-tsin-s1 { /* Serial TS-in 1 */
|
||||||
pingrp = "mis1_pins";
|
abilis,function = "mis1";
|
||||||
};
|
};
|
||||||
pctl_gpio_a: pctl-gpio-a { /* GPIO bank A */
|
pctl_gpio_a: pctl-gpio-a { /* GPIO bank A */
|
||||||
pingrp = "gpioa_pins";
|
abilis,function = "gpioa";
|
||||||
};
|
};
|
||||||
pctl_tsin_p1: pctl-tsin-p1 { /* Parallel TS-in 1 */
|
pctl_tsin_p1: pctl-tsin-p1 { /* Parallel TS-in 1 */
|
||||||
pingrp = "mip1_pins";
|
abilis,function = "mip1";
|
||||||
};
|
};
|
||||||
/* Port 2 */
|
/* Port 2 */
|
||||||
pctl_tsin_s2: pctl-tsin-s2 { /* Serial TS-in 2 */
|
pctl_tsin_s2: pctl-tsin-s2 { /* Serial TS-in 2 */
|
||||||
pingrp = "mis2_pins";
|
abilis,function = "mis2";
|
||||||
};
|
};
|
||||||
pctl_tsin_s3: pctl-tsin-s3 { /* Serial TS-in 3 */
|
pctl_tsin_s3: pctl-tsin-s3 { /* Serial TS-in 3 */
|
||||||
pingrp = "mis3_pins";
|
abilis,function = "mis3";
|
||||||
};
|
};
|
||||||
pctl_gpio_c: pctl-gpio-c { /* GPIO bank C */
|
pctl_gpio_c: pctl-gpio-c { /* GPIO bank C */
|
||||||
pingrp = "gpioc_pins";
|
abilis,function = "gpioc";
|
||||||
};
|
};
|
||||||
pctl_tsin_p3: pctl-tsin-p3 { /* Parallel TS-in 3 */
|
pctl_tsin_p3: pctl-tsin-p3 { /* Parallel TS-in 3 */
|
||||||
pingrp = "mip3_pins";
|
abilis,function = "mip3";
|
||||||
};
|
};
|
||||||
/* Port 3 */
|
/* Port 3 */
|
||||||
pctl_tsin_s4: pctl-tsin-s4 { /* Serial TS-in 4 */
|
pctl_tsin_s4: pctl-tsin-s4 { /* Serial TS-in 4 */
|
||||||
pingrp = "mis4_pins";
|
abilis,function = "mis4";
|
||||||
};
|
};
|
||||||
pctl_tsin_s5: pctl-tsin-s5 { /* Serial TS-in 5 */
|
pctl_tsin_s5: pctl-tsin-s5 { /* Serial TS-in 5 */
|
||||||
pingrp = "mis5_pins";
|
abilis,function = "mis5";
|
||||||
};
|
};
|
||||||
pctl_gpio_e: pctl-gpio-e { /* GPIO bank E */
|
pctl_gpio_e: pctl-gpio-e { /* GPIO bank E */
|
||||||
pingrp = "gpioe_pins";
|
abilis,function = "gpioe";
|
||||||
};
|
};
|
||||||
pctl_tsin_p5: pctl-tsin-p5 { /* Parallel TS-in 5 */
|
pctl_tsin_p5: pctl-tsin-p5 { /* Parallel TS-in 5 */
|
||||||
pingrp = "mip5_pins";
|
abilis,function = "mip5";
|
||||||
};
|
};
|
||||||
/* Port 4 */
|
/* Port 4 */
|
||||||
pctl_tsin_s6: pctl-tsin-s6 { /* Serial TS-in 6 */
|
pctl_tsin_s6: pctl-tsin-s6 { /* Serial TS-in 6 */
|
||||||
pingrp = "mis6_pins";
|
abilis,function = "mis6";
|
||||||
};
|
};
|
||||||
pctl_tsin_s7: pctl-tsin-s7 { /* Serial TS-in 7 */
|
pctl_tsin_s7: pctl-tsin-s7 { /* Serial TS-in 7 */
|
||||||
pingrp = "mis7_pins";
|
abilis,function = "mis7";
|
||||||
};
|
};
|
||||||
pctl_gpio_g: pctl-gpio-g { /* GPIO bank G */
|
pctl_gpio_g: pctl-gpio-g { /* GPIO bank G */
|
||||||
pingrp = "gpiog_pins";
|
abilis,function = "gpiog";
|
||||||
};
|
};
|
||||||
pctl_tsin_p7: pctl-tsin-p7 { /* Parallel TS-in 7 */
|
pctl_tsin_p7: pctl-tsin-p7 { /* Parallel TS-in 7 */
|
||||||
pingrp = "mip7_pins";
|
abilis,function = "mip7";
|
||||||
};
|
};
|
||||||
/* Port 5 */
|
/* Port 5 */
|
||||||
pctl_gpio_j: pctl-gpio-j { /* GPIO bank J */
|
pctl_gpio_j: pctl-gpio-j { /* GPIO bank J */
|
||||||
pingrp = "gpioj_pins";
|
abilis,function = "gpioj";
|
||||||
};
|
};
|
||||||
pctl_gpio_k: pctl-gpio-k { /* GPIO bank K */
|
pctl_gpio_k: pctl-gpio-k { /* GPIO bank K */
|
||||||
pingrp = "gpiok_pins";
|
abilis,function = "gpiok";
|
||||||
};
|
};
|
||||||
pctl_ciplus: pctl-ciplus { /* CI+ interface */
|
pctl_ciplus: pctl-ciplus { /* CI+ interface */
|
||||||
pingrp = "ciplus_pins";
|
abilis,function = "ciplus";
|
||||||
};
|
};
|
||||||
pctl_mcard: pctl-mcard { /* M-Card interface */
|
pctl_mcard: pctl-mcard { /* M-Card interface */
|
||||||
pingrp = "mcard_pins";
|
abilis,function = "mcard";
|
||||||
};
|
};
|
||||||
/* Port 6 */
|
/* Port 6 */
|
||||||
pctl_tsout_p: pctl-tsout-p { /* Parallel TS-out */
|
pctl_tsout_p: pctl-tsout-p { /* Parallel TS-out */
|
||||||
pingrp = "mop_pins";
|
abilis,function = "mop";
|
||||||
};
|
};
|
||||||
pctl_tsout_s0: pctl-tsout-s0 { /* Serial TS-out 0 */
|
pctl_tsout_s0: pctl-tsout-s0 { /* Serial TS-out 0 */
|
||||||
pingrp = "mos0_pins";
|
abilis,function = "mos0";
|
||||||
};
|
};
|
||||||
pctl_tsout_s1: pctl-tsout-s1 { /* Serial TS-out 1 */
|
pctl_tsout_s1: pctl-tsout-s1 { /* Serial TS-out 1 */
|
||||||
pingrp = "mos1_pins";
|
abilis,function = "mos1";
|
||||||
};
|
};
|
||||||
pctl_tsout_s2: pctl-tsout-s2 { /* Serial TS-out 2 */
|
pctl_tsout_s2: pctl-tsout-s2 { /* Serial TS-out 2 */
|
||||||
pingrp = "mos2_pins";
|
abilis,function = "mos2";
|
||||||
};
|
};
|
||||||
pctl_tsout_s3: pctl-tsout-s3 { /* Serial TS-out 3 */
|
pctl_tsout_s3: pctl-tsout-s3 { /* Serial TS-out 3 */
|
||||||
pingrp = "mos3_pins";
|
abilis,function = "mos3";
|
||||||
};
|
};
|
||||||
/* Port 7 */
|
/* Port 7 */
|
||||||
pctl_uart0: pctl-uart0 { /* UART 0 */
|
pctl_uart0: pctl-uart0 { /* UART 0 */
|
||||||
pingrp = "uart0_pins";
|
abilis,function = "uart0";
|
||||||
};
|
};
|
||||||
pctl_uart1: pctl-uart1 { /* UART 1 */
|
pctl_uart1: pctl-uart1 { /* UART 1 */
|
||||||
pingrp = "uart1_pins";
|
abilis,function = "uart1";
|
||||||
};
|
};
|
||||||
pctl_gpio_l: pctl-gpio-l { /* GPIO bank L */
|
pctl_gpio_l: pctl-gpio-l { /* GPIO bank L */
|
||||||
pingrp = "gpiol_pins";
|
abilis,function = "gpiol";
|
||||||
};
|
};
|
||||||
pctl_gpio_m: pctl-gpio-m { /* GPIO bank M */
|
pctl_gpio_m: pctl-gpio-m { /* GPIO bank M */
|
||||||
pingrp = "gpiom_pins";
|
abilis,function = "gpiom";
|
||||||
};
|
};
|
||||||
/* Port 8 */
|
/* Port 8 */
|
||||||
pctl_spi3: pctl-spi3 {
|
pctl_spi3: pctl-spi3 {
|
||||||
pingrp = "spi3_pins";
|
abilis,function = "spi3";
|
||||||
};
|
};
|
||||||
/* Port 9 */
|
/* Port 9 */
|
||||||
pctl_spi1: pctl-spi1 {
|
pctl_spi1: pctl-spi1 {
|
||||||
pingrp = "spi1_pins";
|
abilis,function = "spi1";
|
||||||
};
|
};
|
||||||
pctl_gpio_n: pctl-gpio-n {
|
pctl_gpio_n: pctl-gpio-n {
|
||||||
pingrp = "gpion_pins";
|
abilis,function = "gpion";
|
||||||
};
|
};
|
||||||
/* Unmuxed GPIOs */
|
/* Unmuxed GPIOs */
|
||||||
pctl_gpio_b: pctl-gpio-b {
|
pctl_gpio_b: pctl-gpio-b {
|
||||||
pingrp = "gpiob_pins";
|
abilis,function = "gpiob";
|
||||||
};
|
};
|
||||||
pctl_gpio_d: pctl-gpio-d {
|
pctl_gpio_d: pctl-gpio-d {
|
||||||
pingrp = "gpiod_pins";
|
abilis,function = "gpiod";
|
||||||
};
|
};
|
||||||
pctl_gpio_f: pctl-gpio-f {
|
pctl_gpio_f: pctl-gpio-f {
|
||||||
pingrp = "gpiof_pins";
|
abilis,function = "gpiof";
|
||||||
};
|
};
|
||||||
pctl_gpio_h: pctl-gpio-h {
|
pctl_gpio_h: pctl-gpio-h {
|
||||||
pingrp = "gpioh_pins";
|
abilis,function = "gpioh";
|
||||||
};
|
};
|
||||||
pctl_gpio_i: pctl-gpio-i {
|
pctl_gpio_i: pctl-gpio-i {
|
||||||
pingrp = "gpioi_pins";
|
abilis,function = "gpioi";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -172,9 +172,10 @@
|
|||||||
interrupts = <27 2>;
|
interrupts = <27 2>;
|
||||||
reg = <0xFF140000 0x1000>;
|
reg = <0xFF140000 0x1000>;
|
||||||
gpio-controller;
|
gpio-controller;
|
||||||
#gpio-cells = <1>;
|
#gpio-cells = <2>;
|
||||||
gpio-base = <0>;
|
abilis,ngpio = <3>;
|
||||||
gpio-pins = <&pctl_gpio_a>;
|
gpio-ranges = <&iomux 0 0 0>;
|
||||||
|
gpio-ranges-group-names = "gpioa";
|
||||||
};
|
};
|
||||||
gpiob: gpio@FF141000 {
|
gpiob: gpio@FF141000 {
|
||||||
compatible = "abilis,tb10x-gpio";
|
compatible = "abilis,tb10x-gpio";
|
||||||
@ -184,9 +185,10 @@
|
|||||||
interrupts = <27 2>;
|
interrupts = <27 2>;
|
||||||
reg = <0xFF141000 0x1000>;
|
reg = <0xFF141000 0x1000>;
|
||||||
gpio-controller;
|
gpio-controller;
|
||||||
#gpio-cells = <1>;
|
#gpio-cells = <2>;
|
||||||
gpio-base = <3>;
|
abilis,ngpio = <2>;
|
||||||
gpio-pins = <&pctl_gpio_b>;
|
gpio-ranges = <&iomux 0 0 0>;
|
||||||
|
gpio-ranges-group-names = "gpiob";
|
||||||
};
|
};
|
||||||
gpioc: gpio@FF142000 {
|
gpioc: gpio@FF142000 {
|
||||||
compatible = "abilis,tb10x-gpio";
|
compatible = "abilis,tb10x-gpio";
|
||||||
@ -196,9 +198,10 @@
|
|||||||
interrupts = <27 2>;
|
interrupts = <27 2>;
|
||||||
reg = <0xFF142000 0x1000>;
|
reg = <0xFF142000 0x1000>;
|
||||||
gpio-controller;
|
gpio-controller;
|
||||||
#gpio-cells = <1>;
|
#gpio-cells = <2>;
|
||||||
gpio-base = <5>;
|
abilis,ngpio = <3>;
|
||||||
gpio-pins = <&pctl_gpio_c>;
|
gpio-ranges = <&iomux 0 0 0>;
|
||||||
|
gpio-ranges-group-names = "gpioc";
|
||||||
};
|
};
|
||||||
gpiod: gpio@FF143000 {
|
gpiod: gpio@FF143000 {
|
||||||
compatible = "abilis,tb10x-gpio";
|
compatible = "abilis,tb10x-gpio";
|
||||||
@ -208,9 +211,10 @@
|
|||||||
interrupts = <27 2>;
|
interrupts = <27 2>;
|
||||||
reg = <0xFF143000 0x1000>;
|
reg = <0xFF143000 0x1000>;
|
||||||
gpio-controller;
|
gpio-controller;
|
||||||
#gpio-cells = <1>;
|
#gpio-cells = <2>;
|
||||||
gpio-base = <8>;
|
abilis,ngpio = <2>;
|
||||||
gpio-pins = <&pctl_gpio_d>;
|
gpio-ranges = <&iomux 0 0 0>;
|
||||||
|
gpio-ranges-group-names = "gpiod";
|
||||||
};
|
};
|
||||||
gpioe: gpio@FF144000 {
|
gpioe: gpio@FF144000 {
|
||||||
compatible = "abilis,tb10x-gpio";
|
compatible = "abilis,tb10x-gpio";
|
||||||
@ -220,9 +224,10 @@
|
|||||||
interrupts = <27 2>;
|
interrupts = <27 2>;
|
||||||
reg = <0xFF144000 0x1000>;
|
reg = <0xFF144000 0x1000>;
|
||||||
gpio-controller;
|
gpio-controller;
|
||||||
#gpio-cells = <1>;
|
#gpio-cells = <2>;
|
||||||
gpio-base = <10>;
|
abilis,ngpio = <3>;
|
||||||
gpio-pins = <&pctl_gpio_e>;
|
gpio-ranges = <&iomux 0 0 0>;
|
||||||
|
gpio-ranges-group-names = "gpioe";
|
||||||
};
|
};
|
||||||
gpiof: gpio@FF145000 {
|
gpiof: gpio@FF145000 {
|
||||||
compatible = "abilis,tb10x-gpio";
|
compatible = "abilis,tb10x-gpio";
|
||||||
@ -232,9 +237,10 @@
|
|||||||
interrupts = <27 2>;
|
interrupts = <27 2>;
|
||||||
reg = <0xFF145000 0x1000>;
|
reg = <0xFF145000 0x1000>;
|
||||||
gpio-controller;
|
gpio-controller;
|
||||||
#gpio-cells = <1>;
|
#gpio-cells = <2>;
|
||||||
gpio-base = <13>;
|
abilis,ngpio = <2>;
|
||||||
gpio-pins = <&pctl_gpio_f>;
|
gpio-ranges = <&iomux 0 0 0>;
|
||||||
|
gpio-ranges-group-names = "gpiof";
|
||||||
};
|
};
|
||||||
gpiog: gpio@FF146000 {
|
gpiog: gpio@FF146000 {
|
||||||
compatible = "abilis,tb10x-gpio";
|
compatible = "abilis,tb10x-gpio";
|
||||||
@ -244,9 +250,10 @@
|
|||||||
interrupts = <27 2>;
|
interrupts = <27 2>;
|
||||||
reg = <0xFF146000 0x1000>;
|
reg = <0xFF146000 0x1000>;
|
||||||
gpio-controller;
|
gpio-controller;
|
||||||
#gpio-cells = <1>;
|
#gpio-cells = <2>;
|
||||||
gpio-base = <15>;
|
abilis,ngpio = <3>;
|
||||||
gpio-pins = <&pctl_gpio_g>;
|
gpio-ranges = <&iomux 0 0 0>;
|
||||||
|
gpio-ranges-group-names = "gpiog";
|
||||||
};
|
};
|
||||||
gpioh: gpio@FF147000 {
|
gpioh: gpio@FF147000 {
|
||||||
compatible = "abilis,tb10x-gpio";
|
compatible = "abilis,tb10x-gpio";
|
||||||
@ -256,9 +263,10 @@
|
|||||||
interrupts = <27 2>;
|
interrupts = <27 2>;
|
||||||
reg = <0xFF147000 0x1000>;
|
reg = <0xFF147000 0x1000>;
|
||||||
gpio-controller;
|
gpio-controller;
|
||||||
#gpio-cells = <1>;
|
#gpio-cells = <2>;
|
||||||
gpio-base = <18>;
|
abilis,ngpio = <2>;
|
||||||
gpio-pins = <&pctl_gpio_h>;
|
gpio-ranges = <&iomux 0 0 0>;
|
||||||
|
gpio-ranges-group-names = "gpioh";
|
||||||
};
|
};
|
||||||
gpioi: gpio@FF148000 {
|
gpioi: gpio@FF148000 {
|
||||||
compatible = "abilis,tb10x-gpio";
|
compatible = "abilis,tb10x-gpio";
|
||||||
@ -268,9 +276,10 @@
|
|||||||
interrupts = <27 2>;
|
interrupts = <27 2>;
|
||||||
reg = <0xFF148000 0x1000>;
|
reg = <0xFF148000 0x1000>;
|
||||||
gpio-controller;
|
gpio-controller;
|
||||||
#gpio-cells = <1>;
|
#gpio-cells = <2>;
|
||||||
gpio-base = <20>;
|
abilis,ngpio = <12>;
|
||||||
gpio-pins = <&pctl_gpio_i>;
|
gpio-ranges = <&iomux 0 0 0>;
|
||||||
|
gpio-ranges-group-names = "gpioi";
|
||||||
};
|
};
|
||||||
gpioj: gpio@FF149000 {
|
gpioj: gpio@FF149000 {
|
||||||
compatible = "abilis,tb10x-gpio";
|
compatible = "abilis,tb10x-gpio";
|
||||||
@ -280,9 +289,10 @@
|
|||||||
interrupts = <27 2>;
|
interrupts = <27 2>;
|
||||||
reg = <0xFF149000 0x1000>;
|
reg = <0xFF149000 0x1000>;
|
||||||
gpio-controller;
|
gpio-controller;
|
||||||
#gpio-cells = <1>;
|
#gpio-cells = <2>;
|
||||||
gpio-base = <32>;
|
abilis,ngpio = <32>;
|
||||||
gpio-pins = <&pctl_gpio_j>;
|
gpio-ranges = <&iomux 0 0 0>;
|
||||||
|
gpio-ranges-group-names = "gpioj";
|
||||||
};
|
};
|
||||||
gpiok: gpio@FF14a000 {
|
gpiok: gpio@FF14a000 {
|
||||||
compatible = "abilis,tb10x-gpio";
|
compatible = "abilis,tb10x-gpio";
|
||||||
@ -292,9 +302,10 @@
|
|||||||
interrupts = <27 2>;
|
interrupts = <27 2>;
|
||||||
reg = <0xFF14A000 0x1000>;
|
reg = <0xFF14A000 0x1000>;
|
||||||
gpio-controller;
|
gpio-controller;
|
||||||
#gpio-cells = <1>;
|
#gpio-cells = <2>;
|
||||||
gpio-base = <64>;
|
abilis,ngpio = <22>;
|
||||||
gpio-pins = <&pctl_gpio_k>;
|
gpio-ranges = <&iomux 0 0 0>;
|
||||||
|
gpio-ranges-group-names = "gpiok";
|
||||||
};
|
};
|
||||||
gpiol: gpio@FF14b000 {
|
gpiol: gpio@FF14b000 {
|
||||||
compatible = "abilis,tb10x-gpio";
|
compatible = "abilis,tb10x-gpio";
|
||||||
@ -304,9 +315,10 @@
|
|||||||
interrupts = <27 2>;
|
interrupts = <27 2>;
|
||||||
reg = <0xFF14B000 0x1000>;
|
reg = <0xFF14B000 0x1000>;
|
||||||
gpio-controller;
|
gpio-controller;
|
||||||
#gpio-cells = <1>;
|
#gpio-cells = <2>;
|
||||||
gpio-base = <86>;
|
abilis,ngpio = <4>;
|
||||||
gpio-pins = <&pctl_gpio_l>;
|
gpio-ranges = <&iomux 0 0 0>;
|
||||||
|
gpio-ranges-group-names = "gpiol";
|
||||||
};
|
};
|
||||||
gpiom: gpio@FF14c000 {
|
gpiom: gpio@FF14c000 {
|
||||||
compatible = "abilis,tb10x-gpio";
|
compatible = "abilis,tb10x-gpio";
|
||||||
@ -316,9 +328,10 @@
|
|||||||
interrupts = <27 2>;
|
interrupts = <27 2>;
|
||||||
reg = <0xFF14C000 0x1000>;
|
reg = <0xFF14C000 0x1000>;
|
||||||
gpio-controller;
|
gpio-controller;
|
||||||
#gpio-cells = <1>;
|
#gpio-cells = <2>;
|
||||||
gpio-base = <90>;
|
abilis,ngpio = <4>;
|
||||||
gpio-pins = <&pctl_gpio_m>;
|
gpio-ranges = <&iomux 0 0 0>;
|
||||||
|
gpio-ranges-group-names = "gpiom";
|
||||||
};
|
};
|
||||||
gpion: gpio@FF14d000 {
|
gpion: gpio@FF14d000 {
|
||||||
compatible = "abilis,tb10x-gpio";
|
compatible = "abilis,tb10x-gpio";
|
||||||
@ -328,9 +341,10 @@
|
|||||||
interrupts = <27 2>;
|
interrupts = <27 2>;
|
||||||
reg = <0xFF14D000 0x1000>;
|
reg = <0xFF14D000 0x1000>;
|
||||||
gpio-controller;
|
gpio-controller;
|
||||||
#gpio-cells = <1>;
|
#gpio-cells = <2>;
|
||||||
gpio-base = <94>;
|
abilis,ngpio = <5>;
|
||||||
gpio-pins = <&pctl_gpio_n>;
|
gpio-ranges = <&iomux 0 0 0>;
|
||||||
|
gpio-ranges-group-names = "gpion";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -64,62 +64,62 @@
|
|||||||
compatible = "gpio-leds";
|
compatible = "gpio-leds";
|
||||||
power {
|
power {
|
||||||
label = "Power";
|
label = "Power";
|
||||||
gpios = <&gpioi 0>;
|
gpios = <&gpioi 0 0>;
|
||||||
linux,default-trigger = "default-on";
|
linux,default-trigger = "default-on";
|
||||||
};
|
};
|
||||||
heartbeat {
|
heartbeat {
|
||||||
label = "Heartbeat";
|
label = "Heartbeat";
|
||||||
gpios = <&gpioi 1>;
|
gpios = <&gpioi 1 0>;
|
||||||
linux,default-trigger = "heartbeat";
|
linux,default-trigger = "heartbeat";
|
||||||
};
|
};
|
||||||
led2 {
|
led2 {
|
||||||
label = "LED2";
|
label = "LED2";
|
||||||
gpios = <&gpioi 2>;
|
gpios = <&gpioi 2 0>;
|
||||||
default-state = "off";
|
default-state = "off";
|
||||||
};
|
};
|
||||||
led3 {
|
led3 {
|
||||||
label = "LED3";
|
label = "LED3";
|
||||||
gpios = <&gpioi 3>;
|
gpios = <&gpioi 3 0>;
|
||||||
default-state = "off";
|
default-state = "off";
|
||||||
};
|
};
|
||||||
led4 {
|
led4 {
|
||||||
label = "LED4";
|
label = "LED4";
|
||||||
gpios = <&gpioi 4>;
|
gpios = <&gpioi 4 0>;
|
||||||
default-state = "off";
|
default-state = "off";
|
||||||
};
|
};
|
||||||
led5 {
|
led5 {
|
||||||
label = "LED5";
|
label = "LED5";
|
||||||
gpios = <&gpioi 5>;
|
gpios = <&gpioi 5 0>;
|
||||||
default-state = "off";
|
default-state = "off";
|
||||||
};
|
};
|
||||||
led6 {
|
led6 {
|
||||||
label = "LED6";
|
label = "LED6";
|
||||||
gpios = <&gpioi 6>;
|
gpios = <&gpioi 6 0>;
|
||||||
default-state = "off";
|
default-state = "off";
|
||||||
};
|
};
|
||||||
led7 {
|
led7 {
|
||||||
label = "LED7";
|
label = "LED7";
|
||||||
gpios = <&gpioi 7>;
|
gpios = <&gpioi 7 0>;
|
||||||
default-state = "off";
|
default-state = "off";
|
||||||
};
|
};
|
||||||
led8 {
|
led8 {
|
||||||
label = "LED8";
|
label = "LED8";
|
||||||
gpios = <&gpioi 8>;
|
gpios = <&gpioi 8 0>;
|
||||||
default-state = "off";
|
default-state = "off";
|
||||||
};
|
};
|
||||||
led9 {
|
led9 {
|
||||||
label = "LED9";
|
label = "LED9";
|
||||||
gpios = <&gpioi 9>;
|
gpios = <&gpioi 9 0>;
|
||||||
default-state = "off";
|
default-state = "off";
|
||||||
};
|
};
|
||||||
led10 {
|
led10 {
|
||||||
label = "LED10";
|
label = "LED10";
|
||||||
gpios = <&gpioi 10>;
|
gpios = <&gpioi 10 0>;
|
||||||
default-state = "off";
|
default-state = "off";
|
||||||
};
|
};
|
||||||
led11 {
|
led11 {
|
||||||
label = "LED11";
|
label = "LED11";
|
||||||
gpios = <&gpioi 11>;
|
gpios = <&gpioi 11 0>;
|
||||||
default-state = "off";
|
default-state = "off";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -43,133 +43,133 @@
|
|||||||
iomux: iomux@FF10601c {
|
iomux: iomux@FF10601c {
|
||||||
/* Port 1 */
|
/* Port 1 */
|
||||||
pctl_tsin_s0: pctl-tsin-s0 { /* Serial TS-in 0 */
|
pctl_tsin_s0: pctl-tsin-s0 { /* Serial TS-in 0 */
|
||||||
pingrp = "mis0_pins";
|
abilis,function = "mis0";
|
||||||
};
|
};
|
||||||
pctl_tsin_s1: pctl-tsin-s1 { /* Serial TS-in 1 */
|
pctl_tsin_s1: pctl-tsin-s1 { /* Serial TS-in 1 */
|
||||||
pingrp = "mis1_pins";
|
abilis,function = "mis1";
|
||||||
};
|
};
|
||||||
pctl_gpio_a: pctl-gpio-a { /* GPIO bank A */
|
pctl_gpio_a: pctl-gpio-a { /* GPIO bank A */
|
||||||
pingrp = "gpioa_pins";
|
abilis,function = "gpioa";
|
||||||
};
|
};
|
||||||
pctl_tsin_p1: pctl-tsin-p1 { /* Parallel TS-in 1 */
|
pctl_tsin_p1: pctl-tsin-p1 { /* Parallel TS-in 1 */
|
||||||
pingrp = "mip1_pins";
|
abilis,function = "mip1";
|
||||||
};
|
};
|
||||||
/* Port 2 */
|
/* Port 2 */
|
||||||
pctl_tsin_s2: pctl-tsin-s2 { /* Serial TS-in 2 */
|
pctl_tsin_s2: pctl-tsin-s2 { /* Serial TS-in 2 */
|
||||||
pingrp = "mis2_pins";
|
abilis,function = "mis2";
|
||||||
};
|
};
|
||||||
pctl_tsin_s3: pctl-tsin-s3 { /* Serial TS-in 3 */
|
pctl_tsin_s3: pctl-tsin-s3 { /* Serial TS-in 3 */
|
||||||
pingrp = "mis3_pins";
|
abilis,function = "mis3";
|
||||||
};
|
};
|
||||||
pctl_gpio_c: pctl-gpio-c { /* GPIO bank C */
|
pctl_gpio_c: pctl-gpio-c { /* GPIO bank C */
|
||||||
pingrp = "gpioc_pins";
|
abilis,function = "gpioc";
|
||||||
};
|
};
|
||||||
pctl_tsin_p3: pctl-tsin-p3 { /* Parallel TS-in 3 */
|
pctl_tsin_p3: pctl-tsin-p3 { /* Parallel TS-in 3 */
|
||||||
pingrp = "mip3_pins";
|
abilis,function = "mip3";
|
||||||
};
|
};
|
||||||
/* Port 3 */
|
/* Port 3 */
|
||||||
pctl_tsin_s4: pctl-tsin-s4 { /* Serial TS-in 4 */
|
pctl_tsin_s4: pctl-tsin-s4 { /* Serial TS-in 4 */
|
||||||
pingrp = "mis4_pins";
|
abilis,function = "mis4";
|
||||||
};
|
};
|
||||||
pctl_tsin_s5: pctl-tsin-s5 { /* Serial TS-in 5 */
|
pctl_tsin_s5: pctl-tsin-s5 { /* Serial TS-in 5 */
|
||||||
pingrp = "mis5_pins";
|
abilis,function = "mis5";
|
||||||
};
|
};
|
||||||
pctl_gpio_e: pctl-gpio-e { /* GPIO bank E */
|
pctl_gpio_e: pctl-gpio-e { /* GPIO bank E */
|
||||||
pingrp = "gpioe_pins";
|
abilis,function = "gpioe";
|
||||||
};
|
};
|
||||||
pctl_tsin_p5: pctl-tsin-p5 { /* Parallel TS-in 5 */
|
pctl_tsin_p5: pctl-tsin-p5 { /* Parallel TS-in 5 */
|
||||||
pingrp = "mip5_pins";
|
abilis,function = "mip5";
|
||||||
};
|
};
|
||||||
/* Port 4 */
|
/* Port 4 */
|
||||||
pctl_tsin_s6: pctl-tsin-s6 { /* Serial TS-in 6 */
|
pctl_tsin_s6: pctl-tsin-s6 { /* Serial TS-in 6 */
|
||||||
pingrp = "mis6_pins";
|
abilis,function = "mis6";
|
||||||
};
|
};
|
||||||
pctl_tsin_s7: pctl-tsin-s7 { /* Serial TS-in 7 */
|
pctl_tsin_s7: pctl-tsin-s7 { /* Serial TS-in 7 */
|
||||||
pingrp = "mis7_pins";
|
abilis,function = "mis7";
|
||||||
};
|
};
|
||||||
pctl_gpio_g: pctl-gpio-g { /* GPIO bank G */
|
pctl_gpio_g: pctl-gpio-g { /* GPIO bank G */
|
||||||
pingrp = "gpiog_pins";
|
abilis,function = "gpiog";
|
||||||
};
|
};
|
||||||
pctl_tsin_p7: pctl-tsin-p7 { /* Parallel TS-in 7 */
|
pctl_tsin_p7: pctl-tsin-p7 { /* Parallel TS-in 7 */
|
||||||
pingrp = "mip7_pins";
|
abilis,function = "mip7";
|
||||||
};
|
};
|
||||||
/* Port 5 */
|
/* Port 5 */
|
||||||
pctl_gpio_j: pctl-gpio-j { /* GPIO bank J */
|
pctl_gpio_j: pctl-gpio-j { /* GPIO bank J */
|
||||||
pingrp = "gpioj_pins";
|
abilis,function = "gpioj";
|
||||||
};
|
};
|
||||||
pctl_gpio_k: pctl-gpio-k { /* GPIO bank K */
|
pctl_gpio_k: pctl-gpio-k { /* GPIO bank K */
|
||||||
pingrp = "gpiok_pins";
|
abilis,function = "gpiok";
|
||||||
};
|
};
|
||||||
pctl_ciplus: pctl-ciplus { /* CI+ interface */
|
pctl_ciplus: pctl-ciplus { /* CI+ interface */
|
||||||
pingrp = "ciplus_pins";
|
abilis,function = "ciplus";
|
||||||
};
|
};
|
||||||
pctl_mcard: pctl-mcard { /* M-Card interface */
|
pctl_mcard: pctl-mcard { /* M-Card interface */
|
||||||
pingrp = "mcard_pins";
|
abilis,function = "mcard";
|
||||||
};
|
};
|
||||||
pctl_stc0: pctl-stc0 { /* Smart card I/F 0 */
|
pctl_stc0: pctl-stc0 { /* Smart card I/F 0 */
|
||||||
pingrp = "stc0_pins";
|
abilis,function = "stc0";
|
||||||
};
|
};
|
||||||
pctl_stc1: pctl-stc1 { /* Smart card I/F 1 */
|
pctl_stc1: pctl-stc1 { /* Smart card I/F 1 */
|
||||||
pingrp = "stc1_pins";
|
abilis,function = "stc1";
|
||||||
};
|
};
|
||||||
/* Port 6 */
|
/* Port 6 */
|
||||||
pctl_tsout_p: pctl-tsout-p { /* Parallel TS-out */
|
pctl_tsout_p: pctl-tsout-p { /* Parallel TS-out */
|
||||||
pingrp = "mop_pins";
|
abilis,function = "mop";
|
||||||
};
|
};
|
||||||
pctl_tsout_s0: pctl-tsout-s0 { /* Serial TS-out 0 */
|
pctl_tsout_s0: pctl-tsout-s0 { /* Serial TS-out 0 */
|
||||||
pingrp = "mos0_pins";
|
abilis,function = "mos0";
|
||||||
};
|
};
|
||||||
pctl_tsout_s1: pctl-tsout-s1 { /* Serial TS-out 1 */
|
pctl_tsout_s1: pctl-tsout-s1 { /* Serial TS-out 1 */
|
||||||
pingrp = "mos1_pins";
|
abilis,function = "mos1";
|
||||||
};
|
};
|
||||||
pctl_tsout_s2: pctl-tsout-s2 { /* Serial TS-out 2 */
|
pctl_tsout_s2: pctl-tsout-s2 { /* Serial TS-out 2 */
|
||||||
pingrp = "mos2_pins";
|
abilis,function = "mos2";
|
||||||
};
|
};
|
||||||
pctl_tsout_s3: pctl-tsout-s3 { /* Serial TS-out 3 */
|
pctl_tsout_s3: pctl-tsout-s3 { /* Serial TS-out 3 */
|
||||||
pingrp = "mos3_pins";
|
abilis,function = "mos3";
|
||||||
};
|
};
|
||||||
/* Port 7 */
|
/* Port 7 */
|
||||||
pctl_uart0: pctl-uart0 { /* UART 0 */
|
pctl_uart0: pctl-uart0 { /* UART 0 */
|
||||||
pingrp = "uart0_pins";
|
abilis,function = "uart0";
|
||||||
};
|
};
|
||||||
pctl_uart1: pctl-uart1 { /* UART 1 */
|
pctl_uart1: pctl-uart1 { /* UART 1 */
|
||||||
pingrp = "uart1_pins";
|
abilis,function = "uart1";
|
||||||
};
|
};
|
||||||
pctl_gpio_l: pctl-gpio-l { /* GPIO bank L */
|
pctl_gpio_l: pctl-gpio-l { /* GPIO bank L */
|
||||||
pingrp = "gpiol_pins";
|
abilis,function = "gpiol";
|
||||||
};
|
};
|
||||||
pctl_gpio_m: pctl-gpio-m { /* GPIO bank M */
|
pctl_gpio_m: pctl-gpio-m { /* GPIO bank M */
|
||||||
pingrp = "gpiom_pins";
|
abilis,function = "gpiom";
|
||||||
};
|
};
|
||||||
/* Port 8 */
|
/* Port 8 */
|
||||||
pctl_spi3: pctl-spi3 {
|
pctl_spi3: pctl-spi3 {
|
||||||
pingrp = "spi3_pins";
|
abilis,function = "spi3";
|
||||||
};
|
};
|
||||||
pctl_jtag: pctl-jtag {
|
pctl_jtag: pctl-jtag {
|
||||||
pingrp = "jtag_pins";
|
abilis,function = "jtag";
|
||||||
};
|
};
|
||||||
/* Port 9 */
|
/* Port 9 */
|
||||||
pctl_spi1: pctl-spi1 {
|
pctl_spi1: pctl-spi1 {
|
||||||
pingrp = "spi1_pins";
|
abilis,function = "spi1";
|
||||||
};
|
};
|
||||||
pctl_gpio_n: pctl-gpio-n {
|
pctl_gpio_n: pctl-gpio-n {
|
||||||
pingrp = "gpion_pins";
|
abilis,function = "gpion";
|
||||||
};
|
};
|
||||||
/* Unmuxed GPIOs */
|
/* Unmuxed GPIOs */
|
||||||
pctl_gpio_b: pctl-gpio-b {
|
pctl_gpio_b: pctl-gpio-b {
|
||||||
pingrp = "gpiob_pins";
|
abilis,function = "gpiob";
|
||||||
};
|
};
|
||||||
pctl_gpio_d: pctl-gpio-d {
|
pctl_gpio_d: pctl-gpio-d {
|
||||||
pingrp = "gpiod_pins";
|
abilis,function = "gpiod";
|
||||||
};
|
};
|
||||||
pctl_gpio_f: pctl-gpio-f {
|
pctl_gpio_f: pctl-gpio-f {
|
||||||
pingrp = "gpiof_pins";
|
abilis,function = "gpiof";
|
||||||
};
|
};
|
||||||
pctl_gpio_h: pctl-gpio-h {
|
pctl_gpio_h: pctl-gpio-h {
|
||||||
pingrp = "gpioh_pins";
|
abilis,function = "gpioh";
|
||||||
};
|
};
|
||||||
pctl_gpio_i: pctl-gpio-i {
|
pctl_gpio_i: pctl-gpio-i {
|
||||||
pingrp = "gpioi_pins";
|
abilis,function = "gpioi";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -181,9 +181,10 @@
|
|||||||
interrupts = <27 2>;
|
interrupts = <27 2>;
|
||||||
reg = <0xFF140000 0x1000>;
|
reg = <0xFF140000 0x1000>;
|
||||||
gpio-controller;
|
gpio-controller;
|
||||||
#gpio-cells = <1>;
|
#gpio-cells = <2>;
|
||||||
gpio-base = <0>;
|
abilis,ngpio = <3>;
|
||||||
gpio-pins = <&pctl_gpio_a>;
|
gpio-ranges = <&iomux 0 0 0>;
|
||||||
|
gpio-ranges-group-names = "gpioa";
|
||||||
};
|
};
|
||||||
gpiob: gpio@FF141000 {
|
gpiob: gpio@FF141000 {
|
||||||
compatible = "abilis,tb10x-gpio";
|
compatible = "abilis,tb10x-gpio";
|
||||||
@ -193,9 +194,10 @@
|
|||||||
interrupts = <27 2>;
|
interrupts = <27 2>;
|
||||||
reg = <0xFF141000 0x1000>;
|
reg = <0xFF141000 0x1000>;
|
||||||
gpio-controller;
|
gpio-controller;
|
||||||
#gpio-cells = <1>;
|
#gpio-cells = <2>;
|
||||||
gpio-base = <3>;
|
abilis,ngpio = <2>;
|
||||||
gpio-pins = <&pctl_gpio_b>;
|
gpio-ranges = <&iomux 0 0 0>;
|
||||||
|
gpio-ranges-group-names = "gpiob";
|
||||||
};
|
};
|
||||||
gpioc: gpio@FF142000 {
|
gpioc: gpio@FF142000 {
|
||||||
compatible = "abilis,tb10x-gpio";
|
compatible = "abilis,tb10x-gpio";
|
||||||
@ -205,9 +207,10 @@
|
|||||||
interrupts = <27 2>;
|
interrupts = <27 2>;
|
||||||
reg = <0xFF142000 0x1000>;
|
reg = <0xFF142000 0x1000>;
|
||||||
gpio-controller;
|
gpio-controller;
|
||||||
#gpio-cells = <1>;
|
#gpio-cells = <2>;
|
||||||
gpio-base = <5>;
|
abilis,ngpio = <3>;
|
||||||
gpio-pins = <&pctl_gpio_c>;
|
gpio-ranges = <&iomux 0 0 0>;
|
||||||
|
gpio-ranges-group-names = "gpioc";
|
||||||
};
|
};
|
||||||
gpiod: gpio@FF143000 {
|
gpiod: gpio@FF143000 {
|
||||||
compatible = "abilis,tb10x-gpio";
|
compatible = "abilis,tb10x-gpio";
|
||||||
@ -217,9 +220,10 @@
|
|||||||
interrupts = <27 2>;
|
interrupts = <27 2>;
|
||||||
reg = <0xFF143000 0x1000>;
|
reg = <0xFF143000 0x1000>;
|
||||||
gpio-controller;
|
gpio-controller;
|
||||||
#gpio-cells = <1>;
|
#gpio-cells = <2>;
|
||||||
gpio-base = <8>;
|
abilis,ngpio = <2>;
|
||||||
gpio-pins = <&pctl_gpio_d>;
|
gpio-ranges = <&iomux 0 0 0>;
|
||||||
|
gpio-ranges-group-names = "gpiod";
|
||||||
};
|
};
|
||||||
gpioe: gpio@FF144000 {
|
gpioe: gpio@FF144000 {
|
||||||
compatible = "abilis,tb10x-gpio";
|
compatible = "abilis,tb10x-gpio";
|
||||||
@ -229,9 +233,10 @@
|
|||||||
interrupts = <27 2>;
|
interrupts = <27 2>;
|
||||||
reg = <0xFF144000 0x1000>;
|
reg = <0xFF144000 0x1000>;
|
||||||
gpio-controller;
|
gpio-controller;
|
||||||
#gpio-cells = <1>;
|
#gpio-cells = <2>;
|
||||||
gpio-base = <10>;
|
abilis,ngpio = <3>;
|
||||||
gpio-pins = <&pctl_gpio_e>;
|
gpio-ranges = <&iomux 0 0 0>;
|
||||||
|
gpio-ranges-group-names = "gpioe";
|
||||||
};
|
};
|
||||||
gpiof: gpio@FF145000 {
|
gpiof: gpio@FF145000 {
|
||||||
compatible = "abilis,tb10x-gpio";
|
compatible = "abilis,tb10x-gpio";
|
||||||
@ -241,9 +246,10 @@
|
|||||||
interrupts = <27 2>;
|
interrupts = <27 2>;
|
||||||
reg = <0xFF145000 0x1000>;
|
reg = <0xFF145000 0x1000>;
|
||||||
gpio-controller;
|
gpio-controller;
|
||||||
#gpio-cells = <1>;
|
#gpio-cells = <2>;
|
||||||
gpio-base = <13>;
|
abilis,ngpio = <2>;
|
||||||
gpio-pins = <&pctl_gpio_f>;
|
gpio-ranges = <&iomux 0 0 0>;
|
||||||
|
gpio-ranges-group-names = "gpiof";
|
||||||
};
|
};
|
||||||
gpiog: gpio@FF146000 {
|
gpiog: gpio@FF146000 {
|
||||||
compatible = "abilis,tb10x-gpio";
|
compatible = "abilis,tb10x-gpio";
|
||||||
@ -253,9 +259,10 @@
|
|||||||
interrupts = <27 2>;
|
interrupts = <27 2>;
|
||||||
reg = <0xFF146000 0x1000>;
|
reg = <0xFF146000 0x1000>;
|
||||||
gpio-controller;
|
gpio-controller;
|
||||||
#gpio-cells = <1>;
|
#gpio-cells = <2>;
|
||||||
gpio-base = <15>;
|
abilis,ngpio = <3>;
|
||||||
gpio-pins = <&pctl_gpio_g>;
|
gpio-ranges = <&iomux 0 0 0>;
|
||||||
|
gpio-ranges-group-names = "gpiog";
|
||||||
};
|
};
|
||||||
gpioh: gpio@FF147000 {
|
gpioh: gpio@FF147000 {
|
||||||
compatible = "abilis,tb10x-gpio";
|
compatible = "abilis,tb10x-gpio";
|
||||||
@ -265,9 +272,10 @@
|
|||||||
interrupts = <27 2>;
|
interrupts = <27 2>;
|
||||||
reg = <0xFF147000 0x1000>;
|
reg = <0xFF147000 0x1000>;
|
||||||
gpio-controller;
|
gpio-controller;
|
||||||
#gpio-cells = <1>;
|
#gpio-cells = <2>;
|
||||||
gpio-base = <18>;
|
abilis,ngpio = <2>;
|
||||||
gpio-pins = <&pctl_gpio_h>;
|
gpio-ranges = <&iomux 0 0 0>;
|
||||||
|
gpio-ranges-group-names = "gpioh";
|
||||||
};
|
};
|
||||||
gpioi: gpio@FF148000 {
|
gpioi: gpio@FF148000 {
|
||||||
compatible = "abilis,tb10x-gpio";
|
compatible = "abilis,tb10x-gpio";
|
||||||
@ -277,9 +285,10 @@
|
|||||||
interrupts = <27 2>;
|
interrupts = <27 2>;
|
||||||
reg = <0xFF148000 0x1000>;
|
reg = <0xFF148000 0x1000>;
|
||||||
gpio-controller;
|
gpio-controller;
|
||||||
#gpio-cells = <1>;
|
#gpio-cells = <2>;
|
||||||
gpio-base = <20>;
|
abilis,ngpio = <12>;
|
||||||
gpio-pins = <&pctl_gpio_i>;
|
gpio-ranges = <&iomux 0 0 0>;
|
||||||
|
gpio-ranges-group-names = "gpioi";
|
||||||
};
|
};
|
||||||
gpioj: gpio@FF149000 {
|
gpioj: gpio@FF149000 {
|
||||||
compatible = "abilis,tb10x-gpio";
|
compatible = "abilis,tb10x-gpio";
|
||||||
@ -289,9 +298,10 @@
|
|||||||
interrupts = <27 2>;
|
interrupts = <27 2>;
|
||||||
reg = <0xFF149000 0x1000>;
|
reg = <0xFF149000 0x1000>;
|
||||||
gpio-controller;
|
gpio-controller;
|
||||||
#gpio-cells = <1>;
|
#gpio-cells = <2>;
|
||||||
gpio-base = <32>;
|
abilis,ngpio = <32>;
|
||||||
gpio-pins = <&pctl_gpio_j>;
|
gpio-ranges = <&iomux 0 0 0>;
|
||||||
|
gpio-ranges-group-names = "gpioj";
|
||||||
};
|
};
|
||||||
gpiok: gpio@FF14a000 {
|
gpiok: gpio@FF14a000 {
|
||||||
compatible = "abilis,tb10x-gpio";
|
compatible = "abilis,tb10x-gpio";
|
||||||
@ -301,9 +311,10 @@
|
|||||||
interrupts = <27 2>;
|
interrupts = <27 2>;
|
||||||
reg = <0xFF14A000 0x1000>;
|
reg = <0xFF14A000 0x1000>;
|
||||||
gpio-controller;
|
gpio-controller;
|
||||||
#gpio-cells = <1>;
|
#gpio-cells = <2>;
|
||||||
gpio-base = <64>;
|
abilis,ngpio = <22>;
|
||||||
gpio-pins = <&pctl_gpio_k>;
|
gpio-ranges = <&iomux 0 0 0>;
|
||||||
|
gpio-ranges-group-names = "gpiok";
|
||||||
};
|
};
|
||||||
gpiol: gpio@FF14b000 {
|
gpiol: gpio@FF14b000 {
|
||||||
compatible = "abilis,tb10x-gpio";
|
compatible = "abilis,tb10x-gpio";
|
||||||
@ -313,9 +324,10 @@
|
|||||||
interrupts = <27 2>;
|
interrupts = <27 2>;
|
||||||
reg = <0xFF14B000 0x1000>;
|
reg = <0xFF14B000 0x1000>;
|
||||||
gpio-controller;
|
gpio-controller;
|
||||||
#gpio-cells = <1>;
|
#gpio-cells = <2>;
|
||||||
gpio-base = <86>;
|
abilis,ngpio = <4>;
|
||||||
gpio-pins = <&pctl_gpio_l>;
|
gpio-ranges = <&iomux 0 0 0>;
|
||||||
|
gpio-ranges-group-names = "gpiol";
|
||||||
};
|
};
|
||||||
gpiom: gpio@FF14c000 {
|
gpiom: gpio@FF14c000 {
|
||||||
compatible = "abilis,tb10x-gpio";
|
compatible = "abilis,tb10x-gpio";
|
||||||
@ -325,9 +337,10 @@
|
|||||||
interrupts = <27 2>;
|
interrupts = <27 2>;
|
||||||
reg = <0xFF14C000 0x1000>;
|
reg = <0xFF14C000 0x1000>;
|
||||||
gpio-controller;
|
gpio-controller;
|
||||||
#gpio-cells = <1>;
|
#gpio-cells = <2>;
|
||||||
gpio-base = <90>;
|
abilis,ngpio = <4>;
|
||||||
gpio-pins = <&pctl_gpio_m>;
|
gpio-ranges = <&iomux 0 0 0>;
|
||||||
|
gpio-ranges-group-names = "gpiom";
|
||||||
};
|
};
|
||||||
gpion: gpio@FF14d000 {
|
gpion: gpio@FF14d000 {
|
||||||
compatible = "abilis,tb10x-gpio";
|
compatible = "abilis,tb10x-gpio";
|
||||||
@ -337,9 +350,10 @@
|
|||||||
interrupts = <27 2>;
|
interrupts = <27 2>;
|
||||||
reg = <0xFF14D000 0x1000>;
|
reg = <0xFF14D000 0x1000>;
|
||||||
gpio-controller;
|
gpio-controller;
|
||||||
#gpio-cells = <1>;
|
#gpio-cells = <2>;
|
||||||
gpio-base = <94>;
|
abilis,ngpio = <5>;
|
||||||
gpio-pins = <&pctl_gpio_n>;
|
gpio-ranges = <&iomux 0 0 0>;
|
||||||
|
gpio-ranges-group-names = "gpion";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -64,62 +64,62 @@
|
|||||||
compatible = "gpio-leds";
|
compatible = "gpio-leds";
|
||||||
power {
|
power {
|
||||||
label = "Power";
|
label = "Power";
|
||||||
gpios = <&gpioi 0>;
|
gpios = <&gpioi 0 0>;
|
||||||
linux,default-trigger = "default-on";
|
linux,default-trigger = "default-on";
|
||||||
};
|
};
|
||||||
heartbeat {
|
heartbeat {
|
||||||
label = "Heartbeat";
|
label = "Heartbeat";
|
||||||
gpios = <&gpioi 1>;
|
gpios = <&gpioi 1 0>;
|
||||||
linux,default-trigger = "heartbeat";
|
linux,default-trigger = "heartbeat";
|
||||||
};
|
};
|
||||||
led2 {
|
led2 {
|
||||||
label = "LED2";
|
label = "LED2";
|
||||||
gpios = <&gpioi 2>;
|
gpios = <&gpioi 2 0>;
|
||||||
default-state = "off";
|
default-state = "off";
|
||||||
};
|
};
|
||||||
led3 {
|
led3 {
|
||||||
label = "LED3";
|
label = "LED3";
|
||||||
gpios = <&gpioi 3>;
|
gpios = <&gpioi 3 0>;
|
||||||
default-state = "off";
|
default-state = "off";
|
||||||
};
|
};
|
||||||
led4 {
|
led4 {
|
||||||
label = "LED4";
|
label = "LED4";
|
||||||
gpios = <&gpioi 4>;
|
gpios = <&gpioi 4 0>;
|
||||||
default-state = "off";
|
default-state = "off";
|
||||||
};
|
};
|
||||||
led5 {
|
led5 {
|
||||||
label = "LED5";
|
label = "LED5";
|
||||||
gpios = <&gpioi 5>;
|
gpios = <&gpioi 5 0>;
|
||||||
default-state = "off";
|
default-state = "off";
|
||||||
};
|
};
|
||||||
led6 {
|
led6 {
|
||||||
label = "LED6";
|
label = "LED6";
|
||||||
gpios = <&gpioi 6>;
|
gpios = <&gpioi 6 0>;
|
||||||
default-state = "off";
|
default-state = "off";
|
||||||
};
|
};
|
||||||
led7 {
|
led7 {
|
||||||
label = "LED7";
|
label = "LED7";
|
||||||
gpios = <&gpioi 7>;
|
gpios = <&gpioi 7 0>;
|
||||||
default-state = "off";
|
default-state = "off";
|
||||||
};
|
};
|
||||||
led8 {
|
led8 {
|
||||||
label = "LED8";
|
label = "LED8";
|
||||||
gpios = <&gpioi 8>;
|
gpios = <&gpioi 8 0>;
|
||||||
default-state = "off";
|
default-state = "off";
|
||||||
};
|
};
|
||||||
led9 {
|
led9 {
|
||||||
label = "LED9";
|
label = "LED9";
|
||||||
gpios = <&gpioi 9>;
|
gpios = <&gpioi 9 0>;
|
||||||
default-state = "off";
|
default-state = "off";
|
||||||
};
|
};
|
||||||
led10 {
|
led10 {
|
||||||
label = "LED10";
|
label = "LED10";
|
||||||
gpios = <&gpioi 10>;
|
gpios = <&gpioi 10 0>;
|
||||||
default-state = "off";
|
default-state = "off";
|
||||||
};
|
};
|
||||||
led11 {
|
led11 {
|
||||||
label = "LED11";
|
label = "LED11";
|
||||||
gpios = <&gpioi 11>;
|
gpios = <&gpioi 11 0>;
|
||||||
default-state = "off";
|
default-state = "off";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -62,9 +62,8 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
iomux: iomux@FF10601c {
|
iomux: iomux@FF10601c {
|
||||||
#address-cells = <1>;
|
|
||||||
#size-cells = <1>;
|
|
||||||
compatible = "abilis,tb10x-iomux";
|
compatible = "abilis,tb10x-iomux";
|
||||||
|
#gpio-range-cells = <3>;
|
||||||
reg = <0xFF10601c 0x4>;
|
reg = <0xFF10601c 0x4>;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -67,5 +67,9 @@
|
|||||||
reg = <1>;
|
reg = <1>;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
arcpmu0: pmu {
|
||||||
|
compatible = "snps,arc700-pmu";
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
64
arch/arc/configs/fpga_noramfs_defconfig
Normal file
64
arch/arc/configs/fpga_noramfs_defconfig
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
CONFIG_CROSS_COMPILE="arc-linux-uclibc-"
|
||||||
|
# CONFIG_LOCALVERSION_AUTO is not set
|
||||||
|
CONFIG_DEFAULT_HOSTNAME="ARCLinux"
|
||||||
|
# CONFIG_SWAP is not set
|
||||||
|
CONFIG_HIGH_RES_TIMERS=y
|
||||||
|
CONFIG_IKCONFIG=y
|
||||||
|
CONFIG_IKCONFIG_PROC=y
|
||||||
|
CONFIG_NAMESPACES=y
|
||||||
|
# CONFIG_UTS_NS is not set
|
||||||
|
# CONFIG_PID_NS is not set
|
||||||
|
CONFIG_BLK_DEV_INITRD=y
|
||||||
|
CONFIG_KALLSYMS_ALL=y
|
||||||
|
CONFIG_EMBEDDED=y
|
||||||
|
# CONFIG_SLUB_DEBUG is not set
|
||||||
|
# CONFIG_COMPAT_BRK is not set
|
||||||
|
CONFIG_KPROBES=y
|
||||||
|
CONFIG_MODULES=y
|
||||||
|
# CONFIG_LBDAF is not set
|
||||||
|
# CONFIG_BLK_DEV_BSG is not set
|
||||||
|
# CONFIG_IOSCHED_DEADLINE is not set
|
||||||
|
# CONFIG_IOSCHED_CFQ is not set
|
||||||
|
CONFIG_ARC_PLAT_FPGA_LEGACY=y
|
||||||
|
CONFIG_ARC_BOARD_ML509=y
|
||||||
|
# CONFIG_ARC_HAS_RTSC is not set
|
||||||
|
CONFIG_ARC_BUILTIN_DTB_NAME="angel4"
|
||||||
|
CONFIG_PREEMPT=y
|
||||||
|
# CONFIG_COMPACTION is not set
|
||||||
|
# CONFIG_CROSS_MEMORY_ATTACH is not set
|
||||||
|
CONFIG_NET=y
|
||||||
|
CONFIG_PACKET=y
|
||||||
|
CONFIG_UNIX=y
|
||||||
|
CONFIG_UNIX_DIAG=y
|
||||||
|
CONFIG_NET_KEY=y
|
||||||
|
CONFIG_INET=y
|
||||||
|
# CONFIG_IPV6 is not set
|
||||||
|
# CONFIG_STANDALONE is not set
|
||||||
|
# CONFIG_PREVENT_FIRMWARE_BUILD is not set
|
||||||
|
# CONFIG_FIRMWARE_IN_KERNEL is not set
|
||||||
|
# CONFIG_BLK_DEV is not set
|
||||||
|
CONFIG_NETDEVICES=y
|
||||||
|
CONFIG_ARC_EMAC=y
|
||||||
|
CONFIG_LXT_PHY=y
|
||||||
|
# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
|
||||||
|
# CONFIG_INPUT_KEYBOARD is not set
|
||||||
|
# CONFIG_INPUT_MOUSE is not set
|
||||||
|
# CONFIG_SERIO is not set
|
||||||
|
# CONFIG_LEGACY_PTYS is not set
|
||||||
|
# CONFIG_DEVKMEM is not set
|
||||||
|
CONFIG_SERIAL_ARC=y
|
||||||
|
CONFIG_SERIAL_ARC_CONSOLE=y
|
||||||
|
# CONFIG_HW_RANDOM is not set
|
||||||
|
# CONFIG_HWMON is not set
|
||||||
|
# CONFIG_VGA_CONSOLE is not set
|
||||||
|
# CONFIG_HID is not set
|
||||||
|
# CONFIG_USB_SUPPORT is not set
|
||||||
|
# CONFIG_IOMMU_SUPPORT is not set
|
||||||
|
CONFIG_EXT2_FS=y
|
||||||
|
CONFIG_EXT2_FS_XATTR=y
|
||||||
|
CONFIG_TMPFS=y
|
||||||
|
# CONFIG_MISC_FILESYSTEMS is not set
|
||||||
|
CONFIG_NFS_FS=y
|
||||||
|
# CONFIG_ENABLE_WARN_DEPRECATED is not set
|
||||||
|
# CONFIG_ENABLE_MUST_CHECK is not set
|
||||||
|
CONFIG_XZ_DEC=y
|
@ -1,5 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2011-2012 Synopsys, Inc. (www.synopsys.com)
|
* Linux performance counter support for ARC
|
||||||
|
*
|
||||||
|
* Copyright (C) 2011-2013 Synopsys, Inc. (www.synopsys.com)
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License version 2 as
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
@ -10,4 +12,204 @@
|
|||||||
#ifndef __ASM_PERF_EVENT_H
|
#ifndef __ASM_PERF_EVENT_H
|
||||||
#define __ASM_PERF_EVENT_H
|
#define __ASM_PERF_EVENT_H
|
||||||
|
|
||||||
|
/* real maximum varies per CPU, this is the maximum supported by the driver */
|
||||||
|
#define ARC_PMU_MAX_HWEVENTS 64
|
||||||
|
|
||||||
|
#define ARC_REG_CC_BUILD 0xF6
|
||||||
|
#define ARC_REG_CC_INDEX 0x240
|
||||||
|
#define ARC_REG_CC_NAME0 0x241
|
||||||
|
#define ARC_REG_CC_NAME1 0x242
|
||||||
|
|
||||||
|
#define ARC_REG_PCT_BUILD 0xF5
|
||||||
|
#define ARC_REG_PCT_COUNTL 0x250
|
||||||
|
#define ARC_REG_PCT_COUNTH 0x251
|
||||||
|
#define ARC_REG_PCT_SNAPL 0x252
|
||||||
|
#define ARC_REG_PCT_SNAPH 0x253
|
||||||
|
#define ARC_REG_PCT_CONFIG 0x254
|
||||||
|
#define ARC_REG_PCT_CONTROL 0x255
|
||||||
|
#define ARC_REG_PCT_INDEX 0x256
|
||||||
|
|
||||||
|
#define ARC_REG_PCT_CONTROL_CC (1 << 16) /* clear counts */
|
||||||
|
#define ARC_REG_PCT_CONTROL_SN (1 << 17) /* snapshot */
|
||||||
|
|
||||||
|
struct arc_reg_pct_build {
|
||||||
|
#ifdef CONFIG_CPU_BIG_ENDIAN
|
||||||
|
unsigned int m:8, c:8, r:6, s:2, v:8;
|
||||||
|
#else
|
||||||
|
unsigned int v:8, s:2, r:6, c:8, m:8;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
struct arc_reg_cc_build {
|
||||||
|
#ifdef CONFIG_CPU_BIG_ENDIAN
|
||||||
|
unsigned int c:16, r:8, v:8;
|
||||||
|
#else
|
||||||
|
unsigned int v:8, r:8, c:16;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
#define PERF_COUNT_ARC_DCLM (PERF_COUNT_HW_MAX + 0)
|
||||||
|
#define PERF_COUNT_ARC_DCSM (PERF_COUNT_HW_MAX + 1)
|
||||||
|
#define PERF_COUNT_ARC_ICM (PERF_COUNT_HW_MAX + 2)
|
||||||
|
#define PERF_COUNT_ARC_BPOK (PERF_COUNT_HW_MAX + 3)
|
||||||
|
#define PERF_COUNT_ARC_EDTLB (PERF_COUNT_HW_MAX + 4)
|
||||||
|
#define PERF_COUNT_ARC_EITLB (PERF_COUNT_HW_MAX + 5)
|
||||||
|
#define PERF_COUNT_ARC_HW_MAX (PERF_COUNT_HW_MAX + 6)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The "generalized" performance events seem to really be a copy
|
||||||
|
* of the available events on x86 processors; the mapping to ARC
|
||||||
|
* events is not always possible 1-to-1. Fortunately, there doesn't
|
||||||
|
* seem to be an exact definition for these events, so we can cheat
|
||||||
|
* a bit where necessary.
|
||||||
|
*
|
||||||
|
* In particular, the following PERF events may behave a bit differently
|
||||||
|
* compared to other architectures:
|
||||||
|
*
|
||||||
|
* PERF_COUNT_HW_CPU_CYCLES
|
||||||
|
* Cycles not in halted state
|
||||||
|
*
|
||||||
|
* PERF_COUNT_HW_REF_CPU_CYCLES
|
||||||
|
* Reference cycles not in halted state, same as PERF_COUNT_HW_CPU_CYCLES
|
||||||
|
* for now as we don't do Dynamic Voltage/Frequency Scaling (yet)
|
||||||
|
*
|
||||||
|
* PERF_COUNT_HW_BUS_CYCLES
|
||||||
|
* Unclear what this means, Intel uses 0x013c, which according to
|
||||||
|
* their datasheet means "unhalted reference cycles". It sounds similar
|
||||||
|
* to PERF_COUNT_HW_REF_CPU_CYCLES, and we use the same counter for it.
|
||||||
|
*
|
||||||
|
* PERF_COUNT_HW_STALLED_CYCLES_BACKEND
|
||||||
|
* PERF_COUNT_HW_STALLED_CYCLES_FRONTEND
|
||||||
|
* The ARC 700 can either measure stalls per pipeline stage, or all stalls
|
||||||
|
* combined; for now we assign all stalls to STALLED_CYCLES_BACKEND
|
||||||
|
* and all pipeline flushes (e.g. caused by mispredicts, etc.) to
|
||||||
|
* STALLED_CYCLES_FRONTEND.
|
||||||
|
*
|
||||||
|
* We could start multiple performance counters and combine everything
|
||||||
|
* afterwards, but that makes it complicated.
|
||||||
|
*
|
||||||
|
* Note that I$ cache misses aren't counted by either of the two!
|
||||||
|
*/
|
||||||
|
|
||||||
|
static const char * const arc_pmu_ev_hw_map[] = {
|
||||||
|
[PERF_COUNT_HW_CPU_CYCLES] = "crun",
|
||||||
|
[PERF_COUNT_HW_REF_CPU_CYCLES] = "crun",
|
||||||
|
[PERF_COUNT_HW_BUS_CYCLES] = "crun",
|
||||||
|
[PERF_COUNT_HW_INSTRUCTIONS] = "iall",
|
||||||
|
[PERF_COUNT_HW_BRANCH_MISSES] = "bpfail",
|
||||||
|
[PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = "ijmp",
|
||||||
|
[PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = "bflush",
|
||||||
|
[PERF_COUNT_HW_STALLED_CYCLES_BACKEND] = "bstall",
|
||||||
|
[PERF_COUNT_ARC_DCLM] = "dclm",
|
||||||
|
[PERF_COUNT_ARC_DCSM] = "dcsm",
|
||||||
|
[PERF_COUNT_ARC_ICM] = "icm",
|
||||||
|
[PERF_COUNT_ARC_BPOK] = "bpok",
|
||||||
|
[PERF_COUNT_ARC_EDTLB] = "edtlb",
|
||||||
|
[PERF_COUNT_ARC_EITLB] = "eitlb",
|
||||||
|
};
|
||||||
|
|
||||||
|
#define C(_x) PERF_COUNT_HW_CACHE_##_x
|
||||||
|
#define CACHE_OP_UNSUPPORTED 0xffff
|
||||||
|
|
||||||
|
static const unsigned arc_pmu_cache_map[C(MAX)][C(OP_MAX)][C(RESULT_MAX)] = {
|
||||||
|
[C(L1D)] = {
|
||||||
|
[C(OP_READ)] = {
|
||||||
|
[C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
|
||||||
|
[C(RESULT_MISS)] = PERF_COUNT_ARC_DCLM,
|
||||||
|
},
|
||||||
|
[C(OP_WRITE)] = {
|
||||||
|
[C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
|
||||||
|
[C(RESULT_MISS)] = PERF_COUNT_ARC_DCSM,
|
||||||
|
},
|
||||||
|
[C(OP_PREFETCH)] = {
|
||||||
|
[C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
|
||||||
|
[C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
[C(L1I)] = {
|
||||||
|
[C(OP_READ)] = {
|
||||||
|
[C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
|
||||||
|
[C(RESULT_MISS)] = PERF_COUNT_ARC_ICM,
|
||||||
|
},
|
||||||
|
[C(OP_WRITE)] = {
|
||||||
|
[C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
|
||||||
|
[C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
|
||||||
|
},
|
||||||
|
[C(OP_PREFETCH)] = {
|
||||||
|
[C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
|
||||||
|
[C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
[C(LL)] = {
|
||||||
|
[C(OP_READ)] = {
|
||||||
|
[C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
|
||||||
|
[C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
|
||||||
|
},
|
||||||
|
[C(OP_WRITE)] = {
|
||||||
|
[C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
|
||||||
|
[C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
|
||||||
|
},
|
||||||
|
[C(OP_PREFETCH)] = {
|
||||||
|
[C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
|
||||||
|
[C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
[C(DTLB)] = {
|
||||||
|
[C(OP_READ)] = {
|
||||||
|
[C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
|
||||||
|
[C(RESULT_MISS)] = PERF_COUNT_ARC_EDTLB,
|
||||||
|
},
|
||||||
|
[C(OP_WRITE)] = {
|
||||||
|
[C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
|
||||||
|
[C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
|
||||||
|
},
|
||||||
|
[C(OP_PREFETCH)] = {
|
||||||
|
[C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
|
||||||
|
[C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
[C(ITLB)] = {
|
||||||
|
[C(OP_READ)] = {
|
||||||
|
[C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
|
||||||
|
[C(RESULT_MISS)] = PERF_COUNT_ARC_EITLB,
|
||||||
|
},
|
||||||
|
[C(OP_WRITE)] = {
|
||||||
|
[C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
|
||||||
|
[C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
|
||||||
|
},
|
||||||
|
[C(OP_PREFETCH)] = {
|
||||||
|
[C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
|
||||||
|
[C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
[C(BPU)] = {
|
||||||
|
[C(OP_READ)] = {
|
||||||
|
[C(RESULT_ACCESS)] = PERF_COUNT_HW_BRANCH_INSTRUCTIONS,
|
||||||
|
[C(RESULT_MISS)] = PERF_COUNT_HW_BRANCH_MISSES,
|
||||||
|
},
|
||||||
|
[C(OP_WRITE)] = {
|
||||||
|
[C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
|
||||||
|
[C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
|
||||||
|
},
|
||||||
|
[C(OP_PREFETCH)] = {
|
||||||
|
[C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
|
||||||
|
[C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
[C(NODE)] = {
|
||||||
|
[C(OP_READ)] = {
|
||||||
|
[C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
|
||||||
|
[C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
|
||||||
|
},
|
||||||
|
[C(OP_WRITE)] = {
|
||||||
|
[C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
|
||||||
|
[C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
|
||||||
|
},
|
||||||
|
[C(OP_PREFETCH)] = {
|
||||||
|
[C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
|
||||||
|
[C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
#endif /* __ASM_PERF_EVENT_H */
|
#endif /* __ASM_PERF_EVENT_H */
|
||||||
|
@ -80,8 +80,6 @@ static inline __attribute_const__ struct thread_info *current_thread_info(void)
|
|||||||
|
|
||||||
#endif /* !__ASSEMBLY__ */
|
#endif /* !__ASSEMBLY__ */
|
||||||
|
|
||||||
#define PREEMPT_ACTIVE 0x10000000
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* thread information flags
|
* thread information flags
|
||||||
* - these are process state flags that various assembly files may need to
|
* - these are process state flags that various assembly files may need to
|
||||||
|
@ -8,6 +8,9 @@
|
|||||||
|
|
||||||
/******** no-legacy-syscalls-ABI *******/
|
/******** no-legacy-syscalls-ABI *******/
|
||||||
|
|
||||||
|
#ifndef _UAPI_ASM_ARC_UNISTD_H
|
||||||
|
#define _UAPI_ASM_ARC_UNISTD_H
|
||||||
|
|
||||||
#define __ARCH_WANT_SYS_EXECVE
|
#define __ARCH_WANT_SYS_EXECVE
|
||||||
#define __ARCH_WANT_SYS_CLONE
|
#define __ARCH_WANT_SYS_CLONE
|
||||||
#define __ARCH_WANT_SYS_VFORK
|
#define __ARCH_WANT_SYS_VFORK
|
||||||
@ -32,3 +35,5 @@ __SYSCALL(__NR_arc_gettls, sys_arc_gettls)
|
|||||||
/* Generic syscall (fs/filesystems.c - lost in asm-generic/unistd.h */
|
/* Generic syscall (fs/filesystems.c - lost in asm-generic/unistd.h */
|
||||||
#define __NR_sysfs (__NR_arch_specific_syscall + 3)
|
#define __NR_sysfs (__NR_arch_specific_syscall + 3)
|
||||||
__SYSCALL(__NR_sysfs, sys_sysfs)
|
__SYSCALL(__NR_sysfs, sys_sysfs)
|
||||||
|
|
||||||
|
#endif
|
||||||
|
@ -19,6 +19,7 @@ obj-$(CONFIG_KPROBES) += kprobes.o
|
|||||||
obj-$(CONFIG_ARC_MISALIGN_ACCESS) += unaligned.o
|
obj-$(CONFIG_ARC_MISALIGN_ACCESS) += unaligned.o
|
||||||
obj-$(CONFIG_KGDB) += kgdb.o
|
obj-$(CONFIG_KGDB) += kgdb.o
|
||||||
obj-$(CONFIG_ARC_METAWARE_HLINK) += arc_hostlink.o
|
obj-$(CONFIG_ARC_METAWARE_HLINK) += arc_hostlink.o
|
||||||
|
obj-$(CONFIG_PERF_EVENTS) += perf_event.o
|
||||||
|
|
||||||
obj-$(CONFIG_ARC_FPU_SAVE_RESTORE) += fpu.o
|
obj-$(CONFIG_ARC_FPU_SAVE_RESTORE) += fpu.o
|
||||||
CFLAGS_fpu.o += -mdpfp
|
CFLAGS_fpu.o += -mdpfp
|
||||||
|
326
arch/arc/kernel/perf_event.c
Normal file
326
arch/arc/kernel/perf_event.c
Normal file
@ -0,0 +1,326 @@
|
|||||||
|
/*
|
||||||
|
* Linux performance counter support for ARC700 series
|
||||||
|
*
|
||||||
|
* Copyright (C) 2013 Synopsys, Inc. (www.synopsys.com)
|
||||||
|
*
|
||||||
|
* This code is inspired by the perf support of various other architectures.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#include <linux/errno.h>
|
||||||
|
#include <linux/module.h>
|
||||||
|
#include <linux/of.h>
|
||||||
|
#include <linux/perf_event.h>
|
||||||
|
#include <linux/platform_device.h>
|
||||||
|
#include <asm/arcregs.h>
|
||||||
|
|
||||||
|
struct arc_pmu {
|
||||||
|
struct pmu pmu;
|
||||||
|
int counter_size; /* in bits */
|
||||||
|
int n_counters;
|
||||||
|
unsigned long used_mask[BITS_TO_LONGS(ARC_PMU_MAX_HWEVENTS)];
|
||||||
|
int ev_hw_idx[PERF_COUNT_ARC_HW_MAX];
|
||||||
|
};
|
||||||
|
|
||||||
|
/* read counter #idx; note that counter# != event# on ARC! */
|
||||||
|
static uint64_t arc_pmu_read_counter(int idx)
|
||||||
|
{
|
||||||
|
uint32_t tmp;
|
||||||
|
uint64_t result;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ARC supports making 'snapshots' of the counters, so we don't
|
||||||
|
* need to care about counters wrapping to 0 underneath our feet
|
||||||
|
*/
|
||||||
|
write_aux_reg(ARC_REG_PCT_INDEX, idx);
|
||||||
|
tmp = read_aux_reg(ARC_REG_PCT_CONTROL);
|
||||||
|
write_aux_reg(ARC_REG_PCT_CONTROL, tmp | ARC_REG_PCT_CONTROL_SN);
|
||||||
|
result = (uint64_t) (read_aux_reg(ARC_REG_PCT_SNAPH)) << 32;
|
||||||
|
result |= read_aux_reg(ARC_REG_PCT_SNAPL);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void arc_perf_event_update(struct perf_event *event,
|
||||||
|
struct hw_perf_event *hwc, int idx)
|
||||||
|
{
|
||||||
|
struct arc_pmu *arc_pmu = container_of(event->pmu, struct arc_pmu, pmu);
|
||||||
|
uint64_t prev_raw_count, new_raw_count;
|
||||||
|
int64_t delta;
|
||||||
|
|
||||||
|
do {
|
||||||
|
prev_raw_count = local64_read(&hwc->prev_count);
|
||||||
|
new_raw_count = arc_pmu_read_counter(idx);
|
||||||
|
} while (local64_cmpxchg(&hwc->prev_count, prev_raw_count,
|
||||||
|
new_raw_count) != prev_raw_count);
|
||||||
|
|
||||||
|
delta = (new_raw_count - prev_raw_count) &
|
||||||
|
((1ULL << arc_pmu->counter_size) - 1ULL);
|
||||||
|
|
||||||
|
local64_add(delta, &event->count);
|
||||||
|
local64_sub(delta, &hwc->period_left);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void arc_pmu_read(struct perf_event *event)
|
||||||
|
{
|
||||||
|
arc_perf_event_update(event, &event->hw, event->hw.idx);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int arc_pmu_cache_event(u64 config)
|
||||||
|
{
|
||||||
|
unsigned int cache_type, cache_op, cache_result;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
cache_type = (config >> 0) & 0xff;
|
||||||
|
cache_op = (config >> 8) & 0xff;
|
||||||
|
cache_result = (config >> 16) & 0xff;
|
||||||
|
if (cache_type >= PERF_COUNT_HW_CACHE_MAX)
|
||||||
|
return -EINVAL;
|
||||||
|
if (cache_op >= PERF_COUNT_HW_CACHE_OP_MAX)
|
||||||
|
return -EINVAL;
|
||||||
|
if (cache_result >= PERF_COUNT_HW_CACHE_RESULT_MAX)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
ret = arc_pmu_cache_map[cache_type][cache_op][cache_result];
|
||||||
|
|
||||||
|
if (ret == CACHE_OP_UNSUPPORTED)
|
||||||
|
return -ENOENT;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* initializes hw_perf_event structure if event is supported */
|
||||||
|
static int arc_pmu_event_init(struct perf_event *event)
|
||||||
|
{
|
||||||
|
struct arc_pmu *arc_pmu = container_of(event->pmu, struct arc_pmu, pmu);
|
||||||
|
struct hw_perf_event *hwc = &event->hw;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
/* ARC 700 PMU does not support sampling events */
|
||||||
|
if (is_sampling_event(event))
|
||||||
|
return -ENOENT;
|
||||||
|
|
||||||
|
switch (event->attr.type) {
|
||||||
|
case PERF_TYPE_HARDWARE:
|
||||||
|
if (event->attr.config >= PERF_COUNT_HW_MAX)
|
||||||
|
return -ENOENT;
|
||||||
|
if (arc_pmu->ev_hw_idx[event->attr.config] < 0)
|
||||||
|
return -ENOENT;
|
||||||
|
hwc->config = arc_pmu->ev_hw_idx[event->attr.config];
|
||||||
|
pr_debug("initializing event %d with cfg %d\n",
|
||||||
|
(int) event->attr.config, (int) hwc->config);
|
||||||
|
return 0;
|
||||||
|
case PERF_TYPE_HW_CACHE:
|
||||||
|
ret = arc_pmu_cache_event(event->attr.config);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
hwc->config = arc_pmu->ev_hw_idx[ret];
|
||||||
|
return 0;
|
||||||
|
default:
|
||||||
|
return -ENOENT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* starts all counters */
|
||||||
|
static void arc_pmu_enable(struct pmu *pmu)
|
||||||
|
{
|
||||||
|
uint32_t tmp;
|
||||||
|
tmp = read_aux_reg(ARC_REG_PCT_CONTROL);
|
||||||
|
write_aux_reg(ARC_REG_PCT_CONTROL, (tmp & 0xffff0000) | 0x1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* stops all counters */
|
||||||
|
static void arc_pmu_disable(struct pmu *pmu)
|
||||||
|
{
|
||||||
|
uint32_t tmp;
|
||||||
|
tmp = read_aux_reg(ARC_REG_PCT_CONTROL);
|
||||||
|
write_aux_reg(ARC_REG_PCT_CONTROL, (tmp & 0xffff0000) | 0x0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Assigns hardware counter to hardware condition.
|
||||||
|
* Note that there is no separate start/stop mechanism;
|
||||||
|
* stopping is achieved by assigning the 'never' condition
|
||||||
|
*/
|
||||||
|
static void arc_pmu_start(struct perf_event *event, int flags)
|
||||||
|
{
|
||||||
|
struct hw_perf_event *hwc = &event->hw;
|
||||||
|
int idx = hwc->idx;
|
||||||
|
|
||||||
|
if (WARN_ON_ONCE(idx == -1))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (flags & PERF_EF_RELOAD)
|
||||||
|
WARN_ON_ONCE(!(event->hw.state & PERF_HES_UPTODATE));
|
||||||
|
|
||||||
|
event->hw.state = 0;
|
||||||
|
|
||||||
|
/* enable ARC pmu here */
|
||||||
|
write_aux_reg(ARC_REG_PCT_INDEX, idx);
|
||||||
|
write_aux_reg(ARC_REG_PCT_CONFIG, hwc->config);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void arc_pmu_stop(struct perf_event *event, int flags)
|
||||||
|
{
|
||||||
|
struct hw_perf_event *hwc = &event->hw;
|
||||||
|
int idx = hwc->idx;
|
||||||
|
|
||||||
|
if (!(event->hw.state & PERF_HES_STOPPED)) {
|
||||||
|
/* stop ARC pmu here */
|
||||||
|
write_aux_reg(ARC_REG_PCT_INDEX, idx);
|
||||||
|
|
||||||
|
/* condition code #0 is always "never" */
|
||||||
|
write_aux_reg(ARC_REG_PCT_CONFIG, 0);
|
||||||
|
|
||||||
|
event->hw.state |= PERF_HES_STOPPED;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((flags & PERF_EF_UPDATE) &&
|
||||||
|
!(event->hw.state & PERF_HES_UPTODATE)) {
|
||||||
|
arc_perf_event_update(event, &event->hw, idx);
|
||||||
|
event->hw.state |= PERF_HES_UPTODATE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void arc_pmu_del(struct perf_event *event, int flags)
|
||||||
|
{
|
||||||
|
struct arc_pmu *arc_pmu = container_of(event->pmu, struct arc_pmu, pmu);
|
||||||
|
|
||||||
|
arc_pmu_stop(event, PERF_EF_UPDATE);
|
||||||
|
__clear_bit(event->hw.idx, arc_pmu->used_mask);
|
||||||
|
|
||||||
|
perf_event_update_userpage(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* allocate hardware counter and optionally start counting */
|
||||||
|
static int arc_pmu_add(struct perf_event *event, int flags)
|
||||||
|
{
|
||||||
|
struct arc_pmu *arc_pmu = container_of(event->pmu, struct arc_pmu, pmu);
|
||||||
|
struct hw_perf_event *hwc = &event->hw;
|
||||||
|
int idx = hwc->idx;
|
||||||
|
|
||||||
|
if (__test_and_set_bit(idx, arc_pmu->used_mask)) {
|
||||||
|
idx = find_first_zero_bit(arc_pmu->used_mask,
|
||||||
|
arc_pmu->n_counters);
|
||||||
|
if (idx == arc_pmu->n_counters)
|
||||||
|
return -EAGAIN;
|
||||||
|
|
||||||
|
__set_bit(idx, arc_pmu->used_mask);
|
||||||
|
hwc->idx = idx;
|
||||||
|
}
|
||||||
|
|
||||||
|
write_aux_reg(ARC_REG_PCT_INDEX, idx);
|
||||||
|
write_aux_reg(ARC_REG_PCT_CONFIG, 0);
|
||||||
|
write_aux_reg(ARC_REG_PCT_COUNTL, 0);
|
||||||
|
write_aux_reg(ARC_REG_PCT_COUNTH, 0);
|
||||||
|
local64_set(&hwc->prev_count, 0);
|
||||||
|
|
||||||
|
hwc->state = PERF_HES_UPTODATE | PERF_HES_STOPPED;
|
||||||
|
if (flags & PERF_EF_START)
|
||||||
|
arc_pmu_start(event, PERF_EF_RELOAD);
|
||||||
|
|
||||||
|
perf_event_update_userpage(event);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int arc_pmu_device_probe(struct platform_device *pdev)
|
||||||
|
{
|
||||||
|
struct arc_pmu *arc_pmu;
|
||||||
|
struct arc_reg_pct_build pct_bcr;
|
||||||
|
struct arc_reg_cc_build cc_bcr;
|
||||||
|
int i, j, ret;
|
||||||
|
|
||||||
|
union cc_name {
|
||||||
|
struct {
|
||||||
|
uint32_t word0, word1;
|
||||||
|
char sentinel;
|
||||||
|
} indiv;
|
||||||
|
char str[9];
|
||||||
|
} cc_name;
|
||||||
|
|
||||||
|
|
||||||
|
READ_BCR(ARC_REG_PCT_BUILD, pct_bcr);
|
||||||
|
if (!pct_bcr.v) {
|
||||||
|
pr_err("This core does not have performance counters!\n");
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
|
arc_pmu = devm_kzalloc(&pdev->dev, sizeof(struct arc_pmu),
|
||||||
|
GFP_KERNEL);
|
||||||
|
if (!arc_pmu)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
arc_pmu->n_counters = pct_bcr.c;
|
||||||
|
BUG_ON(arc_pmu->n_counters > ARC_PMU_MAX_HWEVENTS);
|
||||||
|
|
||||||
|
arc_pmu->counter_size = 32 + (pct_bcr.s << 4);
|
||||||
|
pr_info("ARC PMU found with %d counters of size %d bits\n",
|
||||||
|
arc_pmu->n_counters, arc_pmu->counter_size);
|
||||||
|
|
||||||
|
READ_BCR(ARC_REG_CC_BUILD, cc_bcr);
|
||||||
|
|
||||||
|
if (!cc_bcr.v)
|
||||||
|
pr_err("Strange! Performance counters exist, but no countable conditions?\n");
|
||||||
|
|
||||||
|
pr_info("ARC PMU has %d countable conditions\n", cc_bcr.c);
|
||||||
|
|
||||||
|
cc_name.str[8] = 0;
|
||||||
|
for (i = 0; i < PERF_COUNT_HW_MAX; i++)
|
||||||
|
arc_pmu->ev_hw_idx[i] = -1;
|
||||||
|
|
||||||
|
for (j = 0; j < cc_bcr.c; j++) {
|
||||||
|
write_aux_reg(ARC_REG_CC_INDEX, j);
|
||||||
|
cc_name.indiv.word0 = read_aux_reg(ARC_REG_CC_NAME0);
|
||||||
|
cc_name.indiv.word1 = read_aux_reg(ARC_REG_CC_NAME1);
|
||||||
|
for (i = 0; i < ARRAY_SIZE(arc_pmu_ev_hw_map); i++) {
|
||||||
|
if (arc_pmu_ev_hw_map[i] &&
|
||||||
|
!strcmp(arc_pmu_ev_hw_map[i], cc_name.str) &&
|
||||||
|
strlen(arc_pmu_ev_hw_map[i])) {
|
||||||
|
pr_debug("mapping %d to idx %d with name %s\n",
|
||||||
|
i, j, cc_name.str);
|
||||||
|
arc_pmu->ev_hw_idx[i] = j;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
arc_pmu->pmu = (struct pmu) {
|
||||||
|
.pmu_enable = arc_pmu_enable,
|
||||||
|
.pmu_disable = arc_pmu_disable,
|
||||||
|
.event_init = arc_pmu_event_init,
|
||||||
|
.add = arc_pmu_add,
|
||||||
|
.del = arc_pmu_del,
|
||||||
|
.start = arc_pmu_start,
|
||||||
|
.stop = arc_pmu_stop,
|
||||||
|
.read = arc_pmu_read,
|
||||||
|
};
|
||||||
|
|
||||||
|
ret = perf_pmu_register(&arc_pmu->pmu, pdev->name, PERF_TYPE_RAW);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_OF
|
||||||
|
static const struct of_device_id arc_pmu_match[] = {
|
||||||
|
{ .compatible = "snps,arc700-pmu" },
|
||||||
|
{},
|
||||||
|
};
|
||||||
|
MODULE_DEVICE_TABLE(of, arc_pmu_match);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static struct platform_driver arc_pmu_driver = {
|
||||||
|
.driver = {
|
||||||
|
.name = "arc700-pmu",
|
||||||
|
.of_match_table = of_match_ptr(arc_pmu_match),
|
||||||
|
},
|
||||||
|
.probe = arc_pmu_device_probe,
|
||||||
|
};
|
||||||
|
|
||||||
|
module_platform_driver(arc_pmu_driver);
|
||||||
|
|
||||||
|
MODULE_LICENSE("GPL");
|
||||||
|
MODULE_AUTHOR("Mischa Jonker <mjonker@synopsys.com>");
|
||||||
|
MODULE_DESCRIPTION("ARC PMU driver");
|
@ -20,8 +20,10 @@ menuconfig ARC_PLAT_TB10X
|
|||||||
bool "Abilis TB10x"
|
bool "Abilis TB10x"
|
||||||
select COMMON_CLK
|
select COMMON_CLK
|
||||||
select PINCTRL
|
select PINCTRL
|
||||||
|
select PINCTRL_TB10X
|
||||||
select PINMUX
|
select PINMUX
|
||||||
select ARCH_REQUIRE_GPIOLIB
|
select ARCH_REQUIRE_GPIOLIB
|
||||||
|
select GPIO_TB10X
|
||||||
select TB10X_IRQC
|
select TB10X_IRQC
|
||||||
help
|
help
|
||||||
Support for platforms based on the TB10x home media gateway SOC by
|
Support for platforms based on the TB10x home media gateway SOC by
|
||||||
|
@ -25,7 +25,7 @@ config ARM
|
|||||||
select HARDIRQS_SW_RESEND
|
select HARDIRQS_SW_RESEND
|
||||||
select HAVE_ARCH_JUMP_LABEL if !XIP_KERNEL
|
select HAVE_ARCH_JUMP_LABEL if !XIP_KERNEL
|
||||||
select HAVE_ARCH_KGDB
|
select HAVE_ARCH_KGDB
|
||||||
select HAVE_ARCH_SECCOMP_FILTER
|
select HAVE_ARCH_SECCOMP_FILTER if (AEABI && !OABI_COMPAT)
|
||||||
select HAVE_ARCH_TRACEHOOK
|
select HAVE_ARCH_TRACEHOOK
|
||||||
select HAVE_BPF_JIT
|
select HAVE_BPF_JIT
|
||||||
select HAVE_CONTEXT_TRACKING
|
select HAVE_CONTEXT_TRACKING
|
||||||
@ -1496,6 +1496,7 @@ config HAVE_ARM_ARCH_TIMER
|
|||||||
bool "Architected timer support"
|
bool "Architected timer support"
|
||||||
depends on CPU_V7
|
depends on CPU_V7
|
||||||
select ARM_ARCH_TIMER
|
select ARM_ARCH_TIMER
|
||||||
|
select GENERIC_CLOCKEVENTS
|
||||||
help
|
help
|
||||||
This option enables support for the ARM architected timer
|
This option enables support for the ARM architected timer
|
||||||
|
|
||||||
@ -1719,7 +1720,6 @@ config AEABI
|
|||||||
config OABI_COMPAT
|
config OABI_COMPAT
|
||||||
bool "Allow old ABI binaries to run with this kernel (EXPERIMENTAL)"
|
bool "Allow old ABI binaries to run with this kernel (EXPERIMENTAL)"
|
||||||
depends on AEABI && !THUMB2_KERNEL
|
depends on AEABI && !THUMB2_KERNEL
|
||||||
default y
|
|
||||||
help
|
help
|
||||||
This option preserves the old syscall interface along with the
|
This option preserves the old syscall interface along with the
|
||||||
new (ARM EABI) one. It also provides a compatibility layer to
|
new (ARM EABI) one. It also provides a compatibility layer to
|
||||||
@ -1727,11 +1727,16 @@ config OABI_COMPAT
|
|||||||
in memory differs between the legacy ABI and the new ARM EABI
|
in memory differs between the legacy ABI and the new ARM EABI
|
||||||
(only for non "thumb" binaries). This option adds a tiny
|
(only for non "thumb" binaries). This option adds a tiny
|
||||||
overhead to all syscalls and produces a slightly larger kernel.
|
overhead to all syscalls and produces a slightly larger kernel.
|
||||||
|
|
||||||
|
The seccomp filter system will not be available when this is
|
||||||
|
selected, since there is no way yet to sensibly distinguish
|
||||||
|
between calling conventions during filtering.
|
||||||
|
|
||||||
If you know you'll be using only pure EABI user space then you
|
If you know you'll be using only pure EABI user space then you
|
||||||
can say N here. If this option is not selected and you attempt
|
can say N here. If this option is not selected and you attempt
|
||||||
to execute a legacy ABI binary then the result will be
|
to execute a legacy ABI binary then the result will be
|
||||||
UNPREDICTABLE (in fact it can be predicted that it won't work
|
UNPREDICTABLE (in fact it can be predicted that it won't work
|
||||||
at all). If in doubt say Y.
|
at all). If in doubt say N.
|
||||||
|
|
||||||
config ARCH_HAS_HOLES_MEMORYMODEL
|
config ARCH_HAS_HOLES_MEMORYMODEL
|
||||||
bool
|
bool
|
||||||
|
@ -13,4 +13,83 @@
|
|||||||
/ {
|
/ {
|
||||||
model = "IGEP COM AM335x on AQUILA Expansion";
|
model = "IGEP COM AM335x on AQUILA Expansion";
|
||||||
compatible = "isee,am335x-base0033", "isee,am335x-igep0033", "ti,am33xx";
|
compatible = "isee,am335x-base0033", "isee,am335x-igep0033", "ti,am33xx";
|
||||||
|
|
||||||
|
hdmi {
|
||||||
|
compatible = "ti,tilcdc,slave";
|
||||||
|
i2c = <&i2c0>;
|
||||||
|
pinctrl-names = "default", "off";
|
||||||
|
pinctrl-0 = <&nxp_hdmi_pins>;
|
||||||
|
pinctrl-1 = <&nxp_hdmi_off_pins>;
|
||||||
|
status = "okay";
|
||||||
|
};
|
||||||
|
|
||||||
|
leds_base {
|
||||||
|
pinctrl-names = "default";
|
||||||
|
pinctrl-0 = <&leds_base_pins>;
|
||||||
|
|
||||||
|
compatible = "gpio-leds";
|
||||||
|
|
||||||
|
led@0 {
|
||||||
|
label = "base:red:user";
|
||||||
|
gpios = <&gpio1 21 GPIO_ACTIVE_HIGH>; /* gpio1_21 */
|
||||||
|
default-state = "off";
|
||||||
|
};
|
||||||
|
|
||||||
|
led@1 {
|
||||||
|
label = "base:green:user";
|
||||||
|
gpios = <&gpio2 0 GPIO_ACTIVE_HIGH>; /* gpio2_0 */
|
||||||
|
default-state = "off";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
&am33xx_pinmux {
|
||||||
|
nxp_hdmi_pins: pinmux_nxp_hdmi_pins {
|
||||||
|
pinctrl-single,pins = <
|
||||||
|
0x1b0 (PIN_OUTPUT | MUX_MODE3) /* xdma_event_intr0.clkout1 */
|
||||||
|
0xa0 (PIN_OUTPUT | MUX_MODE0) /* lcd_data0 */
|
||||||
|
0xa4 (PIN_OUTPUT | MUX_MODE0) /* lcd_data1 */
|
||||||
|
0xa8 (PIN_OUTPUT | MUX_MODE0) /* lcd_data2 */
|
||||||
|
0xac (PIN_OUTPUT | MUX_MODE0) /* lcd_data3 */
|
||||||
|
0xb0 (PIN_OUTPUT | MUX_MODE0) /* lcd_data4 */
|
||||||
|
0xb4 (PIN_OUTPUT | MUX_MODE0) /* lcd_data5 */
|
||||||
|
0xb8 (PIN_OUTPUT | MUX_MODE0) /* lcd_data6 */
|
||||||
|
0xbc (PIN_OUTPUT | MUX_MODE0) /* lcd_data7 */
|
||||||
|
0xc0 (PIN_OUTPUT | MUX_MODE0) /* lcd_data8 */
|
||||||
|
0xc4 (PIN_OUTPUT | MUX_MODE0) /* lcd_data9 */
|
||||||
|
0xc8 (PIN_OUTPUT | MUX_MODE0) /* lcd_data10 */
|
||||||
|
0xcc (PIN_OUTPUT | MUX_MODE0) /* lcd_data11 */
|
||||||
|
0xd0 (PIN_OUTPUT | MUX_MODE0) /* lcd_data12 */
|
||||||
|
0xd4 (PIN_OUTPUT | MUX_MODE0) /* lcd_data13 */
|
||||||
|
0xd8 (PIN_OUTPUT | MUX_MODE0) /* lcd_data14 */
|
||||||
|
0xdc (PIN_OUTPUT | MUX_MODE0) /* lcd_data15 */
|
||||||
|
0xe0 (PIN_OUTPUT | MUX_MODE0) /* lcd_vsync */
|
||||||
|
0xe4 (PIN_OUTPUT | MUX_MODE0) /* lcd_hsync */
|
||||||
|
0xe8 (PIN_OUTPUT | MUX_MODE0) /* lcd_pclk */
|
||||||
|
0xec (PIN_OUTPUT | MUX_MODE0) /* lcd_ac_bias_en */
|
||||||
|
>;
|
||||||
|
};
|
||||||
|
nxp_hdmi_off_pins: pinmux_nxp_hdmi_off_pins {
|
||||||
|
pinctrl-single,pins = <
|
||||||
|
0x1b0 (PIN_OUTPUT | MUX_MODE3) /* xdma_event_intr0.clkout1 */
|
||||||
|
>;
|
||||||
|
};
|
||||||
|
|
||||||
|
leds_base_pins: pinmux_leds_base_pins {
|
||||||
|
pinctrl-single,pins = <
|
||||||
|
0x54 (PIN_OUTPUT_PULLDOWN | MUX_MODE7) /* gpmc_a5.gpio1_21 */
|
||||||
|
0x88 (PIN_OUTPUT_PULLDOWN | MUX_MODE7) /* gpmc_csn3.gpio2_0 */
|
||||||
|
>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
&lcdc {
|
||||||
|
status = "okay";
|
||||||
|
};
|
||||||
|
|
||||||
|
&i2c0 {
|
||||||
|
eeprom: eeprom@50 {
|
||||||
|
compatible = "at,24c256";
|
||||||
|
reg = <0x50>;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
@ -199,6 +199,35 @@
|
|||||||
pinctrl-0 = <&uart0_pins>;
|
pinctrl-0 = <&uart0_pins>;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
&usb {
|
||||||
|
status = "okay";
|
||||||
|
|
||||||
|
control@44e10000 {
|
||||||
|
status = "okay";
|
||||||
|
};
|
||||||
|
|
||||||
|
usb-phy@47401300 {
|
||||||
|
status = "okay";
|
||||||
|
};
|
||||||
|
|
||||||
|
usb-phy@47401b00 {
|
||||||
|
status = "okay";
|
||||||
|
};
|
||||||
|
|
||||||
|
usb@47401000 {
|
||||||
|
status = "okay";
|
||||||
|
};
|
||||||
|
|
||||||
|
usb@47401800 {
|
||||||
|
status = "okay";
|
||||||
|
dr_mode = "host";
|
||||||
|
};
|
||||||
|
|
||||||
|
dma-controller@07402000 {
|
||||||
|
status = "okay";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
#include "tps65910.dtsi"
|
#include "tps65910.dtsi"
|
||||||
|
|
||||||
&tps {
|
&tps {
|
||||||
|
@ -7,11 +7,11 @@
|
|||||||
*/
|
*/
|
||||||
/dts-v1/;
|
/dts-v1/;
|
||||||
|
|
||||||
#include "omap34xx.dtsi"
|
#include "am3517.dtsi"
|
||||||
|
|
||||||
/ {
|
/ {
|
||||||
model = "TI AM3517 EVM (AM3517/05)";
|
model = "TI AM3517 EVM (AM3517/05 TMDSEVM3517)";
|
||||||
compatible = "ti,am3517-evm", "ti,omap3";
|
compatible = "ti,am3517-evm", "ti,am3517", "ti,omap3";
|
||||||
|
|
||||||
memory {
|
memory {
|
||||||
device_type = "memory";
|
device_type = "memory";
|
||||||
|
63
arch/arm/boot/dts/am3517.dtsi
Normal file
63
arch/arm/boot/dts/am3517.dtsi
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
/*
|
||||||
|
* Device Tree Source for am3517 SoC
|
||||||
|
*
|
||||||
|
* Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/
|
||||||
|
*
|
||||||
|
* This file is licensed under the terms of the GNU General Public License
|
||||||
|
* version 2. This program is licensed "as is" without any warranty of any
|
||||||
|
* kind, whether express or implied.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "omap3.dtsi"
|
||||||
|
|
||||||
|
/ {
|
||||||
|
aliases {
|
||||||
|
serial3 = &uart4;
|
||||||
|
};
|
||||||
|
|
||||||
|
ocp {
|
||||||
|
am35x_otg_hs: am35x_otg_hs@5c040000 {
|
||||||
|
compatible = "ti,omap3-musb";
|
||||||
|
ti,hwmods = "am35x_otg_hs";
|
||||||
|
status = "disabled";
|
||||||
|
reg = <0x5c040000 0x1000>;
|
||||||
|
interrupts = <71>;
|
||||||
|
interrupt-names = "mc";
|
||||||
|
};
|
||||||
|
|
||||||
|
davinci_emac: ethernet@0x5c000000 {
|
||||||
|
compatible = "ti,am3517-emac";
|
||||||
|
ti,hwmods = "davinci_emac";
|
||||||
|
status = "disabled";
|
||||||
|
reg = <0x5c000000 0x30000>;
|
||||||
|
interrupts = <67 68 69 70>;
|
||||||
|
ti,davinci-ctrl-reg-offset = <0x10000>;
|
||||||
|
ti,davinci-ctrl-mod-reg-offset = <0>;
|
||||||
|
ti,davinci-ctrl-ram-offset = <0x20000>;
|
||||||
|
ti,davinci-ctrl-ram-size = <0x2000>;
|
||||||
|
ti,davinci-rmii-en = /bits/ 8 <1>;
|
||||||
|
local-mac-address = [ 00 00 00 00 00 00 ];
|
||||||
|
};
|
||||||
|
|
||||||
|
davinci_mdio: ethernet@0x5c030000 {
|
||||||
|
compatible = "ti,davinci_mdio";
|
||||||
|
ti,hwmods = "davinci_mdio";
|
||||||
|
status = "disabled";
|
||||||
|
reg = <0x5c030000 0x1000>;
|
||||||
|
bus_freq = <1000000>;
|
||||||
|
#address-cells = <1>;
|
||||||
|
#size-cells = <0>;
|
||||||
|
};
|
||||||
|
|
||||||
|
uart4: serial@4809e000 {
|
||||||
|
compatible = "ti,omap3-uart";
|
||||||
|
ti,hwmods = "uart4";
|
||||||
|
status = "disabled";
|
||||||
|
reg = <0x4809e000 0x400>;
|
||||||
|
interrupts = <84>;
|
||||||
|
dmas = <&sdma 55 &sdma 54>;
|
||||||
|
dma-names = "tx", "rx";
|
||||||
|
clock-frequency = <48000000>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
@ -99,22 +99,22 @@
|
|||||||
spi-max-frequency = <50000000>;
|
spi-max-frequency = <50000000>;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
};
|
||||||
|
|
||||||
pcie-controller {
|
pcie-controller {
|
||||||
|
status = "okay";
|
||||||
|
/*
|
||||||
|
* The two PCIe units are accessible through
|
||||||
|
* both standard PCIe slots and mini-PCIe
|
||||||
|
* slots on the board.
|
||||||
|
*/
|
||||||
|
pcie@1,0 {
|
||||||
|
/* Port 0, Lane 0 */
|
||||||
|
status = "okay";
|
||||||
|
};
|
||||||
|
pcie@2,0 {
|
||||||
|
/* Port 1, Lane 0 */
|
||||||
status = "okay";
|
status = "okay";
|
||||||
/*
|
|
||||||
* The two PCIe units are accessible through
|
|
||||||
* both standard PCIe slots and mini-PCIe
|
|
||||||
* slots on the board.
|
|
||||||
*/
|
|
||||||
pcie@1,0 {
|
|
||||||
/* Port 0, Lane 0 */
|
|
||||||
status = "okay";
|
|
||||||
};
|
|
||||||
pcie@2,0 {
|
|
||||||
/* Port 1, Lane 0 */
|
|
||||||
status = "okay";
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -118,7 +118,7 @@
|
|||||||
|
|
||||||
coherency-fabric@20200 {
|
coherency-fabric@20200 {
|
||||||
compatible = "marvell,coherency-fabric";
|
compatible = "marvell,coherency-fabric";
|
||||||
reg = <0x20200 0xb0>, <0x21810 0x1c>;
|
reg = <0x20200 0xb0>, <0x21010 0x1c>;
|
||||||
};
|
};
|
||||||
|
|
||||||
serial@12000 {
|
serial@12000 {
|
||||||
|
@ -47,7 +47,7 @@
|
|||||||
/*
|
/*
|
||||||
* MV78230 has 2 PCIe units Gen2.0: One unit can be
|
* MV78230 has 2 PCIe units Gen2.0: One unit can be
|
||||||
* configured as x4 or quad x1 lanes. One unit is
|
* configured as x4 or quad x1 lanes. One unit is
|
||||||
* x4/x1.
|
* x1 only.
|
||||||
*/
|
*/
|
||||||
pcie-controller {
|
pcie-controller {
|
||||||
compatible = "marvell,armada-xp-pcie";
|
compatible = "marvell,armada-xp-pcie";
|
||||||
@ -62,10 +62,10 @@
|
|||||||
|
|
||||||
ranges =
|
ranges =
|
||||||
<0x82000000 0 0x40000 MBUS_ID(0xf0, 0x01) 0x40000 0 0x00002000 /* Port 0.0 registers */
|
<0x82000000 0 0x40000 MBUS_ID(0xf0, 0x01) 0x40000 0 0x00002000 /* Port 0.0 registers */
|
||||||
0x82000000 0 0x42000 MBUS_ID(0xf0, 0x01) 0x42000 0 0x00002000 /* Port 2.0 registers */
|
|
||||||
0x82000000 0 0x44000 MBUS_ID(0xf0, 0x01) 0x44000 0 0x00002000 /* Port 0.1 registers */
|
0x82000000 0 0x44000 MBUS_ID(0xf0, 0x01) 0x44000 0 0x00002000 /* Port 0.1 registers */
|
||||||
0x82000000 0 0x48000 MBUS_ID(0xf0, 0x01) 0x48000 0 0x00002000 /* Port 0.2 registers */
|
0x82000000 0 0x48000 MBUS_ID(0xf0, 0x01) 0x48000 0 0x00002000 /* Port 0.2 registers */
|
||||||
0x82000000 0 0x4c000 MBUS_ID(0xf0, 0x01) 0x4c000 0 0x00002000 /* Port 0.3 registers */
|
0x82000000 0 0x4c000 MBUS_ID(0xf0, 0x01) 0x4c000 0 0x00002000 /* Port 0.3 registers */
|
||||||
|
0x82000000 0 0x80000 MBUS_ID(0xf0, 0x01) 0x80000 0 0x00002000 /* Port 1.0 registers */
|
||||||
0x82000000 0x1 0 MBUS_ID(0x04, 0xe8) 0 1 0 /* Port 0.0 MEM */
|
0x82000000 0x1 0 MBUS_ID(0x04, 0xe8) 0 1 0 /* Port 0.0 MEM */
|
||||||
0x81000000 0x1 0 MBUS_ID(0x04, 0xe0) 0 1 0 /* Port 0.0 IO */
|
0x81000000 0x1 0 MBUS_ID(0x04, 0xe0) 0 1 0 /* Port 0.0 IO */
|
||||||
0x82000000 0x2 0 MBUS_ID(0x04, 0xd8) 0 1 0 /* Port 0.1 MEM */
|
0x82000000 0x2 0 MBUS_ID(0x04, 0xd8) 0 1 0 /* Port 0.1 MEM */
|
||||||
@ -74,8 +74,8 @@
|
|||||||
0x81000000 0x3 0 MBUS_ID(0x04, 0xb0) 0 1 0 /* Port 0.2 IO */
|
0x81000000 0x3 0 MBUS_ID(0x04, 0xb0) 0 1 0 /* Port 0.2 IO */
|
||||||
0x82000000 0x4 0 MBUS_ID(0x04, 0x78) 0 1 0 /* Port 0.3 MEM */
|
0x82000000 0x4 0 MBUS_ID(0x04, 0x78) 0 1 0 /* Port 0.3 MEM */
|
||||||
0x81000000 0x4 0 MBUS_ID(0x04, 0x70) 0 1 0 /* Port 0.3 IO */
|
0x81000000 0x4 0 MBUS_ID(0x04, 0x70) 0 1 0 /* Port 0.3 IO */
|
||||||
0x82000000 0x9 0 MBUS_ID(0x04, 0xf8) 0 1 0 /* Port 2.0 MEM */
|
0x82000000 0x5 0 MBUS_ID(0x08, 0xe8) 0 1 0 /* Port 1.0 MEM */
|
||||||
0x81000000 0x9 0 MBUS_ID(0x04, 0xf0) 0 1 0 /* Port 2.0 IO */>;
|
0x81000000 0x5 0 MBUS_ID(0x08, 0xe0) 0 1 0 /* Port 1.0 IO */>;
|
||||||
|
|
||||||
pcie@1,0 {
|
pcie@1,0 {
|
||||||
device_type = "pci";
|
device_type = "pci";
|
||||||
@ -145,20 +145,20 @@
|
|||||||
status = "disabled";
|
status = "disabled";
|
||||||
};
|
};
|
||||||
|
|
||||||
pcie@9,0 {
|
pcie@5,0 {
|
||||||
device_type = "pci";
|
device_type = "pci";
|
||||||
assigned-addresses = <0x82000800 0 0x42000 0 0x2000>;
|
assigned-addresses = <0x82000800 0 0x80000 0 0x2000>;
|
||||||
reg = <0x4800 0 0 0 0>;
|
reg = <0x2800 0 0 0 0>;
|
||||||
#address-cells = <3>;
|
#address-cells = <3>;
|
||||||
#size-cells = <2>;
|
#size-cells = <2>;
|
||||||
#interrupt-cells = <1>;
|
#interrupt-cells = <1>;
|
||||||
ranges = <0x82000000 0 0 0x82000000 0x9 0 1 0
|
ranges = <0x82000000 0 0 0x82000000 0x5 0 1 0
|
||||||
0x81000000 0 0 0x81000000 0x9 0 1 0>;
|
0x81000000 0 0 0x81000000 0x5 0 1 0>;
|
||||||
interrupt-map-mask = <0 0 0 0>;
|
interrupt-map-mask = <0 0 0 0>;
|
||||||
interrupt-map = <0 0 0 0 &mpic 99>;
|
interrupt-map = <0 0 0 0 &mpic 62>;
|
||||||
marvell,pcie-port = <2>;
|
marvell,pcie-port = <1>;
|
||||||
marvell,pcie-lane = <0>;
|
marvell,pcie-lane = <0>;
|
||||||
clocks = <&gateclk 26>;
|
clocks = <&gateclk 9>;
|
||||||
status = "disabled";
|
status = "disabled";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -48,7 +48,7 @@
|
|||||||
/*
|
/*
|
||||||
* MV78260 has 3 PCIe units Gen2.0: Two units can be
|
* MV78260 has 3 PCIe units Gen2.0: Two units can be
|
||||||
* configured as x4 or quad x1 lanes. One unit is
|
* configured as x4 or quad x1 lanes. One unit is
|
||||||
* x4/x1.
|
* x4 only.
|
||||||
*/
|
*/
|
||||||
pcie-controller {
|
pcie-controller {
|
||||||
compatible = "marvell,armada-xp-pcie";
|
compatible = "marvell,armada-xp-pcie";
|
||||||
@ -68,7 +68,9 @@
|
|||||||
0x82000000 0 0x48000 MBUS_ID(0xf0, 0x01) 0x48000 0 0x00002000 /* Port 0.2 registers */
|
0x82000000 0 0x48000 MBUS_ID(0xf0, 0x01) 0x48000 0 0x00002000 /* Port 0.2 registers */
|
||||||
0x82000000 0 0x4c000 MBUS_ID(0xf0, 0x01) 0x4c000 0 0x00002000 /* Port 0.3 registers */
|
0x82000000 0 0x4c000 MBUS_ID(0xf0, 0x01) 0x4c000 0 0x00002000 /* Port 0.3 registers */
|
||||||
0x82000000 0 0x80000 MBUS_ID(0xf0, 0x01) 0x80000 0 0x00002000 /* Port 1.0 registers */
|
0x82000000 0 0x80000 MBUS_ID(0xf0, 0x01) 0x80000 0 0x00002000 /* Port 1.0 registers */
|
||||||
0x82000000 0 0x82000 MBUS_ID(0xf0, 0x01) 0x82000 0 0x00002000 /* Port 3.0 registers */
|
0x82000000 0 0x84000 MBUS_ID(0xf0, 0x01) 0x84000 0 0x00002000 /* Port 1.1 registers */
|
||||||
|
0x82000000 0 0x88000 MBUS_ID(0xf0, 0x01) 0x88000 0 0x00002000 /* Port 1.2 registers */
|
||||||
|
0x82000000 0 0x8c000 MBUS_ID(0xf0, 0x01) 0x8c000 0 0x00002000 /* Port 1.3 registers */
|
||||||
0x82000000 0x1 0 MBUS_ID(0x04, 0xe8) 0 1 0 /* Port 0.0 MEM */
|
0x82000000 0x1 0 MBUS_ID(0x04, 0xe8) 0 1 0 /* Port 0.0 MEM */
|
||||||
0x81000000 0x1 0 MBUS_ID(0x04, 0xe0) 0 1 0 /* Port 0.0 IO */
|
0x81000000 0x1 0 MBUS_ID(0x04, 0xe0) 0 1 0 /* Port 0.0 IO */
|
||||||
0x82000000 0x2 0 MBUS_ID(0x04, 0xd8) 0 1 0 /* Port 0.1 MEM */
|
0x82000000 0x2 0 MBUS_ID(0x04, 0xd8) 0 1 0 /* Port 0.1 MEM */
|
||||||
@ -77,10 +79,18 @@
|
|||||||
0x81000000 0x3 0 MBUS_ID(0x04, 0xb0) 0 1 0 /* Port 0.2 IO */
|
0x81000000 0x3 0 MBUS_ID(0x04, 0xb0) 0 1 0 /* Port 0.2 IO */
|
||||||
0x82000000 0x4 0 MBUS_ID(0x04, 0x78) 0 1 0 /* Port 0.3 MEM */
|
0x82000000 0x4 0 MBUS_ID(0x04, 0x78) 0 1 0 /* Port 0.3 MEM */
|
||||||
0x81000000 0x4 0 MBUS_ID(0x04, 0x70) 0 1 0 /* Port 0.3 IO */
|
0x81000000 0x4 0 MBUS_ID(0x04, 0x70) 0 1 0 /* Port 0.3 IO */
|
||||||
0x82000000 0x9 0 MBUS_ID(0x08, 0xe8) 0 1 0 /* Port 1.0 MEM */
|
|
||||||
0x81000000 0x9 0 MBUS_ID(0x08, 0xe0) 0 1 0 /* Port 1.0 IO */
|
0x82000000 0x5 0 MBUS_ID(0x08, 0xe8) 0 1 0 /* Port 1.0 MEM */
|
||||||
0x82000000 0xa 0 MBUS_ID(0x08, 0xf8) 0 1 0 /* Port 3.0 MEM */
|
0x81000000 0x5 0 MBUS_ID(0x08, 0xe0) 0 1 0 /* Port 1.0 IO */
|
||||||
0x81000000 0xa 0 MBUS_ID(0x08, 0xf0) 0 1 0 /* Port 3.0 IO */>;
|
0x82000000 0x6 0 MBUS_ID(0x08, 0xd8) 0 1 0 /* Port 1.1 MEM */
|
||||||
|
0x81000000 0x6 0 MBUS_ID(0x08, 0xd0) 0 1 0 /* Port 1.1 IO */
|
||||||
|
0x82000000 0x7 0 MBUS_ID(0x08, 0xb8) 0 1 0 /* Port 1.2 MEM */
|
||||||
|
0x81000000 0x7 0 MBUS_ID(0x08, 0xb0) 0 1 0 /* Port 1.2 IO */
|
||||||
|
0x82000000 0x8 0 MBUS_ID(0x08, 0x78) 0 1 0 /* Port 1.3 MEM */
|
||||||
|
0x81000000 0x8 0 MBUS_ID(0x08, 0x70) 0 1 0 /* Port 1.3 IO */
|
||||||
|
|
||||||
|
0x82000000 0x9 0 MBUS_ID(0x04, 0xf8) 0 1 0 /* Port 2.0 MEM */
|
||||||
|
0x81000000 0x9 0 MBUS_ID(0x04, 0xf0) 0 1 0 /* Port 2.0 IO */>;
|
||||||
|
|
||||||
pcie@1,0 {
|
pcie@1,0 {
|
||||||
device_type = "pci";
|
device_type = "pci";
|
||||||
@ -106,8 +116,8 @@
|
|||||||
#address-cells = <3>;
|
#address-cells = <3>;
|
||||||
#size-cells = <2>;
|
#size-cells = <2>;
|
||||||
#interrupt-cells = <1>;
|
#interrupt-cells = <1>;
|
||||||
ranges = <0x82000000 0 0 0x82000000 0x2 0 1 0
|
ranges = <0x82000000 0 0 0x82000000 0x2 0 1 0
|
||||||
0x81000000 0 0 0x81000000 0x2 0 1 0>;
|
0x81000000 0 0 0x81000000 0x2 0 1 0>;
|
||||||
interrupt-map-mask = <0 0 0 0>;
|
interrupt-map-mask = <0 0 0 0>;
|
||||||
interrupt-map = <0 0 0 0 &mpic 59>;
|
interrupt-map = <0 0 0 0 &mpic 59>;
|
||||||
marvell,pcie-port = <0>;
|
marvell,pcie-port = <0>;
|
||||||
@ -150,6 +160,74 @@
|
|||||||
status = "disabled";
|
status = "disabled";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
pcie@5,0 {
|
||||||
|
device_type = "pci";
|
||||||
|
assigned-addresses = <0x82000800 0 0x80000 0 0x2000>;
|
||||||
|
reg = <0x2800 0 0 0 0>;
|
||||||
|
#address-cells = <3>;
|
||||||
|
#size-cells = <2>;
|
||||||
|
#interrupt-cells = <1>;
|
||||||
|
ranges = <0x82000000 0 0 0x82000000 0x5 0 1 0
|
||||||
|
0x81000000 0 0 0x81000000 0x5 0 1 0>;
|
||||||
|
interrupt-map-mask = <0 0 0 0>;
|
||||||
|
interrupt-map = <0 0 0 0 &mpic 62>;
|
||||||
|
marvell,pcie-port = <1>;
|
||||||
|
marvell,pcie-lane = <0>;
|
||||||
|
clocks = <&gateclk 9>;
|
||||||
|
status = "disabled";
|
||||||
|
};
|
||||||
|
|
||||||
|
pcie@6,0 {
|
||||||
|
device_type = "pci";
|
||||||
|
assigned-addresses = <0x82000800 0 0x84000 0 0x2000>;
|
||||||
|
reg = <0x3000 0 0 0 0>;
|
||||||
|
#address-cells = <3>;
|
||||||
|
#size-cells = <2>;
|
||||||
|
#interrupt-cells = <1>;
|
||||||
|
ranges = <0x82000000 0 0 0x82000000 0x6 0 1 0
|
||||||
|
0x81000000 0 0 0x81000000 0x6 0 1 0>;
|
||||||
|
interrupt-map-mask = <0 0 0 0>;
|
||||||
|
interrupt-map = <0 0 0 0 &mpic 63>;
|
||||||
|
marvell,pcie-port = <1>;
|
||||||
|
marvell,pcie-lane = <1>;
|
||||||
|
clocks = <&gateclk 10>;
|
||||||
|
status = "disabled";
|
||||||
|
};
|
||||||
|
|
||||||
|
pcie@7,0 {
|
||||||
|
device_type = "pci";
|
||||||
|
assigned-addresses = <0x82000800 0 0x88000 0 0x2000>;
|
||||||
|
reg = <0x3800 0 0 0 0>;
|
||||||
|
#address-cells = <3>;
|
||||||
|
#size-cells = <2>;
|
||||||
|
#interrupt-cells = <1>;
|
||||||
|
ranges = <0x82000000 0 0 0x82000000 0x7 0 1 0
|
||||||
|
0x81000000 0 0 0x81000000 0x7 0 1 0>;
|
||||||
|
interrupt-map-mask = <0 0 0 0>;
|
||||||
|
interrupt-map = <0 0 0 0 &mpic 64>;
|
||||||
|
marvell,pcie-port = <1>;
|
||||||
|
marvell,pcie-lane = <2>;
|
||||||
|
clocks = <&gateclk 11>;
|
||||||
|
status = "disabled";
|
||||||
|
};
|
||||||
|
|
||||||
|
pcie@8,0 {
|
||||||
|
device_type = "pci";
|
||||||
|
assigned-addresses = <0x82000800 0 0x8c000 0 0x2000>;
|
||||||
|
reg = <0x4000 0 0 0 0>;
|
||||||
|
#address-cells = <3>;
|
||||||
|
#size-cells = <2>;
|
||||||
|
#interrupt-cells = <1>;
|
||||||
|
ranges = <0x82000000 0 0 0x82000000 0x8 0 1 0
|
||||||
|
0x81000000 0 0 0x81000000 0x8 0 1 0>;
|
||||||
|
interrupt-map-mask = <0 0 0 0>;
|
||||||
|
interrupt-map = <0 0 0 0 &mpic 65>;
|
||||||
|
marvell,pcie-port = <1>;
|
||||||
|
marvell,pcie-lane = <3>;
|
||||||
|
clocks = <&gateclk 12>;
|
||||||
|
status = "disabled";
|
||||||
|
};
|
||||||
|
|
||||||
pcie@9,0 {
|
pcie@9,0 {
|
||||||
device_type = "pci";
|
device_type = "pci";
|
||||||
assigned-addresses = <0x82000800 0 0x42000 0 0x2000>;
|
assigned-addresses = <0x82000800 0 0x42000 0 0x2000>;
|
||||||
@ -166,23 +244,6 @@
|
|||||||
clocks = <&gateclk 26>;
|
clocks = <&gateclk 26>;
|
||||||
status = "disabled";
|
status = "disabled";
|
||||||
};
|
};
|
||||||
|
|
||||||
pcie@10,0 {
|
|
||||||
device_type = "pci";
|
|
||||||
assigned-addresses = <0x82000800 0 0x82000 0 0x2000>;
|
|
||||||
reg = <0x5000 0 0 0 0>;
|
|
||||||
#address-cells = <3>;
|
|
||||||
#size-cells = <2>;
|
|
||||||
#interrupt-cells = <1>;
|
|
||||||
ranges = <0x82000000 0 0 0x82000000 0xa 0 1 0
|
|
||||||
0x81000000 0 0 0x81000000 0xa 0 1 0>;
|
|
||||||
interrupt-map-mask = <0 0 0 0>;
|
|
||||||
interrupt-map = <0 0 0 0 &mpic 103>;
|
|
||||||
marvell,pcie-port = <3>;
|
|
||||||
marvell,pcie-lane = <0>;
|
|
||||||
clocks = <&gateclk 27>;
|
|
||||||
status = "disabled";
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
internal-regs {
|
internal-regs {
|
||||||
|
@ -11,6 +11,10 @@
|
|||||||
#include <dt-bindings/interrupt-controller/irq.h>
|
#include <dt-bindings/interrupt-controller/irq.h>
|
||||||
|
|
||||||
/ {
|
/ {
|
||||||
|
aliases {
|
||||||
|
serial4 = &usart3;
|
||||||
|
};
|
||||||
|
|
||||||
ahb {
|
ahb {
|
||||||
apb {
|
apb {
|
||||||
pinctrl@fffff400 {
|
pinctrl@fffff400 {
|
||||||
|
@ -85,6 +85,8 @@
|
|||||||
reg = <0x7e205000 0x1000>;
|
reg = <0x7e205000 0x1000>;
|
||||||
interrupts = <2 21>;
|
interrupts = <2 21>;
|
||||||
clocks = <&clk_i2c>;
|
clocks = <&clk_i2c>;
|
||||||
|
#address-cells = <1>;
|
||||||
|
#size-cells = <0>;
|
||||||
status = "disabled";
|
status = "disabled";
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -93,6 +95,8 @@
|
|||||||
reg = <0x7e804000 0x1000>;
|
reg = <0x7e804000 0x1000>;
|
||||||
interrupts = <2 21>;
|
interrupts = <2 21>;
|
||||||
clocks = <&clk_i2c>;
|
clocks = <&clk_i2c>;
|
||||||
|
#address-cells = <1>;
|
||||||
|
#size-cells = <0>;
|
||||||
status = "disabled";
|
status = "disabled";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -27,6 +27,13 @@
|
|||||||
i2c2_bus: i2c2-bus {
|
i2c2_bus: i2c2-bus {
|
||||||
samsung,pin-pud = <0>;
|
samsung,pin-pud = <0>;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
max77686_irq: max77686-irq {
|
||||||
|
samsung,pins = "gpx3-2";
|
||||||
|
samsung,pin-function = <0>;
|
||||||
|
samsung,pin-pud = <0>;
|
||||||
|
samsung,pin-drv = <0>;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
i2c@12C60000 {
|
i2c@12C60000 {
|
||||||
@ -35,6 +42,11 @@
|
|||||||
|
|
||||||
max77686@09 {
|
max77686@09 {
|
||||||
compatible = "maxim,max77686";
|
compatible = "maxim,max77686";
|
||||||
|
interrupt-parent = <&gpx3>;
|
||||||
|
interrupts = <2 0>;
|
||||||
|
pinctrl-names = "default";
|
||||||
|
pinctrl-0 = <&max77686_irq>;
|
||||||
|
wakeup-source;
|
||||||
reg = <0x09>;
|
reg = <0x09>;
|
||||||
|
|
||||||
voltage-regulators {
|
voltage-regulators {
|
||||||
|
@ -161,7 +161,7 @@
|
|||||||
clocks = <&clks 197>, <&clks 3>,
|
clocks = <&clks 197>, <&clks 3>,
|
||||||
<&clks 197>, <&clks 107>,
|
<&clks 197>, <&clks 107>,
|
||||||
<&clks 0>, <&clks 118>,
|
<&clks 0>, <&clks 118>,
|
||||||
<&clks 62>, <&clks 139>,
|
<&clks 0>, <&clks 139>,
|
||||||
<&clks 0>;
|
<&clks 0>;
|
||||||
clock-names = "core", "rxtx0",
|
clock-names = "core", "rxtx0",
|
||||||
"rxtx1", "rxtx2",
|
"rxtx1", "rxtx2",
|
||||||
|
@ -44,8 +44,8 @@
|
|||||||
gpmc,wr-access-ns = <186>;
|
gpmc,wr-access-ns = <186>;
|
||||||
gpmc,cycle2cycle-samecsen;
|
gpmc,cycle2cycle-samecsen;
|
||||||
gpmc,cycle2cycle-diffcsen;
|
gpmc,cycle2cycle-diffcsen;
|
||||||
vmmc-supply = <&vddvario>;
|
vddvario-supply = <&vddvario>;
|
||||||
vmmc_aux-supply = <&vdd33a>;
|
vdd33a-supply = <&vdd33a>;
|
||||||
reg-io-width = <4>;
|
reg-io-width = <4>;
|
||||||
smsc,save-mac-address;
|
smsc,save-mac-address;
|
||||||
};
|
};
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
* they probably share the same GPIO IRQ
|
* they probably share the same GPIO IRQ
|
||||||
* REVISIT: Add timing support from slls644g.pdf
|
* REVISIT: Add timing support from slls644g.pdf
|
||||||
*/
|
*/
|
||||||
8250@3,0 {
|
uart@3,0 {
|
||||||
compatible = "ns16550a";
|
compatible = "ns16550a";
|
||||||
reg = <3 0 0x100>;
|
reg = <3 0 0x100>;
|
||||||
bank-width = <2>;
|
bank-width = <2>;
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user