Merge branch 'master' into for-2.6.35
Conflicts: fs/block_dev.c Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
This commit is contained in:
Коммит
7407cf355f
|
@ -234,7 +234,7 @@ process is as follows:
|
|||
Linus, usually the patches that have already been included in the
|
||||
-next kernel for a few weeks. The preferred way to submit big changes
|
||||
is using git (the kernel's source management tool, more information
|
||||
can be found at http://git.or.cz/) but plain patches are also just
|
||||
can be found at http://git-scm.com/) but plain patches are also just
|
||||
fine.
|
||||
- After two weeks a -rc1 kernel is released it is now possible to push
|
||||
only patches that do not include new features that could affect the
|
||||
|
|
|
@ -34,7 +34,7 @@ NMI handler.
|
|||
cpu = smp_processor_id();
|
||||
++nmi_count(cpu);
|
||||
|
||||
if (!rcu_dereference(nmi_callback)(regs, cpu))
|
||||
if (!rcu_dereference_sched(nmi_callback)(regs, cpu))
|
||||
default_do_nmi(regs);
|
||||
|
||||
nmi_exit();
|
||||
|
@ -47,12 +47,13 @@ function pointer. If this handler returns zero, do_nmi() invokes the
|
|||
default_do_nmi() function to handle a machine-specific NMI. Finally,
|
||||
preemption is restored.
|
||||
|
||||
Strictly speaking, rcu_dereference() is not needed, since this code runs
|
||||
only on i386, which does not need rcu_dereference() anyway. However,
|
||||
it is a good documentation aid, particularly for anyone attempting to
|
||||
do something similar on Alpha.
|
||||
In theory, rcu_dereference_sched() is not needed, since this code runs
|
||||
only on i386, which in theory does not need rcu_dereference_sched()
|
||||
anyway. However, in practice it is a good documentation aid, particularly
|
||||
for anyone attempting to do something similar on Alpha or on systems
|
||||
with aggressive optimizing compilers.
|
||||
|
||||
Quick Quiz: Why might the rcu_dereference() be necessary on Alpha,
|
||||
Quick Quiz: Why might the rcu_dereference_sched() be necessary on Alpha,
|
||||
given that the code referenced by the pointer is read-only?
|
||||
|
||||
|
||||
|
@ -99,17 +100,21 @@ invoke irq_enter() and irq_exit() on NMI entry and exit, respectively.
|
|||
|
||||
Answer to Quick Quiz
|
||||
|
||||
Why might the rcu_dereference() be necessary on Alpha, given
|
||||
Why might the rcu_dereference_sched() be necessary on Alpha, given
|
||||
that the code referenced by the pointer is read-only?
|
||||
|
||||
Answer: The caller to set_nmi_callback() might well have
|
||||
initialized some data that is to be used by the
|
||||
new NMI handler. In this case, the rcu_dereference()
|
||||
would be needed, because otherwise a CPU that received
|
||||
an NMI just after the new handler was set might see
|
||||
the pointer to the new NMI handler, but the old
|
||||
pre-initialized version of the handler's data.
|
||||
initialized some data that is to be used by the new NMI
|
||||
handler. In this case, the rcu_dereference_sched() would
|
||||
be needed, because otherwise a CPU that received an NMI
|
||||
just after the new handler was set might see the pointer
|
||||
to the new NMI handler, but the old pre-initialized
|
||||
version of the handler's data.
|
||||
|
||||
More important, the rcu_dereference() makes it clear
|
||||
to someone reading the code that the pointer is being
|
||||
protected by RCU.
|
||||
This same sad story can happen on other CPUs when using
|
||||
a compiler with aggressive pointer-value speculation
|
||||
optimizations.
|
||||
|
||||
More important, the rcu_dereference_sched() makes it
|
||||
clear to someone reading the code that the pointer is
|
||||
being protected by RCU-sched.
|
||||
|
|
|
@ -260,7 +260,8 @@ over a rather long period of time, but improvements are always welcome!
|
|||
The reason that it is permissible to use RCU list-traversal
|
||||
primitives when the update-side lock is held is that doing so
|
||||
can be quite helpful in reducing code bloat when common code is
|
||||
shared between readers and updaters.
|
||||
shared between readers and updaters. Additional primitives
|
||||
are provided for this case, as discussed in lockdep.txt.
|
||||
|
||||
10. Conversely, if you are in an RCU read-side critical section,
|
||||
and you don't hold the appropriate update-side lock, you -must-
|
||||
|
@ -344,8 +345,8 @@ over a rather long period of time, but improvements are always welcome!
|
|||
requiring SRCU's read-side deadlock immunity or low read-side
|
||||
realtime latency.
|
||||
|
||||
Note that, rcu_assign_pointer() and rcu_dereference() relate to
|
||||
SRCU just as they do to other forms of RCU.
|
||||
Note that, rcu_assign_pointer() relates to SRCU just as they do
|
||||
to other forms of RCU.
|
||||
|
||||
15. The whole point of call_rcu(), synchronize_rcu(), and friends
|
||||
is to wait until all pre-existing readers have finished before
|
||||
|
|
|
@ -32,9 +32,20 @@ checking of rcu_dereference() primitives:
|
|||
srcu_dereference(p, sp):
|
||||
Check for SRCU read-side critical section.
|
||||
rcu_dereference_check(p, c):
|
||||
Use explicit check expression "c".
|
||||
Use explicit check expression "c". This is useful in
|
||||
code that is invoked by both readers and updaters.
|
||||
rcu_dereference_raw(p)
|
||||
Don't check. (Use sparingly, if at all.)
|
||||
rcu_dereference_protected(p, c):
|
||||
Use explicit check expression "c", and omit all barriers
|
||||
and compiler constraints. This is useful when the data
|
||||
structure cannot change, for example, in code that is
|
||||
invoked only by updaters.
|
||||
rcu_access_pointer(p):
|
||||
Return the value of the pointer and omit all barriers,
|
||||
but retain the compiler constraints that prevent duplicating
|
||||
or coalescsing. This is useful when when testing the
|
||||
value of the pointer itself, for example, against NULL.
|
||||
|
||||
The rcu_dereference_check() check expression can be any boolean
|
||||
expression, but would normally include one of the rcu_read_lock_held()
|
||||
|
@ -59,7 +70,20 @@ In case (1), the pointer is picked up in an RCU-safe manner for vanilla
|
|||
RCU read-side critical sections, in case (2) the ->file_lock prevents
|
||||
any change from taking place, and finally, in case (3) the current task
|
||||
is the only task accessing the file_struct, again preventing any change
|
||||
from taking place.
|
||||
from taking place. If the above statement was invoked only from updater
|
||||
code, it could instead be written as follows:
|
||||
|
||||
file = rcu_dereference_protected(fdt->fd[fd],
|
||||
lockdep_is_held(&files->file_lock) ||
|
||||
atomic_read(&files->count) == 1);
|
||||
|
||||
This would verify cases #2 and #3 above, and furthermore lockdep would
|
||||
complain if this was used in an RCU read-side critical section unless one
|
||||
of these two cases held. Because rcu_dereference_protected() omits all
|
||||
barriers and compiler constraints, it generates better code than do the
|
||||
other flavors of rcu_dereference(). On the other hand, it is illegal
|
||||
to use rcu_dereference_protected() if either the RCU-protected pointer
|
||||
or the RCU-protected data that it points to can change concurrently.
|
||||
|
||||
There are currently only "universal" versions of the rcu_assign_pointer()
|
||||
and RCU list-/tree-traversal primitives, which do not (yet) check for
|
||||
|
|
|
@ -840,6 +840,12 @@ SRCU: Initialization/cleanup
|
|||
init_srcu_struct
|
||||
cleanup_srcu_struct
|
||||
|
||||
All: lockdep-checked RCU-protected pointer access
|
||||
|
||||
rcu_dereference_check
|
||||
rcu_dereference_protected
|
||||
rcu_access_pointer
|
||||
|
||||
See the comment headers in the source code (or the docbook generated
|
||||
from them) for more information.
|
||||
|
||||
|
|
|
@ -235,8 +235,7 @@ containing the following files describing that cgroup:
|
|||
- cgroup.procs: list of tgids in the cgroup. This list is not
|
||||
guaranteed to be sorted or free of duplicate tgids, and userspace
|
||||
should sort/uniquify the list if this property is required.
|
||||
Writing a tgid into this file moves all threads with that tgid into
|
||||
this cgroup.
|
||||
This is a read-only file, for now.
|
||||
- notify_on_release flag: run the release agent on exit?
|
||||
- release_agent: the path to use for release notifications (this file
|
||||
exists in the top cgroup only)
|
||||
|
|
|
@ -68,6 +68,22 @@ like:
|
|||
SYN_MT_REPORT
|
||||
SYN_REPORT
|
||||
|
||||
Here is the sequence after lifting one of the fingers:
|
||||
|
||||
ABS_MT_POSITION_X
|
||||
ABS_MT_POSITION_Y
|
||||
SYN_MT_REPORT
|
||||
SYN_REPORT
|
||||
|
||||
And here is the sequence after lifting the remaining finger:
|
||||
|
||||
SYN_MT_REPORT
|
||||
SYN_REPORT
|
||||
|
||||
If the driver reports one of BTN_TOUCH or ABS_PRESSURE in addition to the
|
||||
ABS_MT events, the last SYN_MT_REPORT event may be omitted. Otherwise, the
|
||||
last SYN_REPORT will be dropped by the input core, resulting in no
|
||||
zero-finger event reaching userland.
|
||||
|
||||
Event Semantics
|
||||
---------------
|
||||
|
@ -217,11 +233,6 @@ where examples can be found.
|
|||
difference between the contact position and the approaching tool position
|
||||
could be used to derive tilt.
|
||||
[2] The list can of course be extended.
|
||||
[3] The multi-touch X driver is currently in the prototyping stage. At the
|
||||
time of writing (April 2009), the MT protocol is not yet merged, and the
|
||||
prototype implements finger matching, basic mouse support and two-finger
|
||||
scrolling. The project aims at improving the quality of current multi-touch
|
||||
functionality available in the Synaptics X driver, and in addition
|
||||
implement more advanced gestures.
|
||||
[3] Multitouch X driver project: http://bitmath.org/code/multitouch/.
|
||||
[4] See the section on event computation.
|
||||
[5] See the section on finger tracking.
|
||||
|
|
|
@ -320,11 +320,6 @@ and is between 256 and 4096 characters. It is defined in the file
|
|||
amd_iommu= [HW,X86-84]
|
||||
Pass parameters to the AMD IOMMU driver in the system.
|
||||
Possible values are:
|
||||
isolate - enable device isolation (each device, as far
|
||||
as possible, will get its own protection
|
||||
domain) [default]
|
||||
share - put every device behind one IOMMU into the
|
||||
same protection domain
|
||||
fullflush - enable flushing of IO/TLB entries when
|
||||
they are unmapped. Otherwise they are
|
||||
flushed before they will be reused, which
|
||||
|
@ -1199,7 +1194,7 @@ and is between 256 and 4096 characters. It is defined in the file
|
|||
|
||||
libata.force= [LIBATA] Force configurations. The format is comma
|
||||
separated list of "[ID:]VAL" where ID is
|
||||
PORT[:DEVICE]. PORT and DEVICE are decimal numbers
|
||||
PORT[.DEVICE]. PORT and DEVICE are decimal numbers
|
||||
matching port, link or device. Basically, it matches
|
||||
the ATA ID string printed on console by libata. If
|
||||
the whole ID part is omitted, the last PORT and DEVICE
|
||||
|
|
|
@ -41,11 +41,12 @@ SOF_TIMESTAMPING_SOFTWARE: return system time stamp generated in
|
|||
SOF_TIMESTAMPING_TX/RX determine how time stamps are generated.
|
||||
SOF_TIMESTAMPING_RAW/SYS determine how they are reported in the
|
||||
following control message:
|
||||
struct scm_timestamping {
|
||||
struct timespec systime;
|
||||
struct timespec hwtimetrans;
|
||||
struct timespec hwtimeraw;
|
||||
};
|
||||
|
||||
struct scm_timestamping {
|
||||
struct timespec systime;
|
||||
struct timespec hwtimetrans;
|
||||
struct timespec hwtimeraw;
|
||||
};
|
||||
|
||||
recvmsg() can be used to get this control message for regular incoming
|
||||
packets. For send time stamps the outgoing packet is looped back to
|
||||
|
@ -87,12 +88,13 @@ by the network device and will be empty without that support.
|
|||
SIOCSHWTSTAMP:
|
||||
|
||||
Hardware time stamping must also be initialized for each device driver
|
||||
that is expected to do hardware time stamping. The parameter is:
|
||||
that is expected to do hardware time stamping. The parameter is defined in
|
||||
/include/linux/net_tstamp.h as:
|
||||
|
||||
struct hwtstamp_config {
|
||||
int flags; /* no flags defined right now, must be zero */
|
||||
int tx_type; /* HWTSTAMP_TX_* */
|
||||
int rx_filter; /* HWTSTAMP_FILTER_* */
|
||||
int flags; /* no flags defined right now, must be zero */
|
||||
int tx_type; /* HWTSTAMP_TX_* */
|
||||
int rx_filter; /* HWTSTAMP_FILTER_* */
|
||||
};
|
||||
|
||||
Desired behavior is passed into the kernel and to a specific device by
|
||||
|
@ -139,42 +141,56 @@ enum {
|
|||
/* time stamp any incoming packet */
|
||||
HWTSTAMP_FILTER_ALL,
|
||||
|
||||
/* return value: time stamp all packets requested plus some others */
|
||||
HWTSTAMP_FILTER_SOME,
|
||||
/* return value: time stamp all packets requested plus some others */
|
||||
HWTSTAMP_FILTER_SOME,
|
||||
|
||||
/* PTP v1, UDP, any kind of event packet */
|
||||
HWTSTAMP_FILTER_PTP_V1_L4_EVENT,
|
||||
|
||||
...
|
||||
/* for the complete list of values, please check
|
||||
* the include file /include/linux/net_tstamp.h
|
||||
*/
|
||||
};
|
||||
|
||||
|
||||
DEVICE IMPLEMENTATION
|
||||
|
||||
A driver which supports hardware time stamping must support the
|
||||
SIOCSHWTSTAMP ioctl. Time stamps for received packets must be stored
|
||||
in the skb with skb_hwtstamp_set().
|
||||
SIOCSHWTSTAMP ioctl and update the supplied struct hwtstamp_config with
|
||||
the actual values as described in the section on SIOCSHWTSTAMP.
|
||||
|
||||
Time stamps for received packets must be stored in the skb. To get a pointer
|
||||
to the shared time stamp structure of the skb call skb_hwtstamps(). Then
|
||||
set the time stamps in the structure:
|
||||
|
||||
struct skb_shared_hwtstamps {
|
||||
/* hardware time stamp transformed into duration
|
||||
* since arbitrary point in time
|
||||
*/
|
||||
ktime_t hwtstamp;
|
||||
ktime_t syststamp; /* hwtstamp transformed to system time base */
|
||||
};
|
||||
|
||||
Time stamps for outgoing packets are to be generated as follows:
|
||||
- In hard_start_xmit(), check if skb_hwtstamp_check_tx_hardware()
|
||||
returns non-zero. If yes, then the driver is expected
|
||||
to do hardware time stamping.
|
||||
- In hard_start_xmit(), check if skb_tx(skb)->hardware is set no-zero.
|
||||
If yes, then the driver is expected to do hardware time stamping.
|
||||
- If this is possible for the skb and requested, then declare
|
||||
that the driver is doing the time stamping by calling
|
||||
skb_hwtstamp_tx_in_progress(). A driver not supporting
|
||||
hardware time stamping doesn't do that. A driver must never
|
||||
touch sk_buff::tstamp! It is used to store how time stamping
|
||||
for an outgoing packets is to be done.
|
||||
that the driver is doing the time stamping by setting the field
|
||||
skb_tx(skb)->in_progress non-zero. You might want to keep a pointer
|
||||
to the associated skb for the next step and not free the skb. A driver
|
||||
not supporting hardware time stamping doesn't do that. A driver must
|
||||
never touch sk_buff::tstamp! It is used to store software generated
|
||||
time stamps by the network subsystem.
|
||||
- As soon as the driver has sent the packet and/or obtained a
|
||||
hardware time stamp for it, it passes the time stamp back by
|
||||
calling skb_hwtstamp_tx() with the original skb, the raw
|
||||
hardware time stamp and a handle to the device (necessary
|
||||
to convert the hardware time stamp to system time). If obtaining
|
||||
the hardware time stamp somehow fails, then the driver should
|
||||
not fall back to software time stamping. The rationale is that
|
||||
this would occur at a later time in the processing pipeline
|
||||
than other software time stamping and therefore could lead
|
||||
to unexpected deltas between time stamps.
|
||||
- If the driver did not call skb_hwtstamp_tx_in_progress(), then
|
||||
hardware time stamp. skb_hwtstamp_tx() clones the original skb and
|
||||
adds the timestamps, therefore the original skb has to be freed now.
|
||||
If obtaining the hardware time stamp somehow fails, then the driver
|
||||
should not fall back to software time stamping. The rationale is that
|
||||
this would occur at a later time in the processing pipeline than other
|
||||
software time stamping and therefore could lead to unexpected deltas
|
||||
between time stamps.
|
||||
- If the driver did not call set skb_tx(skb)->in_progress, then
|
||||
dev_hard_start_xmit() checks whether software time stamping
|
||||
is wanted as fallback and potentially generates the time stamp.
|
||||
|
|
|
@ -18,16 +18,15 @@ Rules on what kind of patches are accepted, and which ones are not, into the
|
|||
- It cannot contain any "trivial" fixes in it (spelling changes,
|
||||
whitespace cleanups, etc).
|
||||
- It must follow the Documentation/SubmittingPatches rules.
|
||||
- It or an equivalent fix must already exist in Linus' tree. Quote the
|
||||
respective commit ID in Linus' tree in your patch submission to -stable.
|
||||
- It or an equivalent fix must already exist in Linus' tree (upstream).
|
||||
|
||||
|
||||
Procedure for submitting patches to the -stable tree:
|
||||
|
||||
- Send the patch, after verifying that it follows the above rules, to
|
||||
stable@kernel.org.
|
||||
- To have the patch automatically included in the stable tree, add the
|
||||
the tag
|
||||
stable@kernel.org. You must note the upstream commit ID in the changelog
|
||||
of your submission.
|
||||
- To have the patch automatically included in the stable tree, add the tag
|
||||
Cc: stable@kernel.org
|
||||
in the sign-off area. Once the patch is merged it will be applied to
|
||||
the stable tree without anything else needing to be done by the author
|
||||
|
|
|
@ -485,8 +485,8 @@ S: Maintained
|
|||
F: drivers/input/mouse/bcm5974.c
|
||||
|
||||
APPLE SMC DRIVER
|
||||
M: Nicolas Boichat <nicolas@boichat.ch>
|
||||
L: mactel-linux-devel@lists.sourceforge.net
|
||||
M: Henrik Rydberg <rydberg@euromail.se>
|
||||
L: lm-sensors@lm-sensors.org
|
||||
S: Maintained
|
||||
F: drivers/hwmon/applesmc.c
|
||||
|
||||
|
@ -1960,7 +1960,7 @@ F: lib/kobj*
|
|||
|
||||
DRM DRIVERS
|
||||
M: David Airlie <airlied@linux.ie>
|
||||
L: dri-devel@lists.sourceforge.net
|
||||
L: dri-devel@lists.freedesktop.org
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/airlied/drm-2.6.git
|
||||
S: Maintained
|
||||
F: drivers/gpu/drm/
|
||||
|
@ -4791,12 +4791,11 @@ F: drivers/s390/crypto/
|
|||
|
||||
S390 ZFCP DRIVER
|
||||
M: Christof Schmitt <christof.schmitt@de.ibm.com>
|
||||
M: Martin Peschke <mp3@de.ibm.com>
|
||||
M: Swen Schillig <swen@vnet.ibm.com>
|
||||
M: linux390@de.ibm.com
|
||||
L: linux-s390@vger.kernel.org
|
||||
W: http://www.ibm.com/developerworks/linux/linux390/
|
||||
S: Supported
|
||||
F: Documentation/s390/zfcpdump.txt
|
||||
F: drivers/s390/scsi/zfcp_*
|
||||
|
||||
S390 IUCV NETWORK LAYER
|
||||
|
|
4
Makefile
4
Makefile
|
@ -1,8 +1,8 @@
|
|||
VERSION = 2
|
||||
PATCHLEVEL = 6
|
||||
SUBLEVEL = 34
|
||||
EXTRAVERSION = -rc4
|
||||
NAME = Man-Eating Seals of Antiquity
|
||||
EXTRAVERSION = -rc5
|
||||
NAME = Sheep on Meth
|
||||
|
||||
# *DOCUMENTATION*
|
||||
# To see a list of typical targets execute "make help"
|
||||
|
|
|
@ -1058,7 +1058,6 @@ CONFIG_JFFS2_CMODE_PRIORITY=y
|
|||
# CONFIG_ROMFS_FS is not set
|
||||
# CONFIG_SYSV_FS is not set
|
||||
# CONFIG_UFS_FS is not set
|
||||
# CONFIG_NILFS2_FS is not set
|
||||
CONFIG_NETWORK_FILESYSTEMS=y
|
||||
# CONFIG_NFS_FS is not set
|
||||
# CONFIG_NFSD is not set
|
||||
|
|
|
@ -661,7 +661,7 @@ CONFIG_DEVKMEM=y
|
|||
CONFIG_SERIAL_8250=y
|
||||
CONFIG_SERIAL_8250_CONSOLE=y
|
||||
CONFIG_SERIAL_8250_NR_UARTS=32
|
||||
CONFIG_SERIAL_8250_RUNTIME_UARTS=4
|
||||
CONFIG_SERIAL_8250_RUNTIME_UARTS=1
|
||||
CONFIG_SERIAL_8250_EXTENDED=y
|
||||
CONFIG_SERIAL_8250_MANY_PORTS=y
|
||||
CONFIG_SERIAL_8250_SHARE_IRQ=y
|
||||
|
|
|
@ -680,7 +680,7 @@ CONFIG_DEVKMEM=y
|
|||
CONFIG_SERIAL_8250=y
|
||||
CONFIG_SERIAL_8250_CONSOLE=y
|
||||
CONFIG_SERIAL_8250_NR_UARTS=32
|
||||
CONFIG_SERIAL_8250_RUNTIME_UARTS=4
|
||||
CONFIG_SERIAL_8250_RUNTIME_UARTS=1
|
||||
CONFIG_SERIAL_8250_EXTENDED=y
|
||||
CONFIG_SERIAL_8250_MANY_PORTS=y
|
||||
CONFIG_SERIAL_8250_SHARE_IRQ=y
|
||||
|
|
|
@ -59,8 +59,6 @@ CONFIG_FAIR_GROUP_SCHED=y
|
|||
CONFIG_USER_SCHED=y
|
||||
# CONFIG_CGROUP_SCHED is not set
|
||||
# CONFIG_CGROUPS is not set
|
||||
CONFIG_SYSFS_DEPRECATED=y
|
||||
CONFIG_SYSFS_DEPRECATED_V2=y
|
||||
# CONFIG_RELAY is not set
|
||||
# CONFIG_NAMESPACES is not set
|
||||
CONFIG_BLK_DEV_INITRD=y
|
||||
|
@ -480,7 +478,6 @@ CONFIG_BT_HIDP=m
|
|||
# CONFIG_BT_HCIBFUSB is not set
|
||||
# CONFIG_BT_HCIVHCI is not set
|
||||
# CONFIG_AF_RXRPC is not set
|
||||
# CONFIG_PHONET is not set
|
||||
CONFIG_WIRELESS=y
|
||||
CONFIG_CFG80211=y
|
||||
# CONFIG_CFG80211_REG_DEBUG is not set
|
||||
|
|
|
@ -11,7 +11,11 @@
|
|||
|
||||
#define kmap_prot PAGE_KERNEL
|
||||
|
||||
#define flush_cache_kmaps() flush_cache_all()
|
||||
#define flush_cache_kmaps() \
|
||||
do { \
|
||||
if (cache_is_vivt()) \
|
||||
flush_cache_all(); \
|
||||
} while (0)
|
||||
|
||||
extern pte_t *pkmap_page_table;
|
||||
|
||||
|
@ -21,11 +25,20 @@ extern void *kmap_high(struct page *page);
|
|||
extern void *kmap_high_get(struct page *page);
|
||||
extern void kunmap_high(struct page *page);
|
||||
|
||||
extern void *kmap_high_l1_vipt(struct page *page, pte_t *saved_pte);
|
||||
extern void kunmap_high_l1_vipt(struct page *page, pte_t saved_pte);
|
||||
|
||||
/*
|
||||
* The following functions are already defined by <linux/highmem.h>
|
||||
* when CONFIG_HIGHMEM is not set.
|
||||
*/
|
||||
#ifdef CONFIG_HIGHMEM
|
||||
extern void *kmap(struct page *page);
|
||||
extern void kunmap(struct page *page);
|
||||
extern void *kmap_atomic(struct page *page, enum km_type type);
|
||||
extern void kunmap_atomic(void *kvaddr, enum km_type type);
|
||||
extern void *kmap_atomic_pfn(unsigned long pfn, enum km_type type);
|
||||
extern struct page *kmap_atomic_to_page(const void *ptr);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -18,6 +18,7 @@ enum km_type {
|
|||
KM_IRQ1,
|
||||
KM_SOFTIRQ0,
|
||||
KM_SOFTIRQ1,
|
||||
KM_L1_CACHE,
|
||||
KM_L2_CACHE,
|
||||
KM_TYPE_NR
|
||||
};
|
||||
|
|
|
@ -59,23 +59,22 @@ struct iwmmxt_sigframe {
|
|||
#endif /* CONFIG_IWMMXT */
|
||||
|
||||
#ifdef CONFIG_VFP
|
||||
#if __LINUX_ARM_ARCH__ < 6
|
||||
/* For ARM pre-v6, we use fstmiax and fldmiax. This adds one extra
|
||||
* word after the registers, and a word of padding at the end for
|
||||
* alignment. */
|
||||
#define VFP_MAGIC 0x56465001
|
||||
#define VFP_STORAGE_SIZE 152
|
||||
#else
|
||||
#define VFP_MAGIC 0x56465002
|
||||
#define VFP_STORAGE_SIZE 144
|
||||
#endif
|
||||
|
||||
struct vfp_sigframe
|
||||
{
|
||||
unsigned long magic;
|
||||
unsigned long size;
|
||||
union vfp_state storage;
|
||||
};
|
||||
struct user_vfp ufp;
|
||||
struct user_vfp_exc ufp_exc;
|
||||
} __attribute__((__aligned__(8)));
|
||||
|
||||
/*
|
||||
* 8 byte for magic and size, 264 byte for ufp, 12 bytes for ufp_exc,
|
||||
* 4 bytes padding.
|
||||
*/
|
||||
#define VFP_STORAGE_SIZE sizeof(struct vfp_sigframe)
|
||||
|
||||
#endif /* CONFIG_VFP */
|
||||
|
||||
/*
|
||||
|
@ -91,7 +90,7 @@ struct aux_sigframe {
|
|||
#ifdef CONFIG_IWMMXT
|
||||
struct iwmmxt_sigframe iwmmxt;
|
||||
#endif
|
||||
#if 0 && defined CONFIG_VFP /* Not yet saved. */
|
||||
#ifdef CONFIG_VFP
|
||||
struct vfp_sigframe vfp;
|
||||
#endif
|
||||
/* Something that isn't a valid magic number for any coprocessor. */
|
||||
|
|
|
@ -83,11 +83,21 @@ struct user{
|
|||
|
||||
/*
|
||||
* User specific VFP registers. If only VFPv2 is present, registers 16 to 31
|
||||
* are ignored by the ptrace system call.
|
||||
* are ignored by the ptrace system call and the signal handler.
|
||||
*/
|
||||
struct user_vfp {
|
||||
unsigned long long fpregs[32];
|
||||
unsigned long fpscr;
|
||||
};
|
||||
|
||||
/*
|
||||
* VFP exception registers exposed to user space during signal delivery.
|
||||
* Fields not relavant to the current VFP architecture are ignored.
|
||||
*/
|
||||
struct user_vfp_exc {
|
||||
unsigned long fpexc;
|
||||
unsigned long fpinst;
|
||||
unsigned long fpinst2;
|
||||
};
|
||||
|
||||
#endif /* _ARM_USER_H */
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include <asm/cacheflush.h>
|
||||
#include <asm/ucontext.h>
|
||||
#include <asm/unistd.h>
|
||||
#include <asm/vfp.h>
|
||||
|
||||
#include "ptrace.h"
|
||||
#include "signal.h"
|
||||
|
@ -175,6 +176,90 @@ static int restore_iwmmxt_context(struct iwmmxt_sigframe *frame)
|
|||
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_VFP
|
||||
|
||||
static int preserve_vfp_context(struct vfp_sigframe __user *frame)
|
||||
{
|
||||
struct thread_info *thread = current_thread_info();
|
||||
struct vfp_hard_struct *h = &thread->vfpstate.hard;
|
||||
const unsigned long magic = VFP_MAGIC;
|
||||
const unsigned long size = VFP_STORAGE_SIZE;
|
||||
int err = 0;
|
||||
|
||||
vfp_sync_hwstate(thread);
|
||||
__put_user_error(magic, &frame->magic, err);
|
||||
__put_user_error(size, &frame->size, err);
|
||||
|
||||
/*
|
||||
* Copy the floating point registers. There can be unused
|
||||
* registers see asm/hwcap.h for details.
|
||||
*/
|
||||
err |= __copy_to_user(&frame->ufp.fpregs, &h->fpregs,
|
||||
sizeof(h->fpregs));
|
||||
/*
|
||||
* Copy the status and control register.
|
||||
*/
|
||||
__put_user_error(h->fpscr, &frame->ufp.fpscr, err);
|
||||
|
||||
/*
|
||||
* Copy the exception registers.
|
||||
*/
|
||||
__put_user_error(h->fpexc, &frame->ufp_exc.fpexc, err);
|
||||
__put_user_error(h->fpinst, &frame->ufp_exc.fpinst, err);
|
||||
__put_user_error(h->fpinst2, &frame->ufp_exc.fpinst2, err);
|
||||
|
||||
return err ? -EFAULT : 0;
|
||||
}
|
||||
|
||||
static int restore_vfp_context(struct vfp_sigframe __user *frame)
|
||||
{
|
||||
struct thread_info *thread = current_thread_info();
|
||||
struct vfp_hard_struct *h = &thread->vfpstate.hard;
|
||||
unsigned long magic;
|
||||
unsigned long size;
|
||||
unsigned long fpexc;
|
||||
int err = 0;
|
||||
|
||||
__get_user_error(magic, &frame->magic, err);
|
||||
__get_user_error(size, &frame->size, err);
|
||||
|
||||
if (err)
|
||||
return -EFAULT;
|
||||
if (magic != VFP_MAGIC || size != VFP_STORAGE_SIZE)
|
||||
return -EINVAL;
|
||||
|
||||
/*
|
||||
* Copy the floating point registers. There can be unused
|
||||
* registers see asm/hwcap.h for details.
|
||||
*/
|
||||
err |= __copy_from_user(&h->fpregs, &frame->ufp.fpregs,
|
||||
sizeof(h->fpregs));
|
||||
/*
|
||||
* Copy the status and control register.
|
||||
*/
|
||||
__get_user_error(h->fpscr, &frame->ufp.fpscr, err);
|
||||
|
||||
/*
|
||||
* Sanitise and restore the exception registers.
|
||||
*/
|
||||
__get_user_error(fpexc, &frame->ufp_exc.fpexc, err);
|
||||
/* Ensure the VFP is enabled. */
|
||||
fpexc |= FPEXC_EN;
|
||||
/* Ensure FPINST2 is invalid and the exception flag is cleared. */
|
||||
fpexc &= ~(FPEXC_EX | FPEXC_FP2V);
|
||||
h->fpexc = fpexc;
|
||||
|
||||
__get_user_error(h->fpinst, &frame->ufp_exc.fpinst, err);
|
||||
__get_user_error(h->fpinst2, &frame->ufp_exc.fpinst2, err);
|
||||
|
||||
if (!err)
|
||||
vfp_flush_hwstate(thread);
|
||||
|
||||
return err ? -EFAULT : 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Do a signal return; undo the signal stack. These are aligned to 64-bit.
|
||||
*/
|
||||
|
@ -233,8 +318,8 @@ static int restore_sigframe(struct pt_regs *regs, struct sigframe __user *sf)
|
|||
err |= restore_iwmmxt_context(&aux->iwmmxt);
|
||||
#endif
|
||||
#ifdef CONFIG_VFP
|
||||
// if (err == 0)
|
||||
// err |= vfp_restore_state(&sf->aux.vfp);
|
||||
if (err == 0)
|
||||
err |= restore_vfp_context(&aux->vfp);
|
||||
#endif
|
||||
|
||||
return err;
|
||||
|
@ -348,8 +433,8 @@ setup_sigframe(struct sigframe __user *sf, struct pt_regs *regs, sigset_t *set)
|
|||
err |= preserve_iwmmxt_context(&aux->iwmmxt);
|
||||
#endif
|
||||
#ifdef CONFIG_VFP
|
||||
// if (err == 0)
|
||||
// err |= vfp_save_state(&sf->aux.vfp);
|
||||
if (err == 0)
|
||||
err |= preserve_vfp_context(&aux->vfp);
|
||||
#endif
|
||||
__put_user_error(0, &aux->end_magic, err);
|
||||
|
||||
|
|
|
@ -16,8 +16,8 @@ obj-$(CONFIG_ARCH_AT91SAM9261) += at91sam9261.o at91sam926x_time.o at91sam9261_d
|
|||
obj-$(CONFIG_ARCH_AT91SAM9G10) += at91sam9261.o at91sam926x_time.o at91sam9261_devices.o sam9_smc.o
|
||||
obj-$(CONFIG_ARCH_AT91SAM9263) += at91sam9263.o at91sam926x_time.o at91sam9263_devices.o sam9_smc.o
|
||||
obj-$(CONFIG_ARCH_AT91SAM9RL) += at91sam9rl.o at91sam926x_time.o at91sam9rl_devices.o sam9_smc.o
|
||||
obj-$(CONFIG_ARCH_AT91SAM9G20) += at91sam9260.o at91sam926x_time.o at91sam9260_devices.o sam9_smc.o
|
||||
obj-$(CONFIG_ARCH_AT91SAM9G45) += at91sam9g45.o at91sam926x_time.o at91sam9g45_devices.o sam9_smc.o
|
||||
obj-$(CONFIG_ARCH_AT91SAM9G20) += at91sam9260.o at91sam926x_time.o at91sam9260_devices.o sam9_smc.o
|
||||
obj-$(CONFIG_ARCH_AT91SAM9G45) += at91sam9g45.o at91sam926x_time.o at91sam9g45_devices.o sam9_smc.o
|
||||
obj-$(CONFIG_ARCH_AT91CAP9) += at91cap9.o at91sam926x_time.o at91cap9_devices.o sam9_smc.o
|
||||
obj-$(CONFIG_ARCH_AT572D940HF) += at572d940hf.o at91sam926x_time.o at572d940hf_devices.o sam9_smc.o
|
||||
obj-$(CONFIG_ARCH_AT91X40) += at91x40.o at91x40_time.o
|
||||
|
|
|
@ -175,8 +175,6 @@ ENTRY(at91_slow_clock)
|
|||
orr r3, r3, #(1 << 29) /* bit 29 always set */
|
||||
str r3, [r1, #(AT91_CKGR_PLLAR - AT91_PMC)]
|
||||
|
||||
wait_pllalock
|
||||
|
||||
/* Save PLLB setting and disable it */
|
||||
ldr r3, [r1, #(AT91_CKGR_PLLBR - AT91_PMC)]
|
||||
str r3, .saved_pllbr
|
||||
|
@ -184,8 +182,6 @@ ENTRY(at91_slow_clock)
|
|||
mov r3, #AT91_PMC_PLLCOUNT
|
||||
str r3, [r1, #(AT91_CKGR_PLLBR - AT91_PMC)]
|
||||
|
||||
wait_pllblock
|
||||
|
||||
/* Turn off the main oscillator */
|
||||
ldr r3, [r1, #(AT91_CKGR_MOR - AT91_PMC)]
|
||||
bic r3, r3, #AT91_PMC_MOSCEN
|
||||
|
|
|
@ -68,12 +68,6 @@ struct sys_timer omap_timer;
|
|||
* ---------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#if defined(CONFIG_ARCH_OMAP16XX)
|
||||
#define TIMER_32K_SYNCHRONIZED 0xfffbc410
|
||||
#else
|
||||
#error OMAP 32KHz timer does not currently work on 15XX!
|
||||
#endif
|
||||
|
||||
/* 16xx specific defines */
|
||||
#define OMAP1_32K_TIMER_BASE 0xfffb9000
|
||||
#define OMAP1_32K_TIMER_CR 0x08
|
||||
|
@ -150,15 +144,6 @@ static struct clock_event_device clockevent_32k_timer = {
|
|||
.set_mode = omap_32k_timer_set_mode,
|
||||
};
|
||||
|
||||
/*
|
||||
* The 32KHz synchronized timer is an additional timer on 16xx.
|
||||
* It is always running.
|
||||
*/
|
||||
static inline unsigned long omap_32k_sync_timer_read(void)
|
||||
{
|
||||
return omap_readl(TIMER_32K_SYNCHRONIZED);
|
||||
}
|
||||
|
||||
static irqreturn_t omap_32k_timer_interrupt(int irq, void *dev_id)
|
||||
{
|
||||
struct clock_event_device *evt = &clockevent_32k_timer;
|
||||
|
|
|
@ -59,8 +59,10 @@ config MACH_OMAP3_BEAGLE
|
|||
select OMAP_PACKAGE_CBB
|
||||
|
||||
config MACH_DEVKIT8000
|
||||
bool "DEVKIT8000 board"
|
||||
depends on ARCH_OMAP3
|
||||
bool "DEVKIT8000 board"
|
||||
depends on ARCH_OMAP3
|
||||
select OMAP_PACKAGE_CUS
|
||||
select OMAP_MUX
|
||||
|
||||
config MACH_OMAP_LDP
|
||||
bool "OMAP3 LDP board"
|
||||
|
|
|
@ -96,6 +96,7 @@ static struct omap_board_mux board_mux[] __initdata = {
|
|||
static void __init omap_sdp_init(void)
|
||||
{
|
||||
omap3_mux_init(board_mux, OMAP_PACKAGE_CBP);
|
||||
omap_serial_init();
|
||||
zoom_peripherals_init();
|
||||
board_smc91x_init();
|
||||
enable_board_wakeup_source();
|
||||
|
|
|
@ -294,9 +294,9 @@ static struct omap_board_mux board_mux[] __initdata = {
|
|||
|
||||
static void __init am3517_evm_init(void)
|
||||
{
|
||||
am3517_evm_i2c_init();
|
||||
|
||||
omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
|
||||
|
||||
am3517_evm_i2c_init();
|
||||
platform_add_devices(am3517_evm_devices,
|
||||
ARRAY_SIZE(am3517_evm_devices));
|
||||
|
||||
|
|
|
@ -50,7 +50,6 @@
|
|||
#include <linux/input/matrix_keypad.h>
|
||||
#include <linux/spi/spi.h>
|
||||
#include <linux/spi/ads7846.h>
|
||||
#include <linux/usb/otg.h>
|
||||
#include <linux/dm9000.h>
|
||||
#include <linux/interrupt.h>
|
||||
|
||||
|
@ -269,20 +268,6 @@ static int devkit8000_twl_gpio_setup(struct device *dev,
|
|||
devkit8000_vmmc1_supply.dev = mmc[0].dev;
|
||||
devkit8000_vsim_supply.dev = mmc[0].dev;
|
||||
|
||||
/* REVISIT: need ehci-omap hooks for external VBUS
|
||||
* power switch and overcurrent detect
|
||||
*/
|
||||
|
||||
gpio_request(gpio + 1, "EHCI_nOC");
|
||||
gpio_direction_input(gpio + 1);
|
||||
|
||||
/* TWL4030_GPIO_MAX + 0 == ledA, EHCI nEN_USB_PWR (out, active low) */
|
||||
gpio_request(gpio + TWL4030_GPIO_MAX, "nEN_USB_PWR");
|
||||
gpio_direction_output(gpio + TWL4030_GPIO_MAX, 1);
|
||||
|
||||
/* TWL4030_GPIO_MAX + 1 == ledB, PMU_STAT (out, active low LED) */
|
||||
gpio_leds[2].gpio = gpio + TWL4030_GPIO_MAX + 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -303,7 +288,7 @@ static struct regulator_consumer_supply devkit8000_vpll2_supplies[] = {
|
|||
.dev = &devkit8000_lcd_device.dev,
|
||||
},
|
||||
{
|
||||
.supply = "vdss_dsi",
|
||||
.supply = "vdds_dsi",
|
||||
.dev = &devkit8000_dss_device.dev,
|
||||
}
|
||||
};
|
||||
|
@ -639,17 +624,21 @@ static struct omap_musb_board_data musb_board_data = {
|
|||
static const struct ehci_hcd_omap_platform_data ehci_pdata __initconst = {
|
||||
|
||||
.port_mode[0] = EHCI_HCD_OMAP_MODE_PHY,
|
||||
.port_mode[1] = EHCI_HCD_OMAP_MODE_PHY,
|
||||
.port_mode[1] = EHCI_HCD_OMAP_MODE_UNKNOWN,
|
||||
.port_mode[2] = EHCI_HCD_OMAP_MODE_UNKNOWN,
|
||||
|
||||
.phy_reset = true,
|
||||
.reset_gpio_port[0] = -EINVAL,
|
||||
.reset_gpio_port[1] = 147,
|
||||
.reset_gpio_port[1] = -EINVAL,
|
||||
.reset_gpio_port[2] = -EINVAL
|
||||
};
|
||||
|
||||
static void __init devkit8000_init(void)
|
||||
{
|
||||
omap_serial_init();
|
||||
|
||||
omap_dm9000_init();
|
||||
|
||||
devkit8000_i2c_init();
|
||||
platform_add_devices(devkit8000_devices,
|
||||
ARRAY_SIZE(devkit8000_devices));
|
||||
|
@ -659,25 +648,15 @@ static void __init devkit8000_init(void)
|
|||
spi_register_board_info(devkit8000_spi_board_info,
|
||||
ARRAY_SIZE(devkit8000_spi_board_info));
|
||||
|
||||
omap_serial_init();
|
||||
|
||||
omap_dm9000_init();
|
||||
|
||||
devkit8000_ads7846_init();
|
||||
|
||||
omap_mux_init_gpio(170, OMAP_PIN_INPUT);
|
||||
|
||||
gpio_request(170, "DVI_nPD");
|
||||
/* REVISIT leave DVI powered down until it's needed ... */
|
||||
gpio_direction_output(170, true);
|
||||
|
||||
usb_musb_init(&musb_board_data);
|
||||
usb_ehci_init(&ehci_pdata);
|
||||
devkit8000_flash_init();
|
||||
|
||||
/* Ensure SDRC pins are mux'd for self-refresh */
|
||||
omap_mux_init_signal("sdr_cke0", OMAP_PIN_OUTPUT);
|
||||
omap_mux_init_signal("sdr_cke1", OMAP_PIN_OUTPUT);
|
||||
omap_mux_init_signal("sdrc_cke0", OMAP_PIN_OUTPUT);
|
||||
omap_mux_init_signal("sdrc_cke1", OMAP_PIN_OUTPUT);
|
||||
}
|
||||
|
||||
static void __init devkit8000_map_io(void)
|
||||
|
|
|
@ -458,13 +458,13 @@ static struct omap_musb_board_data musb_board_data = {
|
|||
};
|
||||
|
||||
static const struct ehci_hcd_omap_platform_data ehci_pdata __initconst = {
|
||||
.port_mode[0] = EHCI_HCD_OMAP_MODE_UNKNOWN,
|
||||
.port_mode[1] = EHCI_HCD_OMAP_MODE_PHY,
|
||||
.port_mode[0] = EHCI_HCD_OMAP_MODE_PHY,
|
||||
.port_mode[1] = EHCI_HCD_OMAP_MODE_UNKNOWN,
|
||||
.port_mode[2] = EHCI_HCD_OMAP_MODE_UNKNOWN,
|
||||
|
||||
.phy_reset = true,
|
||||
.reset_gpio_port[0] = -EINVAL,
|
||||
.reset_gpio_port[1] = IGEP2_GPIO_USBH_NRESET,
|
||||
.reset_gpio_port[0] = IGEP2_GPIO_USBH_NRESET,
|
||||
.reset_gpio_port[1] = -EINVAL,
|
||||
.reset_gpio_port[2] = -EINVAL,
|
||||
};
|
||||
|
||||
|
|
|
@ -216,7 +216,7 @@ static void __init n8x0_onenand_init(void) {}
|
|||
*/
|
||||
#define N8X0_SLOT_SWITCH_GPIO 96
|
||||
#define N810_EMMC_VSD_GPIO 23
|
||||
#define NN810_EMMC_VIO_GPIO 9
|
||||
#define N810_EMMC_VIO_GPIO 9
|
||||
|
||||
static int n8x0_mmc_switch_slot(struct device *dev, int slot)
|
||||
{
|
||||
|
@ -304,10 +304,10 @@ static void n810_set_power_emmc(struct device *dev,
|
|||
if (power_on) {
|
||||
gpio_set_value(N810_EMMC_VSD_GPIO, 1);
|
||||
msleep(1);
|
||||
gpio_set_value(NN810_EMMC_VIO_GPIO, 1);
|
||||
gpio_set_value(N810_EMMC_VIO_GPIO, 1);
|
||||
msleep(1);
|
||||
} else {
|
||||
gpio_set_value(NN810_EMMC_VIO_GPIO, 0);
|
||||
gpio_set_value(N810_EMMC_VIO_GPIO, 0);
|
||||
msleep(50);
|
||||
gpio_set_value(N810_EMMC_VSD_GPIO, 0);
|
||||
msleep(50);
|
||||
|
@ -468,7 +468,7 @@ static void n8x0_mmc_cleanup(struct device *dev)
|
|||
|
||||
if (machine_is_nokia_n810()) {
|
||||
gpio_free(N810_EMMC_VSD_GPIO);
|
||||
gpio_free(NN810_EMMC_VIO_GPIO);
|
||||
gpio_free(N810_EMMC_VIO_GPIO);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -529,7 +529,7 @@ void __init n8x0_mmc_init(void)
|
|||
|
||||
err = gpio_request(N8X0_SLOT_SWITCH_GPIO, "MMC slot switch");
|
||||
if (err)
|
||||
return err;
|
||||
return;
|
||||
|
||||
gpio_direction_output(N8X0_SLOT_SWITCH_GPIO, 0);
|
||||
|
||||
|
@ -537,17 +537,17 @@ void __init n8x0_mmc_init(void)
|
|||
err = gpio_request(N810_EMMC_VSD_GPIO, "MMC slot 2 Vddf");
|
||||
if (err) {
|
||||
gpio_free(N8X0_SLOT_SWITCH_GPIO);
|
||||
return err;
|
||||
return;
|
||||
}
|
||||
gpio_direction_output(N810_EMMC_VSD_GPIO, 0);
|
||||
|
||||
err = gpio_request(NN810_EMMC_VIO_GPIO, "MMC slot 2 Vdd");
|
||||
err = gpio_request(N810_EMMC_VIO_GPIO, "MMC slot 2 Vdd");
|
||||
if (err) {
|
||||
gpio_free(N8X0_SLOT_SWITCH_GPIO);
|
||||
gpio_free(N810_EMMC_VSD_GPIO);
|
||||
return err;
|
||||
return;
|
||||
}
|
||||
gpio_direction_output(NN810_EMMC_VIO_GPIO, 0);
|
||||
gpio_direction_output(N810_EMMC_VIO_GPIO, 0);
|
||||
}
|
||||
|
||||
mmc_data[0] = &mmc1_data;
|
||||
|
|
|
@ -253,20 +253,20 @@ void __init sdp_flash_init(struct flash_partitions sdp_partition_info[])
|
|||
}
|
||||
|
||||
if (norcs > GPMC_CS_NUM)
|
||||
printk(KERN_INFO "OneNAND: Unable to find configuration "
|
||||
" in GPMC\n ");
|
||||
printk(KERN_INFO "NOR: Unable to find configuration "
|
||||
"in GPMC\n");
|
||||
else
|
||||
board_nor_init(sdp_partition_info[0], norcs);
|
||||
|
||||
if (onenandcs > GPMC_CS_NUM)
|
||||
printk(KERN_INFO "OneNAND: Unable to find configuration "
|
||||
" in GPMC\n ");
|
||||
"in GPMC\n");
|
||||
else
|
||||
board_onenand_init(sdp_partition_info[1], onenandcs);
|
||||
|
||||
if (nandcs > GPMC_CS_NUM)
|
||||
printk(KERN_INFO "NAND: Unable to find configuration "
|
||||
" in GPMC\n ");
|
||||
"in GPMC\n");
|
||||
else
|
||||
board_nand_init(sdp_partition_info[2], nandcs);
|
||||
}
|
||||
|
|
|
@ -96,7 +96,7 @@ static struct plat_serial8250_port serial_platform_data[] = {
|
|||
|
||||
static struct platform_device zoom_debugboard_serial_device = {
|
||||
.name = "serial8250",
|
||||
.id = 3,
|
||||
.id = PLAT8250_DEV_PLATFORM,
|
||||
.dev = {
|
||||
.platform_data = serial_platform_data,
|
||||
},
|
||||
|
|
|
@ -280,7 +280,6 @@ static void enable_board_wakeup_source(void)
|
|||
void __init zoom_peripherals_init(void)
|
||||
{
|
||||
omap_i2c_init();
|
||||
omap_serial_init();
|
||||
usb_musb_init(&musb_board_data);
|
||||
enable_board_wakeup_source();
|
||||
}
|
||||
|
|
|
@ -895,7 +895,7 @@ static struct clk dpll4_m4x2_ck = {
|
|||
.ops = &clkops_omap2_dflt_wait,
|
||||
.parent = &dpll4_m4_ck,
|
||||
.enable_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN),
|
||||
.enable_bit = OMAP3430_PWRDN_CAM_SHIFT,
|
||||
.enable_bit = OMAP3430_PWRDN_DSS1_SHIFT,
|
||||
.flags = INVERT_ENABLE,
|
||||
.clkdm_name = "dpll4_clkdm",
|
||||
.recalc = &omap3_clkoutx2_recalc,
|
||||
|
|
|
@ -2671,10 +2671,10 @@ static struct omap_clk omap44xx_clks[] = {
|
|||
CLK("omap-mcbsp.2", "ick", &dummy_ck, CK_443X),
|
||||
CLK("omap-mcbsp.3", "ick", &dummy_ck, CK_443X),
|
||||
CLK("omap-mcbsp.4", "ick", &dummy_ck, CK_443X),
|
||||
CLK("omap-mcspi.1", "ick", &dummy_ck, CK_443X),
|
||||
CLK("omap-mcspi.2", "ick", &dummy_ck, CK_443X),
|
||||
CLK("omap-mcspi.3", "ick", &dummy_ck, CK_443X),
|
||||
CLK("omap-mcspi.4", "ick", &dummy_ck, CK_443X),
|
||||
CLK("omap2_mcspi.1", "ick", &dummy_ck, CK_443X),
|
||||
CLK("omap2_mcspi.2", "ick", &dummy_ck, CK_443X),
|
||||
CLK("omap2_mcspi.3", "ick", &dummy_ck, CK_443X),
|
||||
CLK("omap2_mcspi.4", "ick", &dummy_ck, CK_443X),
|
||||
CLK(NULL, "uart1_ick", &dummy_ck, CK_443X),
|
||||
CLK(NULL, "uart2_ick", &dummy_ck, CK_443X),
|
||||
CLK(NULL, "uart3_ick", &dummy_ck, CK_443X),
|
||||
|
|
|
@ -240,7 +240,7 @@ static void _omap2_clkdm_set_hwsup(struct clockdomain *clkdm, int enable)
|
|||
bits = OMAP24XX_CLKSTCTRL_ENABLE_AUTO;
|
||||
else
|
||||
bits = OMAP24XX_CLKSTCTRL_DISABLE_AUTO;
|
||||
} else if (cpu_is_omap34xx() | cpu_is_omap44xx()) {
|
||||
} else if (cpu_is_omap34xx() || cpu_is_omap44xx()) {
|
||||
if (enable)
|
||||
bits = OMAP34XX_CLKSTCTRL_ENABLE_AUTO;
|
||||
else
|
||||
|
@ -812,7 +812,7 @@ int omap2_clkdm_sleep(struct clockdomain *clkdm)
|
|||
cm_set_mod_reg_bits(OMAP24XX_FORCESTATE,
|
||||
clkdm->pwrdm.ptr->prcm_offs, OMAP2_PM_PWSTCTRL);
|
||||
|
||||
} else if (cpu_is_omap34xx() | cpu_is_omap44xx()) {
|
||||
} else if (cpu_is_omap34xx() || cpu_is_omap44xx()) {
|
||||
|
||||
u32 bits = (OMAP34XX_CLKSTCTRL_FORCE_SLEEP <<
|
||||
__ffs(clkdm->clktrctrl_mask));
|
||||
|
@ -856,7 +856,7 @@ int omap2_clkdm_wakeup(struct clockdomain *clkdm)
|
|||
cm_clear_mod_reg_bits(OMAP24XX_FORCESTATE,
|
||||
clkdm->pwrdm.ptr->prcm_offs, OMAP2_PM_PWSTCTRL);
|
||||
|
||||
} else if (cpu_is_omap34xx() | cpu_is_omap44xx()) {
|
||||
} else if (cpu_is_omap34xx() || cpu_is_omap44xx()) {
|
||||
|
||||
u32 bits = (OMAP34XX_CLKSTCTRL_FORCE_WAKEUP <<
|
||||
__ffs(clkdm->clktrctrl_mask));
|
||||
|
|
|
@ -726,7 +726,7 @@ void __init omap2_init_mmc(struct omap_mmc_platform_data **mmc_data,
|
|||
if (!cpu_is_omap44xx())
|
||||
return;
|
||||
base = OMAP4_MMC5_BASE + OMAP4_MMC_REG_OFFSET;
|
||||
irq = OMAP44XX_IRQ_MMC4;
|
||||
irq = OMAP44XX_IRQ_MMC5;
|
||||
break;
|
||||
default:
|
||||
continue;
|
||||
|
|
|
@ -39,6 +39,9 @@ static int omap2_nand_gpmc_retime(void)
|
|||
struct gpmc_timings t;
|
||||
int err;
|
||||
|
||||
if (!gpmc_nand_data->gpmc_t)
|
||||
return 0;
|
||||
|
||||
memset(&t, 0, sizeof(t));
|
||||
t.sync_clk = gpmc_round_ns_to_ticks(gpmc_nand_data->gpmc_t->sync_clk);
|
||||
t.cs_on = gpmc_round_ns_to_ticks(gpmc_nand_data->gpmc_t->cs_on);
|
||||
|
|
|
@ -52,7 +52,7 @@ omap_irq_base: .word 0
|
|||
|
||||
mrc p15, 0, \tmp, c0, c0, 0 @ get processor revision
|
||||
and \tmp, \tmp, #0x000f0000 @ only check architecture
|
||||
cmp \tmp, #0x00060000 @ is v6?
|
||||
cmp \tmp, #0x00070000 @ is v6?
|
||||
beq 2400f @ found v6 so it's omap24xx
|
||||
mrc p15, 0, \tmp, c0, c0, 0 @ get processor revision
|
||||
and \tmp, \tmp, #0x000000f0 @ check cortex 8 or 9
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
ENTRY(omap_secondary_startup)
|
||||
hold: ldr r12,=0x103
|
||||
dsb
|
||||
smc @ read from AuxCoreBoot0
|
||||
smc #0 @ read from AuxCoreBoot0
|
||||
mov r0, r0, lsr #9
|
||||
mrc p15, 0, r4, c0, c0, 5
|
||||
and r4, r4, #0x0f
|
||||
|
@ -52,7 +52,7 @@ ENTRY(omap_modify_auxcoreboot0)
|
|||
stmfd sp!, {r1-r12, lr}
|
||||
ldr r12, =0x104
|
||||
dsb
|
||||
smc
|
||||
smc #0
|
||||
ldmfd sp!, {r1-r12, pc}
|
||||
END(omap_modify_auxcoreboot0)
|
||||
|
||||
|
@ -60,6 +60,6 @@ ENTRY(omap_auxcoreboot_addr)
|
|||
stmfd sp!, {r2-r12, lr}
|
||||
ldr r12, =0x105
|
||||
dsb
|
||||
smc
|
||||
smc #0
|
||||
ldmfd sp!, {r2-r12, pc}
|
||||
END(omap_auxcoreboot_addr)
|
||||
|
|
|
@ -27,6 +27,6 @@ ENTRY(omap_smc1)
|
|||
mov r12, r0
|
||||
mov r0, r1
|
||||
dsb
|
||||
smc
|
||||
smc #0
|
||||
ldmfd sp!, {r2-r12, pc}
|
||||
END(omap_smc1)
|
||||
|
|
|
@ -1511,6 +1511,9 @@ struct powerdomain *omap_hwmod_get_pwrdm(struct omap_hwmod *oh)
|
|||
c = oh->slaves[oh->_mpu_port_index]->_clk;
|
||||
}
|
||||
|
||||
if (!c->clkdm)
|
||||
return NULL;
|
||||
|
||||
return c->clkdm->pwrdm.ptr;
|
||||
|
||||
}
|
||||
|
|
|
@ -222,7 +222,7 @@ void pwrdm_init(struct powerdomain **pwrdm_list)
|
|||
{
|
||||
struct powerdomain **p = NULL;
|
||||
|
||||
if (cpu_is_omap24xx() | cpu_is_omap34xx()) {
|
||||
if (cpu_is_omap24xx() || cpu_is_omap34xx()) {
|
||||
pwrstctrl_reg_offs = OMAP2_PM_PWSTCTRL;
|
||||
pwrstst_reg_offs = OMAP2_PM_PWSTST;
|
||||
} else if (cpu_is_omap44xx()) {
|
||||
|
|
|
@ -123,7 +123,7 @@ struct omap3_prcm_regs prcm_context;
|
|||
u32 omap_prcm_get_reset_sources(void)
|
||||
{
|
||||
/* XXX This presumably needs modification for 34XX */
|
||||
if (cpu_is_omap24xx() | cpu_is_omap34xx())
|
||||
if (cpu_is_omap24xx() || cpu_is_omap34xx())
|
||||
return prm_read_mod_reg(WKUP_MOD, OMAP2_RM_RSTST) & 0x7f;
|
||||
if (cpu_is_omap44xx())
|
||||
return prm_read_mod_reg(WKUP_MOD, OMAP4_RM_RSTST) & 0x7f;
|
||||
|
@ -157,7 +157,7 @@ void omap_prcm_arch_reset(char mode, const char *cmd)
|
|||
else
|
||||
WARN_ON(1);
|
||||
|
||||
if (cpu_is_omap24xx() | cpu_is_omap34xx())
|
||||
if (cpu_is_omap24xx() || cpu_is_omap34xx())
|
||||
prm_set_mod_reg_bits(OMAP_RST_DPLL3, prcm_offs,
|
||||
OMAP2_RM_RSTCTRL);
|
||||
if (cpu_is_omap44xx())
|
||||
|
|
|
@ -115,7 +115,6 @@ static struct plat_serial8250_port serial_platform_data2[] = {
|
|||
}
|
||||
};
|
||||
|
||||
#if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_ARCH_OMAP4)
|
||||
static struct plat_serial8250_port serial_platform_data3[] = {
|
||||
{
|
||||
.irq = 70,
|
||||
|
@ -128,23 +127,12 @@ static struct plat_serial8250_port serial_platform_data3[] = {
|
|||
}
|
||||
};
|
||||
|
||||
static inline void omap2_set_globals_uart4(struct omap_globals *omap2_globals)
|
||||
{
|
||||
serial_platform_data3[0].mapbase = omap2_globals->uart4_phys;
|
||||
}
|
||||
#else
|
||||
static inline void omap2_set_globals_uart4(struct omap_globals *omap2_globals)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
void __init omap2_set_globals_uart(struct omap_globals *omap2_globals)
|
||||
{
|
||||
serial_platform_data0[0].mapbase = omap2_globals->uart1_phys;
|
||||
serial_platform_data1[0].mapbase = omap2_globals->uart2_phys;
|
||||
serial_platform_data2[0].mapbase = omap2_globals->uart3_phys;
|
||||
if (cpu_is_omap3630() || cpu_is_omap44xx())
|
||||
omap2_set_globals_uart4(omap2_globals);
|
||||
serial_platform_data3[0].mapbase = omap2_globals->uart4_phys;
|
||||
}
|
||||
|
||||
static inline unsigned int __serial_read_reg(struct uart_port *up,
|
||||
|
@ -550,7 +538,7 @@ static ssize_t sleep_timeout_store(struct device *dev,
|
|||
unsigned int value;
|
||||
|
||||
if (sscanf(buf, "%u", &value) != 1) {
|
||||
printk(KERN_ERR "sleep_timeout_store: Invalid value\n");
|
||||
dev_err(dev, "sleep_timeout_store: Invalid value\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
@ -664,27 +652,33 @@ void __init omap_serial_early_init(void)
|
|||
struct device *dev = &pdev->dev;
|
||||
struct plat_serial8250_port *p = dev->platform_data;
|
||||
|
||||
/* Don't map zero-based physical address */
|
||||
if (p->mapbase == 0) {
|
||||
dev_warn(dev, "no physical address for uart#%d,"
|
||||
" so skipping early_init...\n", i);
|
||||
continue;
|
||||
}
|
||||
/*
|
||||
* Module 4KB + L4 interconnect 4KB
|
||||
* Static mapping, never released
|
||||
*/
|
||||
p->membase = ioremap(p->mapbase, SZ_8K);
|
||||
if (!p->membase) {
|
||||
printk(KERN_ERR "ioremap failed for uart%i\n", i + 1);
|
||||
dev_err(dev, "ioremap failed for uart%i\n", i + 1);
|
||||
continue;
|
||||
}
|
||||
|
||||
sprintf(name, "uart%d_ick", i + 1);
|
||||
uart->ick = clk_get(NULL, name);
|
||||
if (IS_ERR(uart->ick)) {
|
||||
printk(KERN_ERR "Could not get uart%d_ick\n", i + 1);
|
||||
dev_err(dev, "Could not get uart%d_ick\n", i + 1);
|
||||
uart->ick = NULL;
|
||||
}
|
||||
|
||||
sprintf(name, "uart%d_fck", i+1);
|
||||
uart->fck = clk_get(NULL, name);
|
||||
if (IS_ERR(uart->fck)) {
|
||||
printk(KERN_ERR "Could not get uart%d_fck\n", i + 1);
|
||||
dev_err(dev, "Could not get uart%d_fck\n", i + 1);
|
||||
uart->fck = NULL;
|
||||
}
|
||||
|
||||
|
@ -727,6 +721,13 @@ void __init omap_serial_init_port(int port)
|
|||
pdev = &uart->pdev;
|
||||
dev = &pdev->dev;
|
||||
|
||||
/* Don't proceed if there's no clocks available */
|
||||
if (unlikely(!uart->ick || !uart->fck)) {
|
||||
WARN(1, "%s: can't init uart%d, no clocks available\n",
|
||||
kobject_name(&dev->kobj), port);
|
||||
return;
|
||||
}
|
||||
|
||||
omap_uart_enable_clocks(uart);
|
||||
|
||||
omap_uart_reset(uart);
|
||||
|
|
|
@ -41,14 +41,7 @@ static void v6_copy_user_highpage_nonaliasing(struct page *to,
|
|||
kfrom = kmap_atomic(from, KM_USER0);
|
||||
kto = kmap_atomic(to, KM_USER1);
|
||||
copy_page(kto, kfrom);
|
||||
#ifdef CONFIG_HIGHMEM
|
||||
/*
|
||||
* kmap_atomic() doesn't set the page virtual address, and
|
||||
* kunmap_atomic() takes care of cache flushing already.
|
||||
*/
|
||||
if (page_address(to) != NULL)
|
||||
#endif
|
||||
__cpuc_flush_dcache_area(kto, PAGE_SIZE);
|
||||
__cpuc_flush_dcache_area(kto, PAGE_SIZE);
|
||||
kunmap_atomic(kto, KM_USER1);
|
||||
kunmap_atomic(kfrom, KM_USER0);
|
||||
}
|
||||
|
|
|
@ -464,6 +464,11 @@ static void dma_cache_maint_page(struct page *page, unsigned long offset,
|
|||
vaddr += offset;
|
||||
op(vaddr, len, dir);
|
||||
kunmap_high(page);
|
||||
} else if (cache_is_vipt()) {
|
||||
pte_t saved_pte;
|
||||
vaddr = kmap_high_l1_vipt(page, &saved_pte);
|
||||
op(vaddr + offset, len, dir);
|
||||
kunmap_high_l1_vipt(page, saved_pte);
|
||||
}
|
||||
} else {
|
||||
vaddr = page_address(page) + offset;
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
|
||||
#include <asm/cacheflush.h>
|
||||
#include <asm/cachetype.h>
|
||||
#include <asm/highmem.h>
|
||||
#include <asm/smp_plat.h>
|
||||
#include <asm/system.h>
|
||||
#include <asm/tlbflush.h>
|
||||
|
@ -152,21 +153,25 @@ void copy_to_user_page(struct vm_area_struct *vma, struct page *page,
|
|||
|
||||
void __flush_dcache_page(struct address_space *mapping, struct page *page)
|
||||
{
|
||||
void *addr = page_address(page);
|
||||
|
||||
/*
|
||||
* Writeback any data associated with the kernel mapping of this
|
||||
* page. This ensures that data in the physical page is mutually
|
||||
* coherent with the kernels mapping.
|
||||
*/
|
||||
#ifdef CONFIG_HIGHMEM
|
||||
/*
|
||||
* kmap_atomic() doesn't set the page virtual address, and
|
||||
* kunmap_atomic() takes care of cache flushing already.
|
||||
*/
|
||||
if (addr)
|
||||
#endif
|
||||
__cpuc_flush_dcache_area(addr, PAGE_SIZE);
|
||||
if (!PageHighMem(page)) {
|
||||
__cpuc_flush_dcache_area(page_address(page), PAGE_SIZE);
|
||||
} else {
|
||||
void *addr = kmap_high_get(page);
|
||||
if (addr) {
|
||||
__cpuc_flush_dcache_area(addr, PAGE_SIZE);
|
||||
kunmap_high(page);
|
||||
} else if (cache_is_vipt()) {
|
||||
pte_t saved_pte;
|
||||
addr = kmap_high_l1_vipt(page, &saved_pte);
|
||||
__cpuc_flush_dcache_area(addr, PAGE_SIZE);
|
||||
kunmap_high_l1_vipt(page, saved_pte);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* If this is a page cache page, and we have an aliasing VIPT cache,
|
||||
|
|
|
@ -79,7 +79,8 @@ void kunmap_atomic(void *kvaddr, enum km_type type)
|
|||
unsigned int idx = type + KM_TYPE_NR * smp_processor_id();
|
||||
|
||||
if (kvaddr >= (void *)FIXADDR_START) {
|
||||
__cpuc_flush_dcache_area((void *)vaddr, PAGE_SIZE);
|
||||
if (cache_is_vivt())
|
||||
__cpuc_flush_dcache_area((void *)vaddr, PAGE_SIZE);
|
||||
#ifdef CONFIG_DEBUG_HIGHMEM
|
||||
BUG_ON(vaddr != __fix_to_virt(FIX_KMAP_BEGIN + idx));
|
||||
set_pte_ext(TOP_PTE(vaddr), __pte(0), 0);
|
||||
|
@ -124,3 +125,87 @@ struct page *kmap_atomic_to_page(const void *ptr)
|
|||
pte = TOP_PTE(vaddr);
|
||||
return pte_page(*pte);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_CPU_CACHE_VIPT
|
||||
|
||||
#include <linux/percpu.h>
|
||||
|
||||
/*
|
||||
* The VIVT cache of a highmem page is always flushed before the page
|
||||
* is unmapped. Hence unmapped highmem pages need no cache maintenance
|
||||
* in that case.
|
||||
*
|
||||
* However unmapped pages may still be cached with a VIPT cache, and
|
||||
* it is not possible to perform cache maintenance on them using physical
|
||||
* addresses unfortunately. So we have no choice but to set up a temporary
|
||||
* virtual mapping for that purpose.
|
||||
*
|
||||
* Yet this VIPT cache maintenance may be triggered from DMA support
|
||||
* functions which are possibly called from interrupt context. As we don't
|
||||
* want to keep interrupt disabled all the time when such maintenance is
|
||||
* taking place, we therefore allow for some reentrancy by preserving and
|
||||
* restoring the previous fixmap entry before the interrupted context is
|
||||
* resumed. If the reentrancy depth is 0 then there is no need to restore
|
||||
* the previous fixmap, and leaving the current one in place allow it to
|
||||
* be reused the next time without a TLB flush (common with DMA).
|
||||
*/
|
||||
|
||||
static DEFINE_PER_CPU(int, kmap_high_l1_vipt_depth);
|
||||
|
||||
void *kmap_high_l1_vipt(struct page *page, pte_t *saved_pte)
|
||||
{
|
||||
unsigned int idx, cpu = smp_processor_id();
|
||||
int *depth = &per_cpu(kmap_high_l1_vipt_depth, cpu);
|
||||
unsigned long vaddr, flags;
|
||||
pte_t pte, *ptep;
|
||||
|
||||
idx = KM_L1_CACHE + KM_TYPE_NR * cpu;
|
||||
vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
|
||||
ptep = TOP_PTE(vaddr);
|
||||
pte = mk_pte(page, kmap_prot);
|
||||
|
||||
if (!in_interrupt())
|
||||
preempt_disable();
|
||||
|
||||
raw_local_irq_save(flags);
|
||||
(*depth)++;
|
||||
if (pte_val(*ptep) == pte_val(pte)) {
|
||||
*saved_pte = pte;
|
||||
} else {
|
||||
*saved_pte = *ptep;
|
||||
set_pte_ext(ptep, pte, 0);
|
||||
local_flush_tlb_kernel_page(vaddr);
|
||||
}
|
||||
raw_local_irq_restore(flags);
|
||||
|
||||
return (void *)vaddr;
|
||||
}
|
||||
|
||||
void kunmap_high_l1_vipt(struct page *page, pte_t saved_pte)
|
||||
{
|
||||
unsigned int idx, cpu = smp_processor_id();
|
||||
int *depth = &per_cpu(kmap_high_l1_vipt_depth, cpu);
|
||||
unsigned long vaddr, flags;
|
||||
pte_t pte, *ptep;
|
||||
|
||||
idx = KM_L1_CACHE + KM_TYPE_NR * cpu;
|
||||
vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
|
||||
ptep = TOP_PTE(vaddr);
|
||||
pte = mk_pte(page, kmap_prot);
|
||||
|
||||
BUG_ON(pte_val(*ptep) != pte_val(pte));
|
||||
BUG_ON(*depth <= 0);
|
||||
|
||||
raw_local_irq_save(flags);
|
||||
(*depth)--;
|
||||
if (*depth != 0 && pte_val(pte) != pte_val(saved_pte)) {
|
||||
set_pte_ext(ptep, saved_pte, 0);
|
||||
local_flush_tlb_kernel_page(vaddr);
|
||||
}
|
||||
raw_local_irq_restore(flags);
|
||||
|
||||
if (!in_interrupt())
|
||||
preempt_enable();
|
||||
}
|
||||
|
||||
#endif /* CONFIG_CPU_CACHE_VIPT */
|
||||
|
|
|
@ -1054,10 +1054,12 @@ void setup_mm_for_reboot(char mode)
|
|||
pgd_t *pgd;
|
||||
int i;
|
||||
|
||||
if (current->mm && current->mm->pgd)
|
||||
pgd = current->mm->pgd;
|
||||
else
|
||||
pgd = init_mm.pgd;
|
||||
/*
|
||||
* We need to access to user-mode page tables here. For kernel threads
|
||||
* we don't have any user-mode mappings so we use the context that we
|
||||
* "borrowed".
|
||||
*/
|
||||
pgd = current->active_mm->pgd;
|
||||
|
||||
base_pmdval = PMD_SECT_AP_WRITE | PMD_SECT_AP_READ | PMD_TYPE_SECT;
|
||||
if (cpu_architecture() <= CPU_ARCH_ARMv5TEJ && !cpu_is_xscale())
|
||||
|
|
|
@ -44,9 +44,6 @@
|
|||
|
||||
#define NO_LENGTH_CHECK 0xffffffff
|
||||
|
||||
unsigned char omap_bootloader_tag[512];
|
||||
int omap_bootloader_tag_len;
|
||||
|
||||
struct omap_board_config_kernel *omap_board_config;
|
||||
int omap_board_config_size;
|
||||
|
||||
|
@ -100,10 +97,17 @@ EXPORT_SYMBOL(omap_get_var_config);
|
|||
|
||||
#include <linux/clocksource.h>
|
||||
|
||||
/*
|
||||
* offset_32k holds the init time counter value. It is then subtracted
|
||||
* from every counter read to achieve a counter that counts time from the
|
||||
* kernel boot (needed for sched_clock()).
|
||||
*/
|
||||
static u32 offset_32k __read_mostly;
|
||||
|
||||
#ifdef CONFIG_ARCH_OMAP16XX
|
||||
static cycle_t omap16xx_32k_read(struct clocksource *cs)
|
||||
{
|
||||
return omap_readl(OMAP16XX_TIMER_32K_SYNCHRONIZED);
|
||||
return omap_readl(OMAP16XX_TIMER_32K_SYNCHRONIZED) - offset_32k;
|
||||
}
|
||||
#else
|
||||
#define omap16xx_32k_read NULL
|
||||
|
@ -112,7 +116,7 @@ static cycle_t omap16xx_32k_read(struct clocksource *cs)
|
|||
#ifdef CONFIG_ARCH_OMAP2420
|
||||
static cycle_t omap2420_32k_read(struct clocksource *cs)
|
||||
{
|
||||
return omap_readl(OMAP2420_32KSYNCT_BASE + 0x10);
|
||||
return omap_readl(OMAP2420_32KSYNCT_BASE + 0x10) - offset_32k;
|
||||
}
|
||||
#else
|
||||
#define omap2420_32k_read NULL
|
||||
|
@ -121,7 +125,7 @@ static cycle_t omap2420_32k_read(struct clocksource *cs)
|
|||
#ifdef CONFIG_ARCH_OMAP2430
|
||||
static cycle_t omap2430_32k_read(struct clocksource *cs)
|
||||
{
|
||||
return omap_readl(OMAP2430_32KSYNCT_BASE + 0x10);
|
||||
return omap_readl(OMAP2430_32KSYNCT_BASE + 0x10) - offset_32k;
|
||||
}
|
||||
#else
|
||||
#define omap2430_32k_read NULL
|
||||
|
@ -130,7 +134,7 @@ static cycle_t omap2430_32k_read(struct clocksource *cs)
|
|||
#ifdef CONFIG_ARCH_OMAP3
|
||||
static cycle_t omap34xx_32k_read(struct clocksource *cs)
|
||||
{
|
||||
return omap_readl(OMAP3430_32KSYNCT_BASE + 0x10);
|
||||
return omap_readl(OMAP3430_32KSYNCT_BASE + 0x10) - offset_32k;
|
||||
}
|
||||
#else
|
||||
#define omap34xx_32k_read NULL
|
||||
|
@ -139,7 +143,7 @@ static cycle_t omap34xx_32k_read(struct clocksource *cs)
|
|||
#ifdef CONFIG_ARCH_OMAP4
|
||||
static cycle_t omap44xx_32k_read(struct clocksource *cs)
|
||||
{
|
||||
return omap_readl(OMAP4430_32KSYNCT_BASE + 0x10);
|
||||
return omap_readl(OMAP4430_32KSYNCT_BASE + 0x10) - offset_32k;
|
||||
}
|
||||
#else
|
||||
#define omap44xx_32k_read NULL
|
||||
|
@ -227,6 +231,8 @@ static int __init omap_init_clocksource_32k(void)
|
|||
clocksource_32k.mult = clocksource_hz2mult(32768,
|
||||
clocksource_32k.shift);
|
||||
|
||||
offset_32k = clocksource_32k.read(&clocksource_32k);
|
||||
|
||||
if (clocksource_register(&clocksource_32k))
|
||||
printk(err, clocksource_32k.name);
|
||||
}
|
||||
|
|
|
@ -937,6 +937,15 @@ void omap_start_dma(int lch)
|
|||
{
|
||||
u32 l;
|
||||
|
||||
/*
|
||||
* The CPC/CDAC register needs to be initialized to zero
|
||||
* before starting dma transfer.
|
||||
*/
|
||||
if (cpu_is_omap15xx())
|
||||
dma_write(0, CPC(lch));
|
||||
else
|
||||
dma_write(0, CDAC(lch));
|
||||
|
||||
if (!omap_dma_in_1510_mode() && dma_chan[lch].next_lch != -1) {
|
||||
int next_lch, cur_lch;
|
||||
char dma_chan_link_map[OMAP_DMA4_LOGICAL_DMA_CH_COUNT];
|
||||
|
|
|
@ -798,7 +798,7 @@ static int _set_gpio_triggering(struct gpio_bank *bank, int gpio, int trigger)
|
|||
case METHOD_MPUIO:
|
||||
reg += OMAP_MPUIO_GPIO_INT_EDGE;
|
||||
l = __raw_readl(reg);
|
||||
if (trigger & IRQ_TYPE_EDGE_BOTH)
|
||||
if ((trigger & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_EDGE_BOTH)
|
||||
bank->toggle_mask |= 1 << gpio;
|
||||
if (trigger & IRQ_TYPE_EDGE_RISING)
|
||||
l |= 1 << gpio;
|
||||
|
@ -812,7 +812,7 @@ static int _set_gpio_triggering(struct gpio_bank *bank, int gpio, int trigger)
|
|||
case METHOD_GPIO_1510:
|
||||
reg += OMAP1510_GPIO_INT_CONTROL;
|
||||
l = __raw_readl(reg);
|
||||
if (trigger & IRQ_TYPE_EDGE_BOTH)
|
||||
if ((trigger & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_EDGE_BOTH)
|
||||
bank->toggle_mask |= 1 << gpio;
|
||||
if (trigger & IRQ_TYPE_EDGE_RISING)
|
||||
l |= 1 << gpio;
|
||||
|
@ -846,7 +846,7 @@ static int _set_gpio_triggering(struct gpio_bank *bank, int gpio, int trigger)
|
|||
case METHOD_GPIO_7XX:
|
||||
reg += OMAP7XX_GPIO_INT_CONTROL;
|
||||
l = __raw_readl(reg);
|
||||
if (trigger & IRQ_TYPE_EDGE_BOTH)
|
||||
if ((trigger & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_EDGE_BOTH)
|
||||
bank->toggle_mask |= 1 << gpio;
|
||||
if (trigger & IRQ_TYPE_EDGE_RISING)
|
||||
l |= 1 << gpio;
|
||||
|
|
|
@ -345,8 +345,6 @@
|
|||
#define INT_34XX_MMC3_IRQ 94
|
||||
#define INT_34XX_GPT12_IRQ 95
|
||||
|
||||
#define INT_34XX_BENCH_MPU_EMUL 3
|
||||
|
||||
#define INT_35XX_HECC0_IRQ 24
|
||||
#define INT_35XX_HECC1_IRQ 28
|
||||
#define INT_35XX_EMAC_C0_RXTHRESH_IRQ 67
|
||||
|
|
|
@ -59,7 +59,7 @@
|
|||
#define OMAP44XX_MCBSP1_BASE 0x49022000
|
||||
#define OMAP44XX_MCBSP2_BASE 0x49024000
|
||||
#define OMAP44XX_MCBSP3_BASE 0x49026000
|
||||
#define OMAP44XX_MCBSP4_BASE 0x48074000
|
||||
#define OMAP44XX_MCBSP4_BASE 0x48096000
|
||||
|
||||
#if defined(CONFIG_ARCH_OMAP15XX) || defined(CONFIG_ARCH_OMAP16XX) || defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850)
|
||||
|
||||
|
|
|
@ -29,4 +29,11 @@ struct omap_nand_platform_data {
|
|||
/* size (4 KiB) for IO mapping */
|
||||
#define NAND_IO_SIZE SZ_4K
|
||||
|
||||
#if defined(CONFIG_MTD_NAND_OMAP2) || defined(CONFIG_MTD_NAND_OMAP2_MODULE)
|
||||
extern int gpmc_nand_init(struct omap_nand_platform_data *d);
|
||||
#else
|
||||
static inline int gpmc_nand_init(struct omap_nand_platform_data *d)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
#define OMAP4430_PRM_BASE 0x4a306000
|
||||
#define OMAP44XX_GPMC_BASE 0x50000000
|
||||
#define OMAP443X_SCM_BASE 0x4a002000
|
||||
#define OMAP443X_CTRL_BASE OMAP443X_SCM_BASE
|
||||
#define OMAP443X_CTRL_BASE 0x4a100000
|
||||
#define OMAP44XX_IC_BASE 0x48200000
|
||||
#define OMAP44XX_IVA_INTC_BASE 0x40000000
|
||||
#define IRQ_SIR_IRQ 0x0040
|
||||
|
|
|
@ -294,8 +294,8 @@ struct omap_hwmod_class_sysconfig {
|
|||
u16 rev_offs;
|
||||
u16 sysc_offs;
|
||||
u16 syss_offs;
|
||||
u16 sysc_flags;
|
||||
u8 idlemodes;
|
||||
u8 sysc_flags;
|
||||
u8 clockact;
|
||||
struct omap_hwmod_sysc_fields *sysc_fields;
|
||||
};
|
||||
|
|
|
@ -428,26 +428,6 @@ static void vfp_pm_init(void)
|
|||
static inline void vfp_pm_init(void) { }
|
||||
#endif /* CONFIG_PM */
|
||||
|
||||
/*
|
||||
* Synchronise the hardware VFP state of a thread other than current with the
|
||||
* saved one. This function is used by the ptrace mechanism.
|
||||
*/
|
||||
#ifdef CONFIG_SMP
|
||||
void vfp_sync_hwstate(struct thread_info *thread)
|
||||
{
|
||||
}
|
||||
|
||||
void vfp_flush_hwstate(struct thread_info *thread)
|
||||
{
|
||||
/*
|
||||
* On SMP systems, the VFP state is automatically saved at every
|
||||
* context switch. We mark the thread VFP state as belonging to a
|
||||
* non-existent CPU so that the saved one will be reloaded when
|
||||
* needed.
|
||||
*/
|
||||
thread->vfpstate.hard.cpu = NR_CPUS;
|
||||
}
|
||||
#else
|
||||
void vfp_sync_hwstate(struct thread_info *thread)
|
||||
{
|
||||
unsigned int cpu = get_cpu();
|
||||
|
@ -490,9 +470,18 @@ void vfp_flush_hwstate(struct thread_info *thread)
|
|||
last_VFP_context[cpu] = NULL;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
/*
|
||||
* For SMP we still have to take care of the case where the thread
|
||||
* migrates to another CPU and then back to the original CPU on which
|
||||
* the last VFP user is still the same thread. Mark the thread VFP
|
||||
* state as belonging to a non-existent CPU so that the saved one will
|
||||
* be reloaded in the above case.
|
||||
*/
|
||||
thread->vfpstate.hard.cpu = NR_CPUS;
|
||||
#endif
|
||||
put_cpu();
|
||||
}
|
||||
#endif
|
||||
|
||||
#include <linux/smp.h>
|
||||
|
||||
|
|
|
@ -28,7 +28,7 @@ static struct pt_regs *get_user_regs(struct task_struct *tsk)
|
|||
THREAD_SIZE - sizeof(struct pt_regs));
|
||||
}
|
||||
|
||||
static void user_enable_single_step(struct task_struct *tsk)
|
||||
void user_enable_single_step(struct task_struct *tsk)
|
||||
{
|
||||
pr_debug("user_enable_single_step: pid=%u, PC=0x%08lx, SR=0x%08lx\n",
|
||||
tsk->pid, task_pt_regs(tsk)->pc, task_pt_regs(tsk)->sr);
|
||||
|
|
|
@ -1802,7 +1802,8 @@ static int kvm_ia64_sync_dirty_log(struct kvm *kvm,
|
|||
{
|
||||
struct kvm_memory_slot *memslot;
|
||||
int r, i;
|
||||
long n, base;
|
||||
long base;
|
||||
unsigned long n;
|
||||
unsigned long *dirty_bitmap = (unsigned long *)(kvm->arch.vm_base +
|
||||
offsetof(struct kvm_vm_data, kvm_mem_dirty_log));
|
||||
|
||||
|
@ -1815,7 +1816,7 @@ static int kvm_ia64_sync_dirty_log(struct kvm *kvm,
|
|||
if (!memslot->dirty_bitmap)
|
||||
goto out;
|
||||
|
||||
n = ALIGN(memslot->npages, BITS_PER_LONG) / 8;
|
||||
n = kvm_dirty_bitmap_bytes(memslot);
|
||||
base = memslot->base_gfn / BITS_PER_LONG;
|
||||
|
||||
for (i = 0; i < n/sizeof(long); ++i) {
|
||||
|
@ -1831,7 +1832,7 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
|
|||
struct kvm_dirty_log *log)
|
||||
{
|
||||
int r;
|
||||
int n;
|
||||
unsigned long n;
|
||||
struct kvm_memory_slot *memslot;
|
||||
int is_dirty = 0;
|
||||
|
||||
|
@ -1850,7 +1851,7 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
|
|||
if (is_dirty) {
|
||||
kvm_flush_remote_tlbs(kvm);
|
||||
memslot = &kvm->memslots->memslots[log->slot];
|
||||
n = ALIGN(memslot->npages, BITS_PER_LONG) / 8;
|
||||
n = kvm_dirty_bitmap_bytes(memslot);
|
||||
memset(memslot->dirty_bitmap, 0, n);
|
||||
}
|
||||
r = 0;
|
||||
|
|
|
@ -148,14 +148,18 @@ static inline int atomic_xchg(atomic_t *v, int new)
|
|||
static inline int atomic_sub_and_test(int i, atomic_t *v)
|
||||
{
|
||||
char c;
|
||||
__asm__ __volatile__("subl %2,%1; seq %0" : "=d" (c), "+m" (*v): "g" (i));
|
||||
__asm__ __volatile__("subl %2,%1; seq %0"
|
||||
: "=d" (c), "+m" (*v)
|
||||
: "id" (i));
|
||||
return c != 0;
|
||||
}
|
||||
|
||||
static inline int atomic_add_negative(int i, atomic_t *v)
|
||||
{
|
||||
char c;
|
||||
__asm__ __volatile__("addl %2,%1; smi %0" : "=d" (c), "+m" (*v): "g" (i));
|
||||
__asm__ __volatile__("addl %2,%1; smi %0"
|
||||
: "=d" (c), "+m" (*v)
|
||||
: "id" (i));
|
||||
return c != 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -212,5 +212,10 @@ struct mcf_platform_uart {
|
|||
#define MCFUART_URF_RXS 0xc0 /* Receiver status */
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_M5272)
|
||||
#define MCFUART_TXFIFOSIZE 25
|
||||
#else
|
||||
#define MCFUART_TXFIFOSIZE 1
|
||||
#endif
|
||||
/****************************************************************************/
|
||||
#endif /* mcfuart_h */
|
||||
|
|
|
@ -17,13 +17,11 @@ struct sigcontext {
|
|||
#ifndef __uClinux__
|
||||
# ifdef __mcoldfire__
|
||||
unsigned long sc_fpregs[2][2]; /* room for two fp registers */
|
||||
unsigned long sc_fpcntl[3];
|
||||
unsigned char sc_fpstate[16+6*8];
|
||||
# else
|
||||
unsigned long sc_fpregs[2*3]; /* room for two fp registers */
|
||||
# endif
|
||||
unsigned long sc_fpcntl[3];
|
||||
unsigned char sc_fpstate[216];
|
||||
# endif
|
||||
#endif
|
||||
};
|
||||
|
||||
|
|
|
@ -94,7 +94,7 @@ cflags-$(CONFIG_M520x) := $(call cc-option,-mcpu=5208,-m5200)
|
|||
cflags-$(CONFIG_M523x) := $(call cc-option,-mcpu=523x,-m5307)
|
||||
cflags-$(CONFIG_M5249) := $(call cc-option,-mcpu=5249,-m5200)
|
||||
cflags-$(CONFIG_M5271) := $(call cc-option,-mcpu=5271,-m5307)
|
||||
cflags-$(CONFIG_M5272) := $(call cc-option,-mcpu=5271,-m5200)
|
||||
cflags-$(CONFIG_M5272) := $(call cc-option,-mcpu=5272,-m5307)
|
||||
cflags-$(CONFIG_M5275) := $(call cc-option,-mcpu=5275,-m5307)
|
||||
cflags-$(CONFIG_M528x) := $(call cc-option,-m528x,-m5307)
|
||||
cflags-$(CONFIG_M5307) := $(call cc-option,-m5307,-m5200)
|
||||
|
|
|
@ -145,6 +145,6 @@ ENTRY(ret_from_user_signal)
|
|||
trap #0
|
||||
|
||||
ENTRY(ret_from_user_rt_signal)
|
||||
move #__NR_rt_sigreturn,%d0
|
||||
movel #__NR_rt_sigreturn,%d0
|
||||
trap #0
|
||||
|
||||
|
|
|
@ -107,7 +107,6 @@ void init_IRQ(void)
|
|||
_ramvec[vba+CPMVEC_PIO_PC7] = inthandler; /* pio - pc7 */
|
||||
_ramvec[vba+CPMVEC_PIO_PC6] = inthandler; /* pio - pc6 */
|
||||
_ramvec[vba+CPMVEC_TIMER3] = inthandler; /* timer 3 */
|
||||
_ramvec[vba+CPMVEC_RISCTIMER] = inthandler; /* reserved */
|
||||
_ramvec[vba+CPMVEC_PIO_PC5] = inthandler; /* pio - pc5 */
|
||||
_ramvec[vba+CPMVEC_PIO_PC4] = inthandler; /* pio - pc4 */
|
||||
_ramvec[vba+CPMVEC_RESERVED2] = inthandler; /* reserved */
|
||||
|
|
|
@ -1004,7 +1004,8 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
|
|||
struct kvm_vcpu *vcpu;
|
||||
ulong ga, ga_end;
|
||||
int is_dirty = 0;
|
||||
int r, n;
|
||||
int r;
|
||||
unsigned long n;
|
||||
|
||||
mutex_lock(&kvm->slots_lock);
|
||||
|
||||
|
@ -1022,7 +1023,7 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
|
|||
kvm_for_each_vcpu(n, vcpu, kvm)
|
||||
kvmppc_mmu_pte_pflush(vcpu, ga, ga_end);
|
||||
|
||||
n = ALIGN(memslot->npages, BITS_PER_LONG) / 8;
|
||||
n = kvm_dirty_bitmap_bytes(memslot);
|
||||
memset(memslot->dirty_bitmap, 0, n);
|
||||
}
|
||||
|
||||
|
|
|
@ -29,6 +29,7 @@ struct vdso_data {
|
|||
__u32 tz_minuteswest; /* Minutes west of Greenwich 0x30 */
|
||||
__u32 tz_dsttime; /* Type of dst correction 0x34 */
|
||||
__u32 ectg_available;
|
||||
__u32 ntp_mult; /* NTP adjusted multiplier 0x3C */
|
||||
};
|
||||
|
||||
struct vdso_per_cpu_data {
|
||||
|
|
|
@ -61,6 +61,7 @@ int main(void)
|
|||
DEFINE(__VDSO_WTOM_NSEC, offsetof(struct vdso_data, wtom_clock_nsec));
|
||||
DEFINE(__VDSO_TIMEZONE, offsetof(struct vdso_data, tz_minuteswest));
|
||||
DEFINE(__VDSO_ECTG_OK, offsetof(struct vdso_data, ectg_available));
|
||||
DEFINE(__VDSO_NTP_MULT, offsetof(struct vdso_data, ntp_mult));
|
||||
DEFINE(__VDSO_ECTG_BASE, offsetof(struct vdso_per_cpu_data, ectg_timer_base));
|
||||
DEFINE(__VDSO_ECTG_USER, offsetof(struct vdso_per_cpu_data, ectg_user_time));
|
||||
/* constants used by the vdso */
|
||||
|
|
|
@ -256,6 +256,9 @@ restore_registers:
|
|||
lghi %r2,0
|
||||
brasl %r14,arch_set_page_states
|
||||
|
||||
/* Reinitialize the channel subsystem */
|
||||
brasl %r14,channel_subsystem_reinit
|
||||
|
||||
/* Return 0 */
|
||||
lmg %r6,%r15,STACK_FRAME_OVERHEAD + __SF_GPRS(%r15)
|
||||
lghi %r2,0
|
||||
|
|
|
@ -221,6 +221,7 @@ void update_vsyscall(struct timespec *wall_time, struct clocksource *clock,
|
|||
vdso_data->xtime_clock_nsec = wall_time->tv_nsec;
|
||||
vdso_data->wtom_clock_sec = wall_to_monotonic.tv_sec;
|
||||
vdso_data->wtom_clock_nsec = wall_to_monotonic.tv_nsec;
|
||||
vdso_data->ntp_mult = mult;
|
||||
smp_wmb();
|
||||
++vdso_data->tb_update_count;
|
||||
}
|
||||
|
|
|
@ -38,13 +38,13 @@ __kernel_clock_gettime:
|
|||
sl %r1,__VDSO_XTIME_STAMP+4(%r5)
|
||||
brc 3,2f
|
||||
ahi %r0,-1
|
||||
2: mhi %r0,1000 /* cyc2ns(clock,cycle_delta) */
|
||||
2: ms %r0,__VDSO_NTP_MULT(%r5) /* cyc2ns(clock,cycle_delta) */
|
||||
lr %r2,%r0
|
||||
lhi %r0,1000
|
||||
l %r0,__VDSO_NTP_MULT(%r5)
|
||||
ltr %r1,%r1
|
||||
mr %r0,%r0
|
||||
jnm 3f
|
||||
ahi %r0,1000
|
||||
a %r0,__VDSO_NTP_MULT(%r5)
|
||||
3: alr %r0,%r2
|
||||
srdl %r0,12
|
||||
al %r0,__VDSO_XTIME_NSEC(%r5) /* + xtime */
|
||||
|
@ -86,13 +86,13 @@ __kernel_clock_gettime:
|
|||
sl %r1,__VDSO_XTIME_STAMP+4(%r5)
|
||||
brc 3,12f
|
||||
ahi %r0,-1
|
||||
12: mhi %r0,1000 /* cyc2ns(clock,cycle_delta) */
|
||||
12: ms %r0,__VDSO_NTP_MULT(%r5) /* cyc2ns(clock,cycle_delta) */
|
||||
lr %r2,%r0
|
||||
lhi %r0,1000
|
||||
l %r0,__VDSO_NTP_MULT(%r5)
|
||||
ltr %r1,%r1
|
||||
mr %r0,%r0
|
||||
jnm 13f
|
||||
ahi %r0,1000
|
||||
a %r0,__VDSO_NTP_MULT(%r5)
|
||||
13: alr %r0,%r2
|
||||
srdl %r0,12
|
||||
al %r0,__VDSO_XTIME_NSEC(%r5) /* + xtime */
|
||||
|
|
|
@ -35,13 +35,13 @@ __kernel_gettimeofday:
|
|||
sl %r1,__VDSO_XTIME_STAMP+4(%r5)
|
||||
brc 3,3f
|
||||
ahi %r0,-1
|
||||
3: mhi %r0,1000 /* cyc2ns(clock,cycle_delta) */
|
||||
3: ms %r0,__VDSO_NTP_MULT(%r5) /* cyc2ns(clock,cycle_delta) */
|
||||
st %r0,24(%r15)
|
||||
lhi %r0,1000
|
||||
l %r0,__VDSO_NTP_MULT(%r5)
|
||||
ltr %r1,%r1
|
||||
mr %r0,%r0
|
||||
jnm 4f
|
||||
ahi %r0,1000
|
||||
a %r0,__VDSO_NTP_MULT(%r5)
|
||||
4: al %r0,24(%r15)
|
||||
srdl %r0,12
|
||||
al %r0,__VDSO_XTIME_NSEC(%r5) /* + xtime */
|
||||
|
|
|
@ -36,7 +36,7 @@ __kernel_clock_gettime:
|
|||
stck 48(%r15) /* Store TOD clock */
|
||||
lg %r1,48(%r15)
|
||||
sg %r1,__VDSO_XTIME_STAMP(%r5) /* TOD - cycle_last */
|
||||
mghi %r1,1000
|
||||
msgf %r1,__VDSO_NTP_MULT(%r5) /* * NTP adjustment */
|
||||
srlg %r1,%r1,12 /* cyc2ns(clock,cycle_delta) */
|
||||
alg %r1,__VDSO_XTIME_NSEC(%r5) /* + xtime */
|
||||
lg %r0,__VDSO_XTIME_SEC(%r5)
|
||||
|
@ -64,7 +64,7 @@ __kernel_clock_gettime:
|
|||
stck 48(%r15) /* Store TOD clock */
|
||||
lg %r1,48(%r15)
|
||||
sg %r1,__VDSO_XTIME_STAMP(%r5) /* TOD - cycle_last */
|
||||
mghi %r1,1000
|
||||
msgf %r1,__VDSO_NTP_MULT(%r5) /* * NTP adjustment */
|
||||
srlg %r1,%r1,12 /* cyc2ns(clock,cycle_delta) */
|
||||
alg %r1,__VDSO_XTIME_NSEC(%r5) /* + xtime */
|
||||
lg %r0,__VDSO_XTIME_SEC(%r5)
|
||||
|
|
|
@ -31,7 +31,7 @@ __kernel_gettimeofday:
|
|||
stck 48(%r15) /* Store TOD clock */
|
||||
lg %r1,48(%r15)
|
||||
sg %r1,__VDSO_XTIME_STAMP(%r5) /* TOD - cycle_last */
|
||||
mghi %r1,1000
|
||||
msgf %r1,__VDSO_NTP_MULT(%r5) /* * NTP adjustment */
|
||||
srlg %r1,%r1,12 /* cyc2ns(clock,cycle_delta) */
|
||||
alg %r1,__VDSO_XTIME_NSEC(%r5) /* + xtime.tv_nsec */
|
||||
lg %r0,__VDSO_XTIME_SEC(%r5) /* xtime.tv_sec */
|
||||
|
|
|
@ -37,6 +37,9 @@ config SPARC64
|
|||
def_bool 64BIT
|
||||
select ARCH_SUPPORTS_MSI
|
||||
select HAVE_FUNCTION_TRACER
|
||||
select HAVE_FUNCTION_GRAPH_TRACER
|
||||
select HAVE_FUNCTION_GRAPH_FP_TEST
|
||||
select HAVE_FUNCTION_TRACE_MCOUNT_TEST
|
||||
select HAVE_KRETPROBES
|
||||
select HAVE_KPROBES
|
||||
select HAVE_LMB
|
||||
|
|
|
@ -19,13 +19,10 @@ config DEBUG_DCFLUSH
|
|||
bool "D-cache flush debugging"
|
||||
depends on SPARC64 && DEBUG_KERNEL
|
||||
|
||||
config STACK_DEBUG
|
||||
bool "Stack Overflow Detection Support"
|
||||
|
||||
config MCOUNT
|
||||
bool
|
||||
depends on SPARC64
|
||||
depends on STACK_DEBUG || FUNCTION_TRACER
|
||||
depends on FUNCTION_TRACER
|
||||
default y
|
||||
|
||||
config FRAME_POINTER
|
||||
|
|
|
@ -17,7 +17,7 @@ typedef struct {
|
|||
unsigned int __nmi_count;
|
||||
unsigned long clock_tick; /* %tick's per second */
|
||||
unsigned long __pad;
|
||||
unsigned int __pad1;
|
||||
unsigned int irq0_irqs;
|
||||
unsigned int __pad2;
|
||||
|
||||
/* Dcache line 2, rarely used */
|
||||
|
|
|
@ -76,9 +76,26 @@ static inline int raw_irqs_disabled(void)
|
|||
*/
|
||||
static inline unsigned long __raw_local_irq_save(void)
|
||||
{
|
||||
unsigned long flags = __raw_local_save_flags();
|
||||
unsigned long flags, tmp;
|
||||
|
||||
raw_local_irq_disable();
|
||||
/* Disable interrupts to PIL_NORMAL_MAX unless we already
|
||||
* are using PIL_NMI, in which case PIL_NMI is retained.
|
||||
*
|
||||
* The only values we ever program into the %pil are 0,
|
||||
* PIL_NORMAL_MAX and PIL_NMI.
|
||||
*
|
||||
* Since PIL_NMI is the largest %pil value and all bits are
|
||||
* set in it (0xf), it doesn't matter what PIL_NORMAL_MAX
|
||||
* actually is.
|
||||
*/
|
||||
__asm__ __volatile__(
|
||||
"rdpr %%pil, %0\n\t"
|
||||
"or %0, %2, %1\n\t"
|
||||
"wrpr %1, 0x0, %%pil"
|
||||
: "=r" (flags), "=r" (tmp)
|
||||
: "i" (PIL_NORMAL_MAX)
|
||||
: "memory"
|
||||
);
|
||||
|
||||
return flags;
|
||||
}
|
||||
|
|
|
@ -111,7 +111,7 @@ struct thread_info {
|
|||
#define THREAD_SHIFT PAGE_SHIFT
|
||||
#endif /* PAGE_SHIFT == 13 */
|
||||
|
||||
#define PREEMPT_ACTIVE 0x4000000
|
||||
#define PREEMPT_ACTIVE 0x10000000
|
||||
|
||||
/*
|
||||
* macros/functions for gaining access to the thread information structure
|
||||
|
|
|
@ -13,6 +13,14 @@ extra-y += init_task.o
|
|||
CPPFLAGS_vmlinux.lds := -Usparc -m$(BITS)
|
||||
extra-y += vmlinux.lds
|
||||
|
||||
ifdef CONFIG_FUNCTION_TRACER
|
||||
# Do not profile debug and lowlevel utilities
|
||||
CFLAGS_REMOVE_ftrace.o := -pg
|
||||
CFLAGS_REMOVE_time_$(BITS).o := -pg
|
||||
CFLAGS_REMOVE_perf_event.o := -pg
|
||||
CFLAGS_REMOVE_pcr.o := -pg
|
||||
endif
|
||||
|
||||
obj-$(CONFIG_SPARC32) += entry.o wof.o wuf.o
|
||||
obj-$(CONFIG_SPARC32) += etrap_32.o
|
||||
obj-$(CONFIG_SPARC32) += rtrap_32.o
|
||||
|
@ -85,7 +93,7 @@ obj-$(CONFIG_KGDB) += kgdb_$(BITS).o
|
|||
|
||||
|
||||
obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o
|
||||
CFLAGS_REMOVE_ftrace.o := -pg
|
||||
obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o
|
||||
|
||||
obj-$(CONFIG_EARLYFB) += btext.o
|
||||
obj-$(CONFIG_STACKTRACE) += stacktrace.o
|
||||
|
|
|
@ -13,7 +13,7 @@ static const u32 ftrace_nop = 0x01000000;
|
|||
|
||||
static u32 ftrace_call_replace(unsigned long ip, unsigned long addr)
|
||||
{
|
||||
static u32 call;
|
||||
u32 call;
|
||||
s32 off;
|
||||
|
||||
off = ((s32)addr - (s32)ip);
|
||||
|
@ -91,3 +91,61 @@ int __init ftrace_dyn_arch_init(void *data)
|
|||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_FUNCTION_GRAPH_TRACER
|
||||
|
||||
#ifdef CONFIG_DYNAMIC_FTRACE
|
||||
extern void ftrace_graph_call(void);
|
||||
|
||||
int ftrace_enable_ftrace_graph_caller(void)
|
||||
{
|
||||
unsigned long ip = (unsigned long)(&ftrace_graph_call);
|
||||
u32 old, new;
|
||||
|
||||
old = *(u32 *) &ftrace_graph_call;
|
||||
new = ftrace_call_replace(ip, (unsigned long) &ftrace_graph_caller);
|
||||
return ftrace_modify_code(ip, old, new);
|
||||
}
|
||||
|
||||
int ftrace_disable_ftrace_graph_caller(void)
|
||||
{
|
||||
unsigned long ip = (unsigned long)(&ftrace_graph_call);
|
||||
u32 old, new;
|
||||
|
||||
old = *(u32 *) &ftrace_graph_call;
|
||||
new = ftrace_call_replace(ip, (unsigned long) &ftrace_stub);
|
||||
|
||||
return ftrace_modify_code(ip, old, new);
|
||||
}
|
||||
|
||||
#endif /* !CONFIG_DYNAMIC_FTRACE */
|
||||
|
||||
/*
|
||||
* Hook the return address and push it in the stack of return addrs
|
||||
* in current thread info.
|
||||
*/
|
||||
unsigned long prepare_ftrace_return(unsigned long parent,
|
||||
unsigned long self_addr,
|
||||
unsigned long frame_pointer)
|
||||
{
|
||||
unsigned long return_hooker = (unsigned long) &return_to_handler;
|
||||
struct ftrace_graph_ent trace;
|
||||
|
||||
if (unlikely(atomic_read(¤t->tracing_graph_pause)))
|
||||
return parent + 8UL;
|
||||
|
||||
if (ftrace_push_return_trace(parent, self_addr, &trace.depth,
|
||||
frame_pointer) == -EBUSY)
|
||||
return parent + 8UL;
|
||||
|
||||
trace.func = self_addr;
|
||||
|
||||
/* Only trace if the calling function expects to */
|
||||
if (!ftrace_graph_entry(&trace)) {
|
||||
current->curr_ret_stack--;
|
||||
return parent + 8UL;
|
||||
}
|
||||
|
||||
return return_hooker;
|
||||
}
|
||||
#endif /* CONFIG_FUNCTION_GRAPH_TRACER */
|
||||
|
|
|
@ -20,7 +20,9 @@
|
|||
#include <linux/delay.h>
|
||||
#include <linux/proc_fs.h>
|
||||
#include <linux/seq_file.h>
|
||||
#include <linux/ftrace.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/kmemleak.h>
|
||||
|
||||
#include <asm/ptrace.h>
|
||||
#include <asm/processor.h>
|
||||
|
@ -45,6 +47,7 @@
|
|||
|
||||
#include "entry.h"
|
||||
#include "cpumap.h"
|
||||
#include "kstack.h"
|
||||
|
||||
#define NUM_IVECS (IMAP_INR + 1)
|
||||
|
||||
|
@ -647,6 +650,14 @@ unsigned int sun4v_build_virq(u32 devhandle, unsigned int devino)
|
|||
bucket = kzalloc(sizeof(struct ino_bucket), GFP_ATOMIC);
|
||||
if (unlikely(!bucket))
|
||||
return 0;
|
||||
|
||||
/* The only reference we store to the IRQ bucket is
|
||||
* by physical address which kmemleak can't see, tell
|
||||
* it that this object explicitly is not a leak and
|
||||
* should be scanned.
|
||||
*/
|
||||
kmemleak_not_leak(bucket);
|
||||
|
||||
__flush_dcache_range((unsigned long) bucket,
|
||||
((unsigned long) bucket +
|
||||
sizeof(struct ino_bucket)));
|
||||
|
@ -703,25 +714,7 @@ void ack_bad_irq(unsigned int virt_irq)
|
|||
void *hardirq_stack[NR_CPUS];
|
||||
void *softirq_stack[NR_CPUS];
|
||||
|
||||
static __attribute__((always_inline)) void *set_hardirq_stack(void)
|
||||
{
|
||||
void *orig_sp, *sp = hardirq_stack[smp_processor_id()];
|
||||
|
||||
__asm__ __volatile__("mov %%sp, %0" : "=r" (orig_sp));
|
||||
if (orig_sp < sp ||
|
||||
orig_sp > (sp + THREAD_SIZE)) {
|
||||
sp += THREAD_SIZE - 192 - STACK_BIAS;
|
||||
__asm__ __volatile__("mov %0, %%sp" : : "r" (sp));
|
||||
}
|
||||
|
||||
return orig_sp;
|
||||
}
|
||||
static __attribute__((always_inline)) void restore_hardirq_stack(void *orig_sp)
|
||||
{
|
||||
__asm__ __volatile__("mov %0, %%sp" : : "r" (orig_sp));
|
||||
}
|
||||
|
||||
void handler_irq(int irq, struct pt_regs *regs)
|
||||
void __irq_entry handler_irq(int irq, struct pt_regs *regs)
|
||||
{
|
||||
unsigned long pstate, bucket_pa;
|
||||
struct pt_regs *old_regs;
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
#include <linux/kgdb.h>
|
||||
#include <linux/kdebug.h>
|
||||
#include <linux/ftrace.h>
|
||||
|
||||
#include <asm/kdebug.h>
|
||||
#include <asm/ptrace.h>
|
||||
|
@ -108,7 +109,7 @@ void gdb_regs_to_pt_regs(unsigned long *gdb_regs, struct pt_regs *regs)
|
|||
}
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
void smp_kgdb_capture_client(int irq, struct pt_regs *regs)
|
||||
void __irq_entry smp_kgdb_capture_client(int irq, struct pt_regs *regs)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
|
|
|
@ -61,4 +61,23 @@ check_magic:
|
|||
|
||||
}
|
||||
|
||||
static inline __attribute__((always_inline)) void *set_hardirq_stack(void)
|
||||
{
|
||||
void *orig_sp, *sp = hardirq_stack[smp_processor_id()];
|
||||
|
||||
__asm__ __volatile__("mov %%sp, %0" : "=r" (orig_sp));
|
||||
if (orig_sp < sp ||
|
||||
orig_sp > (sp + THREAD_SIZE)) {
|
||||
sp += THREAD_SIZE - 192 - STACK_BIAS;
|
||||
__asm__ __volatile__("mov %0, %%sp" : : "r" (sp));
|
||||
}
|
||||
|
||||
return orig_sp;
|
||||
}
|
||||
|
||||
static inline __attribute__((always_inline)) void restore_hardirq_stack(void *orig_sp)
|
||||
{
|
||||
__asm__ __volatile__("mov %0, %%sp" : : "r" (orig_sp));
|
||||
}
|
||||
|
||||
#endif /* _KSTACK_H */
|
||||
|
|
|
@ -23,6 +23,8 @@
|
|||
#include <asm/ptrace.h>
|
||||
#include <asm/pcr.h>
|
||||
|
||||
#include "kstack.h"
|
||||
|
||||
/* We don't have a real NMI on sparc64, but we can fake one
|
||||
* up using profiling counter overflow interrupts and interrupt
|
||||
* levels.
|
||||
|
@ -92,7 +94,7 @@ static void die_nmi(const char *str, struct pt_regs *regs, int do_panic)
|
|||
notrace __kprobes void perfctr_irq(int irq, struct pt_regs *regs)
|
||||
{
|
||||
unsigned int sum, touched = 0;
|
||||
int cpu = smp_processor_id();
|
||||
void *orig_sp;
|
||||
|
||||
clear_softint(1 << irq);
|
||||
|
||||
|
@ -100,13 +102,15 @@ notrace __kprobes void perfctr_irq(int irq, struct pt_regs *regs)
|
|||
|
||||
nmi_enter();
|
||||
|
||||
orig_sp = set_hardirq_stack();
|
||||
|
||||
if (notify_die(DIE_NMI, "nmi", regs, 0,
|
||||
pt_regs_trap_type(regs), SIGINT) == NOTIFY_STOP)
|
||||
touched = 1;
|
||||
else
|
||||
pcr_ops->write(PCR_PIC_PRIV);
|
||||
|
||||
sum = kstat_irqs_cpu(0, cpu);
|
||||
sum = local_cpu_data().irq0_irqs;
|
||||
if (__get_cpu_var(nmi_touch)) {
|
||||
__get_cpu_var(nmi_touch) = 0;
|
||||
touched = 1;
|
||||
|
@ -125,6 +129,8 @@ notrace __kprobes void perfctr_irq(int irq, struct pt_regs *regs)
|
|||
pcr_ops->write(pcr_enable);
|
||||
}
|
||||
|
||||
restore_hardirq_stack(orig_sp);
|
||||
|
||||
nmi_exit();
|
||||
}
|
||||
|
||||
|
|
|
@ -371,14 +371,19 @@ static void pci_register_iommu_region(struct pci_pbm_info *pbm)
|
|||
struct resource *rp = kzalloc(sizeof(*rp), GFP_KERNEL);
|
||||
|
||||
if (!rp) {
|
||||
prom_printf("Cannot allocate IOMMU resource.\n");
|
||||
prom_halt();
|
||||
pr_info("%s: Cannot allocate IOMMU resource.\n",
|
||||
pbm->name);
|
||||
return;
|
||||
}
|
||||
rp->name = "IOMMU";
|
||||
rp->start = pbm->mem_space.start + (unsigned long) vdma[0];
|
||||
rp->end = rp->start + (unsigned long) vdma[1] - 1UL;
|
||||
rp->flags = IORESOURCE_BUSY;
|
||||
request_resource(&pbm->mem_space, rp);
|
||||
if (request_resource(&pbm->mem_space, rp)) {
|
||||
pr_info("%s: Unable to request IOMMU resource.\n",
|
||||
pbm->name);
|
||||
kfree(rp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include <linux/irq.h>
|
||||
|
||||
#include <linux/perf_event.h>
|
||||
#include <linux/ftrace.h>
|
||||
|
||||
#include <asm/pil.h>
|
||||
#include <asm/pcr.h>
|
||||
|
@ -34,7 +35,7 @@ unsigned int picl_shift;
|
|||
* Therefore in such situations we defer the work by signalling
|
||||
* a lower level cpu IRQ.
|
||||
*/
|
||||
void deferred_pcr_work_irq(int irq, struct pt_regs *regs)
|
||||
void __irq_entry deferred_pcr_work_irq(int irq, struct pt_regs *regs)
|
||||
{
|
||||
struct pt_regs *old_regs;
|
||||
|
||||
|
|
|
@ -130,7 +130,17 @@ rtrap_xcall:
|
|||
nop
|
||||
call trace_hardirqs_on
|
||||
nop
|
||||
wrpr %l4, %pil
|
||||
/* Do not actually set the %pil here. We will do that
|
||||
* below after we clear PSTATE_IE in the %pstate register.
|
||||
* If we re-enable interrupts here, we can recurse down
|
||||
* the hardirq stack potentially endlessly, causing a
|
||||
* stack overflow.
|
||||
*
|
||||
* It is tempting to put this test and trace_hardirqs_on
|
||||
* call at the 'rt_continue' label, but that will not work
|
||||
* as that path hits unconditionally and we do not want to
|
||||
* execute this in NMI return paths, for example.
|
||||
*/
|
||||
#endif
|
||||
rtrap_no_irq_enable:
|
||||
andcc %l1, TSTATE_PRIV, %l3
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include <linux/profile.h>
|
||||
#include <linux/bootmem.h>
|
||||
#include <linux/vmalloc.h>
|
||||
#include <linux/ftrace.h>
|
||||
#include <linux/cpu.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
|
@ -823,13 +824,13 @@ void arch_send_call_function_single_ipi(int cpu)
|
|||
&cpumask_of_cpu(cpu));
|
||||
}
|
||||
|
||||
void smp_call_function_client(int irq, struct pt_regs *regs)
|
||||
void __irq_entry smp_call_function_client(int irq, struct pt_regs *regs)
|
||||
{
|
||||
clear_softint(1 << irq);
|
||||
generic_smp_call_function_interrupt();
|
||||
}
|
||||
|
||||
void smp_call_function_single_client(int irq, struct pt_regs *regs)
|
||||
void __irq_entry smp_call_function_single_client(int irq, struct pt_regs *regs)
|
||||
{
|
||||
clear_softint(1 << irq);
|
||||
generic_smp_call_function_single_interrupt();
|
||||
|
@ -965,7 +966,7 @@ void flush_dcache_page_all(struct mm_struct *mm, struct page *page)
|
|||
put_cpu();
|
||||
}
|
||||
|
||||
void smp_new_mmu_context_version_client(int irq, struct pt_regs *regs)
|
||||
void __irq_entry smp_new_mmu_context_version_client(int irq, struct pt_regs *regs)
|
||||
{
|
||||
struct mm_struct *mm;
|
||||
unsigned long flags;
|
||||
|
@ -1149,7 +1150,7 @@ void smp_release(void)
|
|||
*/
|
||||
extern void prom_world(int);
|
||||
|
||||
void smp_penguin_jailcell(int irq, struct pt_regs *regs)
|
||||
void __irq_entry smp_penguin_jailcell(int irq, struct pt_regs *regs)
|
||||
{
|
||||
clear_softint(1 << irq);
|
||||
|
||||
|
@ -1365,7 +1366,7 @@ void smp_send_reschedule(int cpu)
|
|||
&cpumask_of_cpu(cpu));
|
||||
}
|
||||
|
||||
void smp_receive_signal_client(int irq, struct pt_regs *regs)
|
||||
void __irq_entry smp_receive_signal_client(int irq, struct pt_regs *regs)
|
||||
{
|
||||
clear_softint(1 << irq);
|
||||
}
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
#include <linux/clocksource.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/ftrace.h>
|
||||
|
||||
#include <asm/oplib.h>
|
||||
#include <asm/timer.h>
|
||||
|
@ -717,7 +718,7 @@ static struct clock_event_device sparc64_clockevent = {
|
|||
};
|
||||
static DEFINE_PER_CPU(struct clock_event_device, sparc64_events);
|
||||
|
||||
void timer_interrupt(int irq, struct pt_regs *regs)
|
||||
void __irq_entry timer_interrupt(int irq, struct pt_regs *regs)
|
||||
{
|
||||
struct pt_regs *old_regs = set_irq_regs(regs);
|
||||
unsigned long tick_mask = tick_ops->softint_mask;
|
||||
|
@ -728,6 +729,7 @@ void timer_interrupt(int irq, struct pt_regs *regs)
|
|||
|
||||
irq_enter();
|
||||
|
||||
local_cpu_data().irq0_irqs++;
|
||||
kstat_incr_irqs_this_cpu(0, irq_to_desc(0));
|
||||
|
||||
if (unlikely(!evt->event_handler)) {
|
||||
|
|
|
@ -2203,27 +2203,6 @@ void dump_stack(void)
|
|||
|
||||
EXPORT_SYMBOL(dump_stack);
|
||||
|
||||
static inline int is_kernel_stack(struct task_struct *task,
|
||||
struct reg_window *rw)
|
||||
{
|
||||
unsigned long rw_addr = (unsigned long) rw;
|
||||
unsigned long thread_base, thread_end;
|
||||
|
||||
if (rw_addr < PAGE_OFFSET) {
|
||||
if (task != &init_task)
|
||||
return 0;
|
||||
}
|
||||
|
||||
thread_base = (unsigned long) task_stack_page(task);
|
||||
thread_end = thread_base + sizeof(union thread_union);
|
||||
if (rw_addr >= thread_base &&
|
||||
rw_addr < thread_end &&
|
||||
!(rw_addr & 0x7UL))
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline struct reg_window *kernel_stack_up(struct reg_window *rw)
|
||||
{
|
||||
unsigned long fp = rw->ins[6];
|
||||
|
@ -2252,6 +2231,7 @@ void die_if_kernel(char *str, struct pt_regs *regs)
|
|||
show_regs(regs);
|
||||
add_taint(TAINT_DIE);
|
||||
if (regs->tstate & TSTATE_PRIV) {
|
||||
struct thread_info *tp = current_thread_info();
|
||||
struct reg_window *rw = (struct reg_window *)
|
||||
(regs->u_regs[UREG_FP] + STACK_BIAS);
|
||||
|
||||
|
@ -2259,8 +2239,8 @@ void die_if_kernel(char *str, struct pt_regs *regs)
|
|||
* find some badly aligned kernel stack.
|
||||
*/
|
||||
while (rw &&
|
||||
count++ < 30&&
|
||||
is_kernel_stack(current, rw)) {
|
||||
count++ < 30 &&
|
||||
kstack_valid(tp, (unsigned long) rw)) {
|
||||
printk("Caller[%016lx]: %pS\n", rw->ins[7],
|
||||
(void *) rw->ins[7]);
|
||||
|
||||
|
|
|
@ -50,7 +50,7 @@ static inline enum direction decode_direction(unsigned int insn)
|
|||
}
|
||||
|
||||
/* 16 = double-word, 8 = extra-word, 4 = word, 2 = half-word */
|
||||
static inline int decode_access_size(unsigned int insn)
|
||||
static inline int decode_access_size(struct pt_regs *regs, unsigned int insn)
|
||||
{
|
||||
unsigned int tmp;
|
||||
|
||||
|
@ -66,7 +66,7 @@ static inline int decode_access_size(unsigned int insn)
|
|||
return 2;
|
||||
else {
|
||||
printk("Impossible unaligned trap. insn=%08x\n", insn);
|
||||
die_if_kernel("Byte sized unaligned access?!?!", current_thread_info()->kregs);
|
||||
die_if_kernel("Byte sized unaligned access?!?!", regs);
|
||||
|
||||
/* GCC should never warn that control reaches the end
|
||||
* of this function without returning a value because
|
||||
|
@ -286,7 +286,7 @@ static void log_unaligned(struct pt_regs *regs)
|
|||
asmlinkage void kernel_unaligned_trap(struct pt_regs *regs, unsigned int insn)
|
||||
{
|
||||
enum direction dir = decode_direction(insn);
|
||||
int size = decode_access_size(insn);
|
||||
int size = decode_access_size(regs, insn);
|
||||
int orig_asi, asi;
|
||||
|
||||
current_thread_info()->kern_una_regs = regs;
|
||||
|
|
|
@ -46,11 +46,16 @@ SECTIONS
|
|||
SCHED_TEXT
|
||||
LOCK_TEXT
|
||||
KPROBES_TEXT
|
||||
IRQENTRY_TEXT
|
||||
*(.gnu.warning)
|
||||
} = 0
|
||||
_etext = .;
|
||||
|
||||
RO_DATA(PAGE_SIZE)
|
||||
|
||||
/* Start of data section */
|
||||
_sdata = .;
|
||||
|
||||
.data1 : {
|
||||
*(.data1)
|
||||
}
|
||||
|
|
|
@ -7,26 +7,11 @@
|
|||
|
||||
#include <linux/linkage.h>
|
||||
|
||||
#include <asm/ptrace.h>
|
||||
#include <asm/thread_info.h>
|
||||
|
||||
/*
|
||||
* This is the main variant and is called by C code. GCC's -pg option
|
||||
* automatically instruments every C function with a call to this.
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_STACK_DEBUG
|
||||
|
||||
#define OVSTACKSIZE 4096 /* lets hope this is enough */
|
||||
|
||||
.data
|
||||
.align 8
|
||||
panicstring:
|
||||
.asciz "Stack overflow\n"
|
||||
.align 8
|
||||
ovstack:
|
||||
.skip OVSTACKSIZE
|
||||
#endif
|
||||
.text
|
||||
.align 32
|
||||
.globl _mcount
|
||||
|
@ -35,84 +20,48 @@ ovstack:
|
|||
.type mcount,#function
|
||||
_mcount:
|
||||
mcount:
|
||||
#ifdef CONFIG_STACK_DEBUG
|
||||
/*
|
||||
* Check whether %sp is dangerously low.
|
||||
*/
|
||||
ldub [%g6 + TI_FPDEPTH], %g1
|
||||
srl %g1, 1, %g3
|
||||
add %g3, 1, %g3
|
||||
sllx %g3, 8, %g3 ! each fpregs frame is 256b
|
||||
add %g3, 192, %g3
|
||||
add %g6, %g3, %g3 ! where does task_struct+frame end?
|
||||
sub %g3, STACK_BIAS, %g3
|
||||
cmp %sp, %g3
|
||||
bg,pt %xcc, 1f
|
||||
nop
|
||||
lduh [%g6 + TI_CPU], %g1
|
||||
sethi %hi(hardirq_stack), %g3
|
||||
or %g3, %lo(hardirq_stack), %g3
|
||||
sllx %g1, 3, %g1
|
||||
ldx [%g3 + %g1], %g7
|
||||
sub %g7, STACK_BIAS, %g7
|
||||
cmp %sp, %g7
|
||||
bleu,pt %xcc, 2f
|
||||
sethi %hi(THREAD_SIZE), %g3
|
||||
add %g7, %g3, %g7
|
||||
cmp %sp, %g7
|
||||
blu,pn %xcc, 1f
|
||||
2: sethi %hi(softirq_stack), %g3
|
||||
or %g3, %lo(softirq_stack), %g3
|
||||
ldx [%g3 + %g1], %g7
|
||||
sub %g7, STACK_BIAS, %g7
|
||||
cmp %sp, %g7
|
||||
bleu,pt %xcc, 3f
|
||||
sethi %hi(THREAD_SIZE), %g3
|
||||
add %g7, %g3, %g7
|
||||
cmp %sp, %g7
|
||||
blu,pn %xcc, 1f
|
||||
nop
|
||||
/* If we are already on ovstack, don't hop onto it
|
||||
* again, we are already trying to output the stack overflow
|
||||
* message.
|
||||
*/
|
||||
3: sethi %hi(ovstack), %g7 ! cant move to panic stack fast enough
|
||||
or %g7, %lo(ovstack), %g7
|
||||
add %g7, OVSTACKSIZE, %g3
|
||||
sub %g3, STACK_BIAS + 192, %g3
|
||||
sub %g7, STACK_BIAS, %g7
|
||||
cmp %sp, %g7
|
||||
blu,pn %xcc, 2f
|
||||
cmp %sp, %g3
|
||||
bleu,pn %xcc, 1f
|
||||
nop
|
||||
2: mov %g3, %sp
|
||||
sethi %hi(panicstring), %g3
|
||||
call prom_printf
|
||||
or %g3, %lo(panicstring), %o0
|
||||
call prom_halt
|
||||
nop
|
||||
1:
|
||||
#endif
|
||||
#ifdef CONFIG_FUNCTION_TRACER
|
||||
#ifdef CONFIG_DYNAMIC_FTRACE
|
||||
mov %o7, %o0
|
||||
.globl mcount_call
|
||||
mcount_call:
|
||||
call ftrace_stub
|
||||
mov %o0, %o7
|
||||
/* Do nothing, the retl/nop below is all we need. */
|
||||
#else
|
||||
sethi %hi(ftrace_trace_function), %g1
|
||||
sethi %hi(function_trace_stop), %g1
|
||||
lduw [%g1 + %lo(function_trace_stop)], %g2
|
||||
brnz,pn %g2, 2f
|
||||
sethi %hi(ftrace_trace_function), %g1
|
||||
sethi %hi(ftrace_stub), %g2
|
||||
ldx [%g1 + %lo(ftrace_trace_function)], %g1
|
||||
or %g2, %lo(ftrace_stub), %g2
|
||||
cmp %g1, %g2
|
||||
be,pn %icc, 1f
|
||||
mov %i7, %o1
|
||||
jmpl %g1, %g0
|
||||
mov %o7, %o0
|
||||
mov %i7, %g3
|
||||
save %sp, -176, %sp
|
||||
mov %g3, %o1
|
||||
jmpl %g1, %o7
|
||||
mov %i7, %o0
|
||||
ret
|
||||
restore
|
||||
/* not reached */
|
||||
1:
|
||||
#ifdef CONFIG_FUNCTION_GRAPH_TRACER
|
||||
sethi %hi(ftrace_graph_return), %g1
|
||||
ldx [%g1 + %lo(ftrace_graph_return)], %g3
|
||||
cmp %g2, %g3
|
||||
bne,pn %xcc, 5f
|
||||
sethi %hi(ftrace_graph_entry_stub), %g2
|
||||
sethi %hi(ftrace_graph_entry), %g1
|
||||
or %g2, %lo(ftrace_graph_entry_stub), %g2
|
||||
ldx [%g1 + %lo(ftrace_graph_entry)], %g1
|
||||
cmp %g1, %g2
|
||||
be,pt %xcc, 2f
|
||||
nop
|
||||
5: mov %i7, %g2
|
||||
mov %fp, %g3
|
||||
save %sp, -176, %sp
|
||||
mov %g2, %l0
|
||||
ba,pt %xcc, ftrace_graph_caller
|
||||
mov %g3, %l1
|
||||
#endif
|
||||
2:
|
||||
#endif
|
||||
#endif
|
||||
retl
|
||||
|
@ -131,14 +80,50 @@ ftrace_stub:
|
|||
.globl ftrace_caller
|
||||
.type ftrace_caller,#function
|
||||
ftrace_caller:
|
||||
mov %i7, %o1
|
||||
mov %o7, %o0
|
||||
sethi %hi(function_trace_stop), %g1
|
||||
mov %i7, %g2
|
||||
lduw [%g1 + %lo(function_trace_stop)], %g1
|
||||
brnz,pn %g1, ftrace_stub
|
||||
mov %fp, %g3
|
||||
save %sp, -176, %sp
|
||||
mov %g2, %o1
|
||||
mov %g2, %l0
|
||||
mov %g3, %l1
|
||||
.globl ftrace_call
|
||||
ftrace_call:
|
||||
call ftrace_stub
|
||||
mov %o0, %o7
|
||||
retl
|
||||
mov %i7, %o0
|
||||
#ifdef CONFIG_FUNCTION_GRAPH_TRACER
|
||||
.globl ftrace_graph_call
|
||||
ftrace_graph_call:
|
||||
call ftrace_stub
|
||||
nop
|
||||
#endif
|
||||
ret
|
||||
restore
|
||||
#ifdef CONFIG_FUNCTION_GRAPH_TRACER
|
||||
.size ftrace_graph_call,.-ftrace_graph_call
|
||||
#endif
|
||||
.size ftrace_call,.-ftrace_call
|
||||
.size ftrace_caller,.-ftrace_caller
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_FUNCTION_GRAPH_TRACER
|
||||
ENTRY(ftrace_graph_caller)
|
||||
mov %l0, %o0
|
||||
mov %i7, %o1
|
||||
call prepare_ftrace_return
|
||||
mov %l1, %o2
|
||||
ret
|
||||
restore %o0, -8, %i7
|
||||
END(ftrace_graph_caller)
|
||||
|
||||
ENTRY(return_to_handler)
|
||||
save %sp, -176, %sp
|
||||
call ftrace_return_to_handler
|
||||
mov %fp, %o0
|
||||
jmpl %o0 + 8, %g0
|
||||
restore
|
||||
END(return_to_handler)
|
||||
#endif
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#include "linux/irqreturn.h"
|
||||
#include "linux/kd.h"
|
||||
#include "linux/sched.h"
|
||||
#include "linux/slab.h"
|
||||
#include "chan_kern.h"
|
||||
#include "irq_kern.h"
|
||||
#include "irq_user.h"
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
#include <errno.h>
|
||||
#include <sched.h>
|
||||
#include <linux/limits.h>
|
||||
#include <linux/slab.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/wait.h>
|
||||
#include "kern_constants.h"
|
||||
|
|
|
@ -626,7 +626,7 @@ ia32_sys_call_table:
|
|||
.quad stub32_sigreturn
|
||||
.quad stub32_clone /* 120 */
|
||||
.quad sys_setdomainname
|
||||
.quad sys_uname
|
||||
.quad sys_newuname
|
||||
.quad sys_modify_ldt
|
||||
.quad compat_sys_adjtimex
|
||||
.quad sys32_mprotect /* 125 */
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#define _ASM_X86_AMD_IOMMU_TYPES_H
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/spinlock.h>
|
||||
|
||||
|
@ -140,6 +141,7 @@
|
|||
|
||||
/* constants to configure the command buffer */
|
||||
#define CMD_BUFFER_SIZE 8192
|
||||
#define CMD_BUFFER_UNINITIALIZED 1
|
||||
#define CMD_BUFFER_ENTRIES 512
|
||||
#define MMIO_CMD_SIZE_SHIFT 56
|
||||
#define MMIO_CMD_SIZE_512 (0x9ULL << MMIO_CMD_SIZE_SHIFT)
|
||||
|
@ -237,6 +239,7 @@ struct protection_domain {
|
|||
struct list_head list; /* for list of all protection domains */
|
||||
struct list_head dev_list; /* List of all devices in this domain */
|
||||
spinlock_t lock; /* mostly used to lock the page table*/
|
||||
struct mutex api_lock; /* protect page tables in the iommu-api path */
|
||||
u16 id; /* the domain id written to the device table */
|
||||
int mode; /* paging mode (0-6 levels) */
|
||||
u64 *pt_root; /* page table root pointer */
|
||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче