Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
Conflicts: drivers/net/wireless/iwlwifi/iwl-6000.c net/core/dev.c
This commit is contained in:
commit
87eb367003
|
@ -34,7 +34,7 @@ NMI handler.
|
||||||
cpu = smp_processor_id();
|
cpu = smp_processor_id();
|
||||||
++nmi_count(cpu);
|
++nmi_count(cpu);
|
||||||
|
|
||||||
if (!rcu_dereference(nmi_callback)(regs, cpu))
|
if (!rcu_dereference_sched(nmi_callback)(regs, cpu))
|
||||||
default_do_nmi(regs);
|
default_do_nmi(regs);
|
||||||
|
|
||||||
nmi_exit();
|
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,
|
default_do_nmi() function to handle a machine-specific NMI. Finally,
|
||||||
preemption is restored.
|
preemption is restored.
|
||||||
|
|
||||||
Strictly speaking, rcu_dereference() is not needed, since this code runs
|
In theory, rcu_dereference_sched() is not needed, since this code runs
|
||||||
only on i386, which does not need rcu_dereference() anyway. However,
|
only on i386, which in theory does not need rcu_dereference_sched()
|
||||||
it is a good documentation aid, particularly for anyone attempting to
|
anyway. However, in practice it is a good documentation aid, particularly
|
||||||
do something similar on Alpha.
|
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?
|
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
|
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?
|
that the code referenced by the pointer is read-only?
|
||||||
|
|
||||||
Answer: The caller to set_nmi_callback() might well have
|
Answer: The caller to set_nmi_callback() might well have
|
||||||
initialized some data that is to be used by the
|
initialized some data that is to be used by the new NMI
|
||||||
new NMI handler. In this case, the rcu_dereference()
|
handler. In this case, the rcu_dereference_sched() would
|
||||||
would be needed, because otherwise a CPU that received
|
be needed, because otherwise a CPU that received an NMI
|
||||||
an NMI just after the new handler was set might see
|
just after the new handler was set might see the pointer
|
||||||
the pointer to the new NMI handler, but the old
|
to the new NMI handler, but the old pre-initialized
|
||||||
pre-initialized version of the handler's data.
|
version of the handler's data.
|
||||||
|
|
||||||
More important, the rcu_dereference() makes it clear
|
This same sad story can happen on other CPUs when using
|
||||||
to someone reading the code that the pointer is being
|
a compiler with aggressive pointer-value speculation
|
||||||
protected by RCU.
|
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
|
The reason that it is permissible to use RCU list-traversal
|
||||||
primitives when the update-side lock is held is that doing so
|
primitives when the update-side lock is held is that doing so
|
||||||
can be quite helpful in reducing code bloat when common code is
|
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,
|
10. Conversely, if you are in an RCU read-side critical section,
|
||||||
and you don't hold the appropriate update-side lock, you -must-
|
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
|
requiring SRCU's read-side deadlock immunity or low read-side
|
||||||
realtime latency.
|
realtime latency.
|
||||||
|
|
||||||
Note that, rcu_assign_pointer() and rcu_dereference() relate to
|
Note that, rcu_assign_pointer() relates to SRCU just as they do
|
||||||
SRCU just as they do to other forms of RCU.
|
to other forms of RCU.
|
||||||
|
|
||||||
15. The whole point of call_rcu(), synchronize_rcu(), and friends
|
15. The whole point of call_rcu(), synchronize_rcu(), and friends
|
||||||
is to wait until all pre-existing readers have finished before
|
is to wait until all pre-existing readers have finished before
|
||||||
|
|
|
@ -32,9 +32,20 @@ checking of rcu_dereference() primitives:
|
||||||
srcu_dereference(p, sp):
|
srcu_dereference(p, sp):
|
||||||
Check for SRCU read-side critical section.
|
Check for SRCU read-side critical section.
|
||||||
rcu_dereference_check(p, c):
|
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)
|
rcu_dereference_raw(p)
|
||||||
Don't check. (Use sparingly, if at all.)
|
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
|
The rcu_dereference_check() check expression can be any boolean
|
||||||
expression, but would normally include one of the rcu_read_lock_held()
|
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
|
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
|
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
|
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()
|
There are currently only "universal" versions of the rcu_assign_pointer()
|
||||||
and RCU list-/tree-traversal primitives, which do not (yet) check for
|
and RCU list-/tree-traversal primitives, which do not (yet) check for
|
||||||
|
|
|
@ -840,6 +840,12 @@ SRCU: Initialization/cleanup
|
||||||
init_srcu_struct
|
init_srcu_struct
|
||||||
cleanup_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
|
See the comment headers in the source code (or the docbook generated
|
||||||
from them) for more information.
|
from them) for more information.
|
||||||
|
|
||||||
|
|
|
@ -68,6 +68,22 @@ like:
|
||||||
SYN_MT_REPORT
|
SYN_MT_REPORT
|
||||||
SYN_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
|
Event Semantics
|
||||||
---------------
|
---------------
|
||||||
|
@ -217,11 +233,6 @@ where examples can be found.
|
||||||
difference between the contact position and the approaching tool position
|
difference between the contact position and the approaching tool position
|
||||||
could be used to derive tilt.
|
could be used to derive tilt.
|
||||||
[2] The list can of course be extended.
|
[2] The list can of course be extended.
|
||||||
[3] The multi-touch X driver is currently in the prototyping stage. At the
|
[3] Multitouch X driver project: http://bitmath.org/code/multitouch/.
|
||||||
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.
|
|
||||||
[4] See the section on event computation.
|
[4] See the section on event computation.
|
||||||
[5] See the section on finger tracking.
|
[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]
|
amd_iommu= [HW,X86-84]
|
||||||
Pass parameters to the AMD IOMMU driver in the system.
|
Pass parameters to the AMD IOMMU driver in the system.
|
||||||
Possible values are:
|
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
|
fullflush - enable flushing of IO/TLB entries when
|
||||||
they are unmapped. Otherwise they are
|
they are unmapped. Otherwise they are
|
||||||
flushed before they will be reused, which
|
flushed before they will be reused, which
|
||||||
|
|
14
MAINTAINERS
14
MAINTAINERS
|
@ -485,8 +485,8 @@ S: Maintained
|
||||||
F: drivers/input/mouse/bcm5974.c
|
F: drivers/input/mouse/bcm5974.c
|
||||||
|
|
||||||
APPLE SMC DRIVER
|
APPLE SMC DRIVER
|
||||||
M: Nicolas Boichat <nicolas@boichat.ch>
|
M: Henrik Rydberg <rydberg@euromail.se>
|
||||||
L: mactel-linux-devel@lists.sourceforge.net
|
L: lm-sensors@lm-sensors.org
|
||||||
S: Maintained
|
S: Maintained
|
||||||
F: drivers/hwmon/applesmc.c
|
F: drivers/hwmon/applesmc.c
|
||||||
|
|
||||||
|
@ -971,6 +971,16 @@ L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
|
||||||
W: http://www.mcuos.com
|
W: http://www.mcuos.com
|
||||||
S: Maintained
|
S: Maintained
|
||||||
|
|
||||||
|
ARM/U300 MACHINE SUPPORT
|
||||||
|
M: Linus Walleij <linus.walleij@stericsson.com>
|
||||||
|
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
|
||||||
|
S: Supported
|
||||||
|
F: arch/arm/mach-u300/
|
||||||
|
F: drivers/i2c/busses/i2c-stu300.c
|
||||||
|
F: drivers/rtc/rtc-coh901331.c
|
||||||
|
F: drivers/watchdog/coh901327_wdt.c
|
||||||
|
F: drivers/dma/coh901318*
|
||||||
|
|
||||||
ARM/U8500 ARM ARCHITECTURE
|
ARM/U8500 ARM ARCHITECTURE
|
||||||
M: Srinidhi Kasagar <srinidhi.kasagar@stericsson.com>
|
M: Srinidhi Kasagar <srinidhi.kasagar@stericsson.com>
|
||||||
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
|
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
|
||||||
|
|
4
Makefile
4
Makefile
|
@ -1,8 +1,8 @@
|
||||||
VERSION = 2
|
VERSION = 2
|
||||||
PATCHLEVEL = 6
|
PATCHLEVEL = 6
|
||||||
SUBLEVEL = 34
|
SUBLEVEL = 34
|
||||||
EXTRAVERSION = -rc3
|
EXTRAVERSION = -rc5
|
||||||
NAME = Man-Eating Seals of Antiquity
|
NAME = Sheep on Meth
|
||||||
|
|
||||||
# *DOCUMENTATION*
|
# *DOCUMENTATION*
|
||||||
# To see a list of typical targets execute "make help"
|
# To see a list of typical targets execute "make help"
|
||||||
|
|
|
@ -172,7 +172,7 @@ not_angel:
|
||||||
adr r0, LC0
|
adr r0, LC0
|
||||||
ARM( ldmia r0, {r1, r2, r3, r4, r5, r6, r11, ip, sp})
|
ARM( ldmia r0, {r1, r2, r3, r4, r5, r6, r11, ip, sp})
|
||||||
THUMB( ldmia r0, {r1, r2, r3, r4, r5, r6, r11, ip} )
|
THUMB( ldmia r0, {r1, r2, r3, r4, r5, r6, r11, ip} )
|
||||||
THUMB( ldr sp, [r0, #28] )
|
THUMB( ldr sp, [r0, #32] )
|
||||||
subs r0, r0, r1 @ calculate the delta offset
|
subs r0, r0, r1 @ calculate the delta offset
|
||||||
|
|
||||||
@ if delta is zero, we are
|
@ if delta is zero, we are
|
||||||
|
|
|
@ -11,7 +11,11 @@
|
||||||
|
|
||||||
#define kmap_prot PAGE_KERNEL
|
#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;
|
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 *kmap_high_get(struct page *page);
|
||||||
extern void kunmap_high(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 *kmap(struct page *page);
|
||||||
extern void kunmap(struct page *page);
|
extern void kunmap(struct page *page);
|
||||||
extern void *kmap_atomic(struct page *page, enum km_type type);
|
extern void *kmap_atomic(struct page *page, enum km_type type);
|
||||||
extern void kunmap_atomic(void *kvaddr, 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 void *kmap_atomic_pfn(unsigned long pfn, enum km_type type);
|
||||||
extern struct page *kmap_atomic_to_page(const void *ptr);
|
extern struct page *kmap_atomic_to_page(const void *ptr);
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -18,6 +18,7 @@ enum km_type {
|
||||||
KM_IRQ1,
|
KM_IRQ1,
|
||||||
KM_SOFTIRQ0,
|
KM_SOFTIRQ0,
|
||||||
KM_SOFTIRQ1,
|
KM_SOFTIRQ1,
|
||||||
|
KM_L1_CACHE,
|
||||||
KM_L2_CACHE,
|
KM_L2_CACHE,
|
||||||
KM_TYPE_NR
|
KM_TYPE_NR
|
||||||
};
|
};
|
||||||
|
|
|
@ -59,23 +59,22 @@ struct iwmmxt_sigframe {
|
||||||
#endif /* CONFIG_IWMMXT */
|
#endif /* CONFIG_IWMMXT */
|
||||||
|
|
||||||
#ifdef CONFIG_VFP
|
#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_MAGIC 0x56465001
|
||||||
#define VFP_STORAGE_SIZE 152
|
|
||||||
#else
|
|
||||||
#define VFP_MAGIC 0x56465002
|
|
||||||
#define VFP_STORAGE_SIZE 144
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct vfp_sigframe
|
struct vfp_sigframe
|
||||||
{
|
{
|
||||||
unsigned long magic;
|
unsigned long magic;
|
||||||
unsigned long size;
|
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 */
|
#endif /* CONFIG_VFP */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -91,7 +90,7 @@ struct aux_sigframe {
|
||||||
#ifdef CONFIG_IWMMXT
|
#ifdef CONFIG_IWMMXT
|
||||||
struct iwmmxt_sigframe iwmmxt;
|
struct iwmmxt_sigframe iwmmxt;
|
||||||
#endif
|
#endif
|
||||||
#if 0 && defined CONFIG_VFP /* Not yet saved. */
|
#ifdef CONFIG_VFP
|
||||||
struct vfp_sigframe vfp;
|
struct vfp_sigframe vfp;
|
||||||
#endif
|
#endif
|
||||||
/* Something that isn't a valid magic number for any coprocessor. */
|
/* 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
|
* 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 {
|
struct user_vfp {
|
||||||
unsigned long long fpregs[32];
|
unsigned long long fpregs[32];
|
||||||
unsigned long fpscr;
|
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 */
|
#endif /* _ARM_USER_H */
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
#include <asm/cacheflush.h>
|
#include <asm/cacheflush.h>
|
||||||
#include <asm/ucontext.h>
|
#include <asm/ucontext.h>
|
||||||
#include <asm/unistd.h>
|
#include <asm/unistd.h>
|
||||||
|
#include <asm/vfp.h>
|
||||||
|
|
||||||
#include "ptrace.h"
|
#include "ptrace.h"
|
||||||
#include "signal.h"
|
#include "signal.h"
|
||||||
|
@ -175,6 +176,90 @@ static int restore_iwmmxt_context(struct iwmmxt_sigframe *frame)
|
||||||
|
|
||||||
#endif
|
#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.
|
* 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);
|
err |= restore_iwmmxt_context(&aux->iwmmxt);
|
||||||
#endif
|
#endif
|
||||||
#ifdef CONFIG_VFP
|
#ifdef CONFIG_VFP
|
||||||
// if (err == 0)
|
if (err == 0)
|
||||||
// err |= vfp_restore_state(&sf->aux.vfp);
|
err |= restore_vfp_context(&aux->vfp);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return err;
|
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);
|
err |= preserve_iwmmxt_context(&aux->iwmmxt);
|
||||||
#endif
|
#endif
|
||||||
#ifdef CONFIG_VFP
|
#ifdef CONFIG_VFP
|
||||||
// if (err == 0)
|
if (err == 0)
|
||||||
// err |= vfp_save_state(&sf->aux.vfp);
|
err |= preserve_vfp_context(&aux->vfp);
|
||||||
#endif
|
#endif
|
||||||
__put_user_error(0, &aux->end_magic, err);
|
__put_user_error(0, &aux->end_magic, err);
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,7 @@ obj-$(CONFIG_ARCH_AT91SAM9G10) += at91sam9261.o at91sam926x_time.o at91sam9261_d
|
||||||
obj-$(CONFIG_ARCH_AT91SAM9263) += at91sam9263.o at91sam926x_time.o at91sam9263_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_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_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_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_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_AT572D940HF) += at572d940hf.o at91sam926x_time.o at572d940hf_devices.o sam9_smc.o
|
||||||
obj-$(CONFIG_ARCH_AT91X40) += at91x40.o at91x40_time.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 */
|
orr r3, r3, #(1 << 29) /* bit 29 always set */
|
||||||
str r3, [r1, #(AT91_CKGR_PLLAR - AT91_PMC)]
|
str r3, [r1, #(AT91_CKGR_PLLAR - AT91_PMC)]
|
||||||
|
|
||||||
wait_pllalock
|
|
||||||
|
|
||||||
/* Save PLLB setting and disable it */
|
/* Save PLLB setting and disable it */
|
||||||
ldr r3, [r1, #(AT91_CKGR_PLLBR - AT91_PMC)]
|
ldr r3, [r1, #(AT91_CKGR_PLLBR - AT91_PMC)]
|
||||||
str r3, .saved_pllbr
|
str r3, .saved_pllbr
|
||||||
|
@ -184,8 +182,6 @@ ENTRY(at91_slow_clock)
|
||||||
mov r3, #AT91_PMC_PLLCOUNT
|
mov r3, #AT91_PMC_PLLCOUNT
|
||||||
str r3, [r1, #(AT91_CKGR_PLLBR - AT91_PMC)]
|
str r3, [r1, #(AT91_CKGR_PLLBR - AT91_PMC)]
|
||||||
|
|
||||||
wait_pllblock
|
|
||||||
|
|
||||||
/* Turn off the main oscillator */
|
/* Turn off the main oscillator */
|
||||||
ldr r3, [r1, #(AT91_CKGR_MOR - AT91_PMC)]
|
ldr r3, [r1, #(AT91_CKGR_MOR - AT91_PMC)]
|
||||||
bic r3, r3, #AT91_PMC_MOSCEN
|
bic r3, r3, #AT91_PMC_MOSCEN
|
||||||
|
@ -205,13 +201,25 @@ ENTRY(at91_slow_clock)
|
||||||
ldr r3, .saved_pllbr
|
ldr r3, .saved_pllbr
|
||||||
str r3, [r1, #(AT91_CKGR_PLLBR - AT91_PMC)]
|
str r3, [r1, #(AT91_CKGR_PLLBR - AT91_PMC)]
|
||||||
|
|
||||||
|
tst r3, #(AT91_PMC_MUL & 0xff0000)
|
||||||
|
bne 1f
|
||||||
|
tst r3, #(AT91_PMC_MUL & ~0xff0000)
|
||||||
|
beq 2f
|
||||||
|
1:
|
||||||
wait_pllblock
|
wait_pllblock
|
||||||
|
2:
|
||||||
|
|
||||||
/* Restore PLLA setting */
|
/* Restore PLLA setting */
|
||||||
ldr r3, .saved_pllar
|
ldr r3, .saved_pllar
|
||||||
str r3, [r1, #(AT91_CKGR_PLLAR - AT91_PMC)]
|
str r3, [r1, #(AT91_CKGR_PLLAR - AT91_PMC)]
|
||||||
|
|
||||||
|
tst r3, #(AT91_PMC_MUL & 0xff0000)
|
||||||
|
bne 3f
|
||||||
|
tst r3, #(AT91_PMC_MUL & ~0xff0000)
|
||||||
|
beq 4f
|
||||||
|
3:
|
||||||
wait_pllalock
|
wait_pllalock
|
||||||
|
4:
|
||||||
|
|
||||||
#ifdef SLOWDOWN_MASTER_CLOCK
|
#ifdef SLOWDOWN_MASTER_CLOCK
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -2221,11 +2221,15 @@ EXPORT_SYMBOL(dma_map_create_descriptor_ring);
|
||||||
int dma_unmap(DMA_MemMap_t *memMap, /* Stores state information about the map */
|
int dma_unmap(DMA_MemMap_t *memMap, /* Stores state information about the map */
|
||||||
int dirtied /* non-zero if any of the pages were modified */
|
int dirtied /* non-zero if any of the pages were modified */
|
||||||
) {
|
) {
|
||||||
|
|
||||||
|
int rc = 0;
|
||||||
int regionIdx;
|
int regionIdx;
|
||||||
int segmentIdx;
|
int segmentIdx;
|
||||||
DMA_Region_t *region;
|
DMA_Region_t *region;
|
||||||
DMA_Segment_t *segment;
|
DMA_Segment_t *segment;
|
||||||
|
|
||||||
|
down(&memMap->lock);
|
||||||
|
|
||||||
for (regionIdx = 0; regionIdx < memMap->numRegionsUsed; regionIdx++) {
|
for (regionIdx = 0; regionIdx < memMap->numRegionsUsed; regionIdx++) {
|
||||||
region = &memMap->region[regionIdx];
|
region = &memMap->region[regionIdx];
|
||||||
|
|
||||||
|
@ -2239,7 +2243,8 @@ int dma_unmap(DMA_MemMap_t *memMap, /* Stores state information about the map */
|
||||||
printk(KERN_ERR
|
printk(KERN_ERR
|
||||||
"%s: vmalloc'd pages are not yet supported\n",
|
"%s: vmalloc'd pages are not yet supported\n",
|
||||||
__func__);
|
__func__);
|
||||||
return -EINVAL;
|
rc = -EINVAL;
|
||||||
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
case DMA_MEM_TYPE_KMALLOC:
|
case DMA_MEM_TYPE_KMALLOC:
|
||||||
|
@ -2276,7 +2281,8 @@ int dma_unmap(DMA_MemMap_t *memMap, /* Stores state information about the map */
|
||||||
printk(KERN_ERR
|
printk(KERN_ERR
|
||||||
"%s: Unsupported memory type: %d\n",
|
"%s: Unsupported memory type: %d\n",
|
||||||
__func__, region->memType);
|
__func__, region->memType);
|
||||||
return -EINVAL;
|
rc = -EINVAL;
|
||||||
|
goto out;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2314,9 +2320,10 @@ int dma_unmap(DMA_MemMap_t *memMap, /* Stores state information about the map */
|
||||||
memMap->numRegionsUsed = 0;
|
memMap->numRegionsUsed = 0;
|
||||||
memMap->inUse = 0;
|
memMap->inUse = 0;
|
||||||
|
|
||||||
|
out:
|
||||||
up(&memMap->lock);
|
up(&memMap->lock);
|
||||||
|
|
||||||
return 0;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
EXPORT_SYMBOL(dma_unmap);
|
EXPORT_SYMBOL(dma_unmap);
|
||||||
|
|
|
@ -25,7 +25,7 @@
|
||||||
#include <mach/hardware.h>
|
#include <mach/hardware.h>
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
* GPIO handling for EP93xx
|
* Interrupt handling for EP93xx on-chip GPIOs
|
||||||
*************************************************************************/
|
*************************************************************************/
|
||||||
static unsigned char gpio_int_unmasked[3];
|
static unsigned char gpio_int_unmasked[3];
|
||||||
static unsigned char gpio_int_enabled[3];
|
static unsigned char gpio_int_enabled[3];
|
||||||
|
@ -40,7 +40,7 @@ static const u8 eoi_register_offset[3] = { 0x98, 0xb4, 0x54 };
|
||||||
static const u8 int_en_register_offset[3] = { 0x9c, 0xb8, 0x58 };
|
static const u8 int_en_register_offset[3] = { 0x9c, 0xb8, 0x58 };
|
||||||
static const u8 int_debounce_register_offset[3] = { 0xa8, 0xc4, 0x64 };
|
static const u8 int_debounce_register_offset[3] = { 0xa8, 0xc4, 0x64 };
|
||||||
|
|
||||||
void ep93xx_gpio_update_int_params(unsigned port)
|
static void ep93xx_gpio_update_int_params(unsigned port)
|
||||||
{
|
{
|
||||||
BUG_ON(port > 2);
|
BUG_ON(port > 2);
|
||||||
|
|
||||||
|
@ -56,7 +56,7 @@ void ep93xx_gpio_update_int_params(unsigned port)
|
||||||
EP93XX_GPIO_REG(int_en_register_offset[port]));
|
EP93XX_GPIO_REG(int_en_register_offset[port]));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ep93xx_gpio_int_mask(unsigned line)
|
static inline void ep93xx_gpio_int_mask(unsigned line)
|
||||||
{
|
{
|
||||||
gpio_int_unmasked[line >> 3] &= ~(1 << (line & 7));
|
gpio_int_unmasked[line >> 3] &= ~(1 << (line & 7));
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,6 +62,15 @@ config MACH_MX31_3DS
|
||||||
Include support for MX31PDK (3DS) platform. This includes specific
|
Include support for MX31PDK (3DS) platform. This includes specific
|
||||||
configurations for the board and its peripherals.
|
configurations for the board and its peripherals.
|
||||||
|
|
||||||
|
config MACH_MX31_3DS_MXC_NAND_USE_BBT
|
||||||
|
bool "Make the MXC NAND driver use the in flash Bad Block Table"
|
||||||
|
depends on MACH_MX31_3DS
|
||||||
|
depends on MTD_NAND_MXC
|
||||||
|
help
|
||||||
|
Enable this if you want that the MXC NAND driver uses the in flash
|
||||||
|
Bad Block Table to know what blocks are bad instead of scanning the
|
||||||
|
entire flash looking for bad block markers.
|
||||||
|
|
||||||
config MACH_MX31MOBOARD
|
config MACH_MX31MOBOARD
|
||||||
bool "Support mx31moboard platforms (EPFL Mobots group)"
|
bool "Support mx31moboard platforms (EPFL Mobots group)"
|
||||||
select ARCH_MX31
|
select ARCH_MX31
|
||||||
|
@ -95,6 +104,7 @@ config MACH_PCM043
|
||||||
config MACH_ARMADILLO5X0
|
config MACH_ARMADILLO5X0
|
||||||
bool "Support Atmark Armadillo-500 Development Base Board"
|
bool "Support Atmark Armadillo-500 Development Base Board"
|
||||||
select ARCH_MX31
|
select ARCH_MX31
|
||||||
|
select MXC_ULPI if USB_ULPI
|
||||||
help
|
help
|
||||||
Include support for Atmark Armadillo-500 platform. This includes
|
Include support for Atmark Armadillo-500 platform. This includes
|
||||||
specific configurations for the board and its peripherals.
|
specific configurations for the board and its peripherals.
|
||||||
|
|
|
@ -468,6 +468,7 @@ static struct clk ahb_clk = {
|
||||||
}
|
}
|
||||||
|
|
||||||
DEFINE_CLOCK(perclk_clk, 0, NULL, 0, NULL, NULL, &ipg_clk);
|
DEFINE_CLOCK(perclk_clk, 0, NULL, 0, NULL, NULL, &ipg_clk);
|
||||||
|
DEFINE_CLOCK(ckil_clk, 0, NULL, 0, clk_ckil_get_rate, NULL, NULL);
|
||||||
|
|
||||||
DEFINE_CLOCK(sdhc1_clk, 0, MXC_CCM_CGR0, 0, NULL, NULL, &perclk_clk);
|
DEFINE_CLOCK(sdhc1_clk, 0, MXC_CCM_CGR0, 0, NULL, NULL, &perclk_clk);
|
||||||
DEFINE_CLOCK(sdhc2_clk, 1, MXC_CCM_CGR0, 2, NULL, NULL, &perclk_clk);
|
DEFINE_CLOCK(sdhc2_clk, 1, MXC_CCM_CGR0, 2, NULL, NULL, &perclk_clk);
|
||||||
|
@ -490,7 +491,7 @@ DEFINE_CLOCK(mpeg4_clk, 0, MXC_CCM_CGR1, 0, NULL, NULL, &ahb_clk);
|
||||||
DEFINE_CLOCK(mstick1_clk, 0, MXC_CCM_CGR1, 2, mstick1_get_rate, NULL, &usb_pll_clk);
|
DEFINE_CLOCK(mstick1_clk, 0, MXC_CCM_CGR1, 2, mstick1_get_rate, NULL, &usb_pll_clk);
|
||||||
DEFINE_CLOCK(mstick2_clk, 1, MXC_CCM_CGR1, 4, mstick2_get_rate, NULL, &usb_pll_clk);
|
DEFINE_CLOCK(mstick2_clk, 1, MXC_CCM_CGR1, 4, mstick2_get_rate, NULL, &usb_pll_clk);
|
||||||
DEFINE_CLOCK1(csi_clk, 0, MXC_CCM_CGR1, 6, csi, NULL, &serial_pll_clk);
|
DEFINE_CLOCK1(csi_clk, 0, MXC_CCM_CGR1, 6, csi, NULL, &serial_pll_clk);
|
||||||
DEFINE_CLOCK(rtc_clk, 0, MXC_CCM_CGR1, 8, NULL, NULL, &ipg_clk);
|
DEFINE_CLOCK(rtc_clk, 0, MXC_CCM_CGR1, 8, NULL, NULL, &ckil_clk);
|
||||||
DEFINE_CLOCK(wdog_clk, 0, MXC_CCM_CGR1, 10, NULL, NULL, &ipg_clk);
|
DEFINE_CLOCK(wdog_clk, 0, MXC_CCM_CGR1, 10, NULL, NULL, &ipg_clk);
|
||||||
DEFINE_CLOCK(pwm_clk, 0, MXC_CCM_CGR1, 12, NULL, NULL, &perclk_clk);
|
DEFINE_CLOCK(pwm_clk, 0, MXC_CCM_CGR1, 12, NULL, NULL, &perclk_clk);
|
||||||
DEFINE_CLOCK(usb_clk2, 0, MXC_CCM_CGR1, 18, usb_get_rate, NULL, &ahb_clk);
|
DEFINE_CLOCK(usb_clk2, 0, MXC_CCM_CGR1, 18, usb_get_rate, NULL, &ahb_clk);
|
||||||
|
@ -514,7 +515,6 @@ DEFINE_CLOCK(usb_clk1, 0, NULL, 0, usb_get_rate, NULL, &usb_pll_clk)
|
||||||
DEFINE_CLOCK(nfc_clk, 0, NULL, 0, nfc_get_rate, NULL, &ahb_clk);
|
DEFINE_CLOCK(nfc_clk, 0, NULL, 0, nfc_get_rate, NULL, &ahb_clk);
|
||||||
DEFINE_CLOCK(scc_clk, 0, NULL, 0, NULL, NULL, &ipg_clk);
|
DEFINE_CLOCK(scc_clk, 0, NULL, 0, NULL, NULL, &ipg_clk);
|
||||||
DEFINE_CLOCK(ipg_clk, 0, NULL, 0, ipg_get_rate, NULL, &ahb_clk);
|
DEFINE_CLOCK(ipg_clk, 0, NULL, 0, ipg_get_rate, NULL, &ahb_clk);
|
||||||
DEFINE_CLOCK(ckil_clk, 0, NULL, 0, clk_ckil_get_rate, NULL, NULL);
|
|
||||||
|
|
||||||
#define _REGISTER_CLOCK(d, n, c) \
|
#define _REGISTER_CLOCK(d, n, c) \
|
||||||
{ \
|
{ \
|
||||||
|
@ -572,7 +572,6 @@ static struct clk_lookup lookups[] = {
|
||||||
_REGISTER_CLOCK(NULL, "iim", iim_clk)
|
_REGISTER_CLOCK(NULL, "iim", iim_clk)
|
||||||
_REGISTER_CLOCK(NULL, "mpeg4", mpeg4_clk)
|
_REGISTER_CLOCK(NULL, "mpeg4", mpeg4_clk)
|
||||||
_REGISTER_CLOCK(NULL, "mbx", mbx_clk)
|
_REGISTER_CLOCK(NULL, "mbx", mbx_clk)
|
||||||
_REGISTER_CLOCK("mxc_rtc", NULL, ckil_clk)
|
|
||||||
};
|
};
|
||||||
|
|
||||||
int __init mx31_clocks_init(unsigned long fref)
|
int __init mx31_clocks_init(unsigned long fref)
|
||||||
|
|
|
@ -575,11 +575,26 @@ struct platform_device imx_ssi_device1 = {
|
||||||
.resource = imx_ssi_resources1,
|
.resource = imx_ssi_resources1,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int mx3_devices_init(void)
|
static struct resource imx_wdt_resources[] = {
|
||||||
|
{
|
||||||
|
.flags = IORESOURCE_MEM,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
struct platform_device imx_wdt_device0 = {
|
||||||
|
.name = "imx-wdt",
|
||||||
|
.id = 0,
|
||||||
|
.num_resources = ARRAY_SIZE(imx_wdt_resources),
|
||||||
|
.resource = imx_wdt_resources,
|
||||||
|
};
|
||||||
|
|
||||||
|
static int __init mx3_devices_init(void)
|
||||||
{
|
{
|
||||||
if (cpu_is_mx31()) {
|
if (cpu_is_mx31()) {
|
||||||
mxc_nand_resources[0].start = MX31_NFC_BASE_ADDR;
|
mxc_nand_resources[0].start = MX31_NFC_BASE_ADDR;
|
||||||
mxc_nand_resources[0].end = MX31_NFC_BASE_ADDR + 0xfff;
|
mxc_nand_resources[0].end = MX31_NFC_BASE_ADDR + 0xfff;
|
||||||
|
imx_wdt_resources[0].start = MX31_WDOG_BASE_ADDR;
|
||||||
|
imx_wdt_resources[0].end = MX31_WDOG_BASE_ADDR + 0x3fff;
|
||||||
mxc_register_device(&mxc_rnga_device, NULL);
|
mxc_register_device(&mxc_rnga_device, NULL);
|
||||||
}
|
}
|
||||||
if (cpu_is_mx35()) {
|
if (cpu_is_mx35()) {
|
||||||
|
@ -597,6 +612,8 @@ static int mx3_devices_init(void)
|
||||||
imx_ssi_resources0[1].end = MX35_INT_SSI1;
|
imx_ssi_resources0[1].end = MX35_INT_SSI1;
|
||||||
imx_ssi_resources1[1].start = MX35_INT_SSI2;
|
imx_ssi_resources1[1].start = MX35_INT_SSI2;
|
||||||
imx_ssi_resources1[1].end = MX35_INT_SSI2;
|
imx_ssi_resources1[1].end = MX35_INT_SSI2;
|
||||||
|
imx_wdt_resources[0].start = MX35_WDOG_BASE_ADDR;
|
||||||
|
imx_wdt_resources[0].end = MX35_WDOG_BASE_ADDR + 0x3fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -25,4 +25,5 @@ extern struct platform_device mxc_spi_device1;
|
||||||
extern struct platform_device mxc_spi_device2;
|
extern struct platform_device mxc_spi_device2;
|
||||||
extern struct platform_device imx_ssi_device0;
|
extern struct platform_device imx_ssi_device0;
|
||||||
extern struct platform_device imx_ssi_device1;
|
extern struct platform_device imx_ssi_device1;
|
||||||
|
extern struct platform_device imx_ssi_device1;
|
||||||
|
extern struct platform_device imx_wdt_device0;
|
||||||
|
|
|
@ -36,6 +36,9 @@
|
||||||
#include <linux/input.h>
|
#include <linux/input.h>
|
||||||
#include <linux/gpio_keys.h>
|
#include <linux/gpio_keys.h>
|
||||||
#include <linux/i2c.h>
|
#include <linux/i2c.h>
|
||||||
|
#include <linux/usb/otg.h>
|
||||||
|
#include <linux/usb/ulpi.h>
|
||||||
|
#include <linux/delay.h>
|
||||||
|
|
||||||
#include <mach/hardware.h>
|
#include <mach/hardware.h>
|
||||||
#include <asm/mach-types.h>
|
#include <asm/mach-types.h>
|
||||||
|
@ -52,6 +55,8 @@
|
||||||
#include <mach/ipu.h>
|
#include <mach/ipu.h>
|
||||||
#include <mach/mx3fb.h>
|
#include <mach/mx3fb.h>
|
||||||
#include <mach/mxc_nand.h>
|
#include <mach/mxc_nand.h>
|
||||||
|
#include <mach/mxc_ehci.h>
|
||||||
|
#include <mach/ulpi.h>
|
||||||
|
|
||||||
#include "devices.h"
|
#include "devices.h"
|
||||||
#include "crm_regs.h"
|
#include "crm_regs.h"
|
||||||
|
@ -103,8 +108,158 @@ static int armadillo5x0_pins[] = {
|
||||||
/* I2C2 */
|
/* I2C2 */
|
||||||
MX31_PIN_CSPI2_MOSI__SCL,
|
MX31_PIN_CSPI2_MOSI__SCL,
|
||||||
MX31_PIN_CSPI2_MISO__SDA,
|
MX31_PIN_CSPI2_MISO__SDA,
|
||||||
|
/* OTG */
|
||||||
|
MX31_PIN_USBOTG_DATA0__USBOTG_DATA0,
|
||||||
|
MX31_PIN_USBOTG_DATA1__USBOTG_DATA1,
|
||||||
|
MX31_PIN_USBOTG_DATA2__USBOTG_DATA2,
|
||||||
|
MX31_PIN_USBOTG_DATA3__USBOTG_DATA3,
|
||||||
|
MX31_PIN_USBOTG_DATA4__USBOTG_DATA4,
|
||||||
|
MX31_PIN_USBOTG_DATA5__USBOTG_DATA5,
|
||||||
|
MX31_PIN_USBOTG_DATA6__USBOTG_DATA6,
|
||||||
|
MX31_PIN_USBOTG_DATA7__USBOTG_DATA7,
|
||||||
|
MX31_PIN_USBOTG_CLK__USBOTG_CLK,
|
||||||
|
MX31_PIN_USBOTG_DIR__USBOTG_DIR,
|
||||||
|
MX31_PIN_USBOTG_NXT__USBOTG_NXT,
|
||||||
|
MX31_PIN_USBOTG_STP__USBOTG_STP,
|
||||||
|
/* USB host 2 */
|
||||||
|
IOMUX_MODE(MX31_PIN_USBH2_CLK, IOMUX_CONFIG_FUNC),
|
||||||
|
IOMUX_MODE(MX31_PIN_USBH2_DIR, IOMUX_CONFIG_FUNC),
|
||||||
|
IOMUX_MODE(MX31_PIN_USBH2_NXT, IOMUX_CONFIG_FUNC),
|
||||||
|
IOMUX_MODE(MX31_PIN_USBH2_STP, IOMUX_CONFIG_FUNC),
|
||||||
|
IOMUX_MODE(MX31_PIN_USBH2_DATA0, IOMUX_CONFIG_FUNC),
|
||||||
|
IOMUX_MODE(MX31_PIN_USBH2_DATA1, IOMUX_CONFIG_FUNC),
|
||||||
|
IOMUX_MODE(MX31_PIN_STXD3, IOMUX_CONFIG_FUNC),
|
||||||
|
IOMUX_MODE(MX31_PIN_SRXD3, IOMUX_CONFIG_FUNC),
|
||||||
|
IOMUX_MODE(MX31_PIN_SCK3, IOMUX_CONFIG_FUNC),
|
||||||
|
IOMUX_MODE(MX31_PIN_SFS3, IOMUX_CONFIG_FUNC),
|
||||||
|
IOMUX_MODE(MX31_PIN_STXD6, IOMUX_CONFIG_FUNC),
|
||||||
|
IOMUX_MODE(MX31_PIN_SRXD6, IOMUX_CONFIG_FUNC),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* USB */
|
||||||
|
#if defined(CONFIG_USB_ULPI)
|
||||||
|
|
||||||
|
#define OTG_RESET IOMUX_TO_GPIO(MX31_PIN_STXD4)
|
||||||
|
#define USBH2_RESET IOMUX_TO_GPIO(MX31_PIN_SCK6)
|
||||||
|
#define USBH2_CS IOMUX_TO_GPIO(MX31_PIN_GPIO1_3)
|
||||||
|
|
||||||
|
#define USB_PAD_CFG (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST | PAD_CTL_HYS_CMOS | \
|
||||||
|
PAD_CTL_ODE_CMOS | PAD_CTL_100K_PU)
|
||||||
|
|
||||||
|
static int usbotg_init(struct platform_device *pdev)
|
||||||
|
{
|
||||||
|
int err;
|
||||||
|
|
||||||
|
mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA0, USB_PAD_CFG);
|
||||||
|
mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA1, USB_PAD_CFG);
|
||||||
|
mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA2, USB_PAD_CFG);
|
||||||
|
mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA3, USB_PAD_CFG);
|
||||||
|
mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA4, USB_PAD_CFG);
|
||||||
|
mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA5, USB_PAD_CFG);
|
||||||
|
mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA6, USB_PAD_CFG);
|
||||||
|
mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA7, USB_PAD_CFG);
|
||||||
|
mxc_iomux_set_pad(MX31_PIN_USBOTG_CLK, USB_PAD_CFG);
|
||||||
|
mxc_iomux_set_pad(MX31_PIN_USBOTG_DIR, USB_PAD_CFG);
|
||||||
|
mxc_iomux_set_pad(MX31_PIN_USBOTG_NXT, USB_PAD_CFG);
|
||||||
|
mxc_iomux_set_pad(MX31_PIN_USBOTG_STP, USB_PAD_CFG);
|
||||||
|
|
||||||
|
/* Chip already enabled by hardware */
|
||||||
|
/* OTG phy reset*/
|
||||||
|
err = gpio_request(OTG_RESET, "USB-OTG-RESET");
|
||||||
|
if (err) {
|
||||||
|
pr_err("Failed to request the usb otg reset gpio\n");
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
err = gpio_direction_output(OTG_RESET, 1/*HIGH*/);
|
||||||
|
if (err) {
|
||||||
|
pr_err("Failed to reset the usb otg phy\n");
|
||||||
|
goto otg_free_reset;
|
||||||
|
}
|
||||||
|
|
||||||
|
gpio_set_value(OTG_RESET, 0/*LOW*/);
|
||||||
|
mdelay(5);
|
||||||
|
gpio_set_value(OTG_RESET, 1/*HIGH*/);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
otg_free_reset:
|
||||||
|
gpio_free(OTG_RESET);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int usbh2_init(struct platform_device *pdev)
|
||||||
|
{
|
||||||
|
int err;
|
||||||
|
|
||||||
|
mxc_iomux_set_pad(MX31_PIN_USBH2_CLK, USB_PAD_CFG);
|
||||||
|
mxc_iomux_set_pad(MX31_PIN_USBH2_DIR, USB_PAD_CFG);
|
||||||
|
mxc_iomux_set_pad(MX31_PIN_USBH2_NXT, USB_PAD_CFG);
|
||||||
|
mxc_iomux_set_pad(MX31_PIN_USBH2_STP, USB_PAD_CFG);
|
||||||
|
mxc_iomux_set_pad(MX31_PIN_USBH2_DATA0, USB_PAD_CFG);
|
||||||
|
mxc_iomux_set_pad(MX31_PIN_USBH2_DATA1, USB_PAD_CFG);
|
||||||
|
mxc_iomux_set_pad(MX31_PIN_SRXD6, USB_PAD_CFG);
|
||||||
|
mxc_iomux_set_pad(MX31_PIN_STXD6, USB_PAD_CFG);
|
||||||
|
mxc_iomux_set_pad(MX31_PIN_SFS3, USB_PAD_CFG);
|
||||||
|
mxc_iomux_set_pad(MX31_PIN_SCK3, USB_PAD_CFG);
|
||||||
|
mxc_iomux_set_pad(MX31_PIN_SRXD3, USB_PAD_CFG);
|
||||||
|
mxc_iomux_set_pad(MX31_PIN_STXD3, USB_PAD_CFG);
|
||||||
|
|
||||||
|
mxc_iomux_set_gpr(MUX_PGP_UH2, true);
|
||||||
|
|
||||||
|
|
||||||
|
/* Enable the chip */
|
||||||
|
err = gpio_request(USBH2_CS, "USB-H2-CS");
|
||||||
|
if (err) {
|
||||||
|
pr_err("Failed to request the usb host 2 CS gpio\n");
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
err = gpio_direction_output(USBH2_CS, 0/*Enabled*/);
|
||||||
|
if (err) {
|
||||||
|
pr_err("Failed to drive the usb host 2 CS gpio\n");
|
||||||
|
goto h2_free_cs;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* H2 phy reset*/
|
||||||
|
err = gpio_request(USBH2_RESET, "USB-H2-RESET");
|
||||||
|
if (err) {
|
||||||
|
pr_err("Failed to request the usb host 2 reset gpio\n");
|
||||||
|
goto h2_free_cs;
|
||||||
|
}
|
||||||
|
|
||||||
|
err = gpio_direction_output(USBH2_RESET, 1/*HIGH*/);
|
||||||
|
if (err) {
|
||||||
|
pr_err("Failed to reset the usb host 2 phy\n");
|
||||||
|
goto h2_free_reset;
|
||||||
|
}
|
||||||
|
|
||||||
|
gpio_set_value(USBH2_RESET, 0/*LOW*/);
|
||||||
|
mdelay(5);
|
||||||
|
gpio_set_value(USBH2_RESET, 1/*HIGH*/);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
h2_free_reset:
|
||||||
|
gpio_free(USBH2_RESET);
|
||||||
|
h2_free_cs:
|
||||||
|
gpio_free(USBH2_CS);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct mxc_usbh_platform_data usbotg_pdata = {
|
||||||
|
.init = usbotg_init,
|
||||||
|
.portsc = MXC_EHCI_MODE_ULPI | MXC_EHCI_UTMI_8BIT,
|
||||||
|
.flags = MXC_EHCI_POWER_PINS_ENABLED | MXC_EHCI_INTERFACE_DIFF_UNI,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct mxc_usbh_platform_data usbh2_pdata = {
|
||||||
|
.init = usbh2_init,
|
||||||
|
.portsc = MXC_EHCI_MODE_ULPI | MXC_EHCI_UTMI_8BIT,
|
||||||
|
.flags = MXC_EHCI_POWER_PINS_ENABLED | MXC_EHCI_INTERFACE_DIFF_UNI,
|
||||||
|
};
|
||||||
|
#endif /* CONFIG_USB_ULPI */
|
||||||
|
|
||||||
/* RTC over I2C*/
|
/* RTC over I2C*/
|
||||||
#define ARMADILLO5X0_RTC_GPIO IOMUX_TO_GPIO(MX31_PIN_SRXD4)
|
#define ARMADILLO5X0_RTC_GPIO IOMUX_TO_GPIO(MX31_PIN_SRXD4)
|
||||||
|
|
||||||
|
@ -393,6 +548,17 @@ static void __init armadillo5x0_init(void)
|
||||||
if (armadillo5x0_i2c_rtc.irq == 0)
|
if (armadillo5x0_i2c_rtc.irq == 0)
|
||||||
pr_warning("armadillo5x0_init: failed to get RTC IRQ\n");
|
pr_warning("armadillo5x0_init: failed to get RTC IRQ\n");
|
||||||
i2c_register_board_info(1, &armadillo5x0_i2c_rtc, 1);
|
i2c_register_board_info(1, &armadillo5x0_i2c_rtc, 1);
|
||||||
|
|
||||||
|
/* USB */
|
||||||
|
#if defined(CONFIG_USB_ULPI)
|
||||||
|
usbotg_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops,
|
||||||
|
USB_OTG_DRV_VBUS | USB_OTG_DRV_VBUS_EXT);
|
||||||
|
usbh2_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops,
|
||||||
|
USB_OTG_DRV_VBUS | USB_OTG_DRV_VBUS_EXT);
|
||||||
|
|
||||||
|
mxc_register_device(&mxc_otg_host, &usbotg_pdata);
|
||||||
|
mxc_register_device(&mxc_usbh2, &usbh2_pdata);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __init armadillo5x0_timer_init(void)
|
static void __init armadillo5x0_timer_init(void)
|
||||||
|
|
|
@ -23,6 +23,9 @@
|
||||||
#include <linux/gpio.h>
|
#include <linux/gpio.h>
|
||||||
#include <linux/smsc911x.h>
|
#include <linux/smsc911x.h>
|
||||||
#include <linux/platform_device.h>
|
#include <linux/platform_device.h>
|
||||||
|
#include <linux/mfd/mc13783.h>
|
||||||
|
#include <linux/spi/spi.h>
|
||||||
|
#include <linux/regulator/machine.h>
|
||||||
|
|
||||||
#include <mach/hardware.h>
|
#include <mach/hardware.h>
|
||||||
#include <asm/mach-types.h>
|
#include <asm/mach-types.h>
|
||||||
|
@ -31,26 +34,96 @@
|
||||||
#include <asm/memory.h>
|
#include <asm/memory.h>
|
||||||
#include <asm/mach/map.h>
|
#include <asm/mach/map.h>
|
||||||
#include <mach/common.h>
|
#include <mach/common.h>
|
||||||
#include <mach/board-mx31pdk.h>
|
#include <mach/board-mx31_3ds.h>
|
||||||
#include <mach/imx-uart.h>
|
#include <mach/imx-uart.h>
|
||||||
#include <mach/iomux-mx3.h>
|
#include <mach/iomux-mx3.h>
|
||||||
|
#include <mach/mxc_nand.h>
|
||||||
|
#include <mach/spi.h>
|
||||||
#include "devices.h"
|
#include "devices.h"
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* @file mx31pdk.c
|
* @file mx31_3ds.c
|
||||||
*
|
*
|
||||||
* @brief This file contains the board-specific initialization routines.
|
* @brief This file contains the board-specific initialization routines.
|
||||||
*
|
*
|
||||||
* @ingroup System
|
* @ingroup System
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static int mx31pdk_pins[] = {
|
static int mx31_3ds_pins[] = {
|
||||||
/* UART1 */
|
/* UART1 */
|
||||||
MX31_PIN_CTS1__CTS1,
|
MX31_PIN_CTS1__CTS1,
|
||||||
MX31_PIN_RTS1__RTS1,
|
MX31_PIN_RTS1__RTS1,
|
||||||
MX31_PIN_TXD1__TXD1,
|
MX31_PIN_TXD1__TXD1,
|
||||||
MX31_PIN_RXD1__RXD1,
|
MX31_PIN_RXD1__RXD1,
|
||||||
IOMUX_MODE(MX31_PIN_GPIO1_1, IOMUX_CONFIG_GPIO),
|
IOMUX_MODE(MX31_PIN_GPIO1_1, IOMUX_CONFIG_GPIO),
|
||||||
|
/* SPI 1 */
|
||||||
|
MX31_PIN_CSPI2_SCLK__SCLK,
|
||||||
|
MX31_PIN_CSPI2_MOSI__MOSI,
|
||||||
|
MX31_PIN_CSPI2_MISO__MISO,
|
||||||
|
MX31_PIN_CSPI2_SPI_RDY__SPI_RDY,
|
||||||
|
MX31_PIN_CSPI2_SS0__SS0,
|
||||||
|
MX31_PIN_CSPI2_SS2__SS2, /*CS for MC13783 */
|
||||||
|
/* MC13783 IRQ */
|
||||||
|
IOMUX_MODE(MX31_PIN_GPIO1_3, IOMUX_CONFIG_GPIO),
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Regulators */
|
||||||
|
static struct regulator_init_data pwgtx_init = {
|
||||||
|
.constraints = {
|
||||||
|
.boot_on = 1,
|
||||||
|
.always_on = 1,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct mc13783_regulator_init_data mx31_3ds_regulators[] = {
|
||||||
|
{
|
||||||
|
.id = MC13783_REGU_PWGT1SPI, /* Power Gate for ARM core. */
|
||||||
|
.init_data = &pwgtx_init,
|
||||||
|
}, {
|
||||||
|
.id = MC13783_REGU_PWGT2SPI, /* Power Gate for L2 Cache. */
|
||||||
|
.init_data = &pwgtx_init,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
/* MC13783 */
|
||||||
|
static struct mc13783_platform_data mc13783_pdata __initdata = {
|
||||||
|
.regulators = mx31_3ds_regulators,
|
||||||
|
.num_regulators = ARRAY_SIZE(mx31_3ds_regulators),
|
||||||
|
.flags = MC13783_USE_REGULATOR,
|
||||||
|
};
|
||||||
|
|
||||||
|
/* SPI */
|
||||||
|
static int spi1_internal_chipselect[] = {
|
||||||
|
MXC_SPI_CS(0),
|
||||||
|
MXC_SPI_CS(2),
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct spi_imx_master spi1_pdata = {
|
||||||
|
.chipselect = spi1_internal_chipselect,
|
||||||
|
.num_chipselect = ARRAY_SIZE(spi1_internal_chipselect),
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct spi_board_info mx31_3ds_spi_devs[] __initdata = {
|
||||||
|
{
|
||||||
|
.modalias = "mc13783",
|
||||||
|
.max_speed_hz = 1000000,
|
||||||
|
.bus_num = 1,
|
||||||
|
.chip_select = 1, /* SS2 */
|
||||||
|
.platform_data = &mc13783_pdata,
|
||||||
|
.irq = IOMUX_TO_IRQ(MX31_PIN_GPIO1_3),
|
||||||
|
.mode = SPI_CS_HIGH,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* NAND Flash
|
||||||
|
*/
|
||||||
|
static struct mxc_nand_platform_data imx31_3ds_nand_flash_pdata = {
|
||||||
|
.width = 1,
|
||||||
|
.hw_ecc = 1,
|
||||||
|
#ifdef MACH_MX31_3DS_MXC_NAND_USE_BBT
|
||||||
|
.flash_bbt = 1,
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct imxuart_platform_data uart_pdata = {
|
static struct imxuart_platform_data uart_pdata = {
|
||||||
|
@ -95,7 +168,7 @@ static struct platform_device smsc911x_device = {
|
||||||
* LEDs, switches, interrupts for Ethernet.
|
* LEDs, switches, interrupts for Ethernet.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void mx31pdk_expio_irq_handler(uint32_t irq, struct irq_desc *desc)
|
static void mx31_3ds_expio_irq_handler(uint32_t irq, struct irq_desc *desc)
|
||||||
{
|
{
|
||||||
uint32_t imr_val;
|
uint32_t imr_val;
|
||||||
uint32_t int_valid;
|
uint32_t int_valid;
|
||||||
|
@ -163,7 +236,7 @@ static struct irq_chip expio_irq_chip = {
|
||||||
.unmask = expio_unmask_irq,
|
.unmask = expio_unmask_irq,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int __init mx31pdk_init_expio(void)
|
static int __init mx31_3ds_init_expio(void)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
int ret;
|
int ret;
|
||||||
|
@ -176,7 +249,7 @@ static int __init mx31pdk_init_expio(void)
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
|
||||||
pr_info("i.MX31PDK Debug board detected, rev = 0x%04X\n",
|
pr_info("i.MX31 3DS Debug board detected, rev = 0x%04X\n",
|
||||||
__raw_readw(CPLD_CODE_VER_REG));
|
__raw_readw(CPLD_CODE_VER_REG));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -201,7 +274,7 @@ static int __init mx31pdk_init_expio(void)
|
||||||
set_irq_flags(i, IRQF_VALID);
|
set_irq_flags(i, IRQF_VALID);
|
||||||
}
|
}
|
||||||
set_irq_type(EXPIO_PARENT_INT, IRQ_TYPE_LEVEL_LOW);
|
set_irq_type(EXPIO_PARENT_INT, IRQ_TYPE_LEVEL_LOW);
|
||||||
set_irq_chained_handler(EXPIO_PARENT_INT, mx31pdk_expio_irq_handler);
|
set_irq_chained_handler(EXPIO_PARENT_INT, mx31_3ds_expio_irq_handler);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -209,7 +282,7 @@ static int __init mx31pdk_init_expio(void)
|
||||||
/*
|
/*
|
||||||
* This structure defines the MX31 memory map.
|
* This structure defines the MX31 memory map.
|
||||||
*/
|
*/
|
||||||
static struct map_desc mx31pdk_io_desc[] __initdata = {
|
static struct map_desc mx31_3ds_io_desc[] __initdata = {
|
||||||
{
|
{
|
||||||
.virtual = MX31_CS5_BASE_ADDR_VIRT,
|
.virtual = MX31_CS5_BASE_ADDR_VIRT,
|
||||||
.pfn = __phys_to_pfn(MX31_CS5_BASE_ADDR),
|
.pfn = __phys_to_pfn(MX31_CS5_BASE_ADDR),
|
||||||
|
@ -221,10 +294,10 @@ static struct map_desc mx31pdk_io_desc[] __initdata = {
|
||||||
/*
|
/*
|
||||||
* Set up static virtual mappings.
|
* Set up static virtual mappings.
|
||||||
*/
|
*/
|
||||||
static void __init mx31pdk_map_io(void)
|
static void __init mx31_3ds_map_io(void)
|
||||||
{
|
{
|
||||||
mx31_map_io();
|
mx31_map_io();
|
||||||
iotable_init(mx31pdk_io_desc, ARRAY_SIZE(mx31pdk_io_desc));
|
iotable_init(mx31_3ds_io_desc, ARRAY_SIZE(mx31_3ds_io_desc));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
@ -232,35 +305,40 @@ static void __init mx31pdk_map_io(void)
|
||||||
*/
|
*/
|
||||||
static void __init mxc_board_init(void)
|
static void __init mxc_board_init(void)
|
||||||
{
|
{
|
||||||
mxc_iomux_setup_multiple_pins(mx31pdk_pins, ARRAY_SIZE(mx31pdk_pins),
|
mxc_iomux_setup_multiple_pins(mx31_3ds_pins, ARRAY_SIZE(mx31_3ds_pins),
|
||||||
"mx31pdk");
|
"mx31_3ds");
|
||||||
|
|
||||||
mxc_register_device(&mxc_uart_device0, &uart_pdata);
|
mxc_register_device(&mxc_uart_device0, &uart_pdata);
|
||||||
|
mxc_register_device(&mxc_nand_device, &imx31_3ds_nand_flash_pdata);
|
||||||
|
|
||||||
if (!mx31pdk_init_expio())
|
mxc_register_device(&mxc_spi_device1, &spi1_pdata);
|
||||||
|
spi_register_board_info(mx31_3ds_spi_devs,
|
||||||
|
ARRAY_SIZE(mx31_3ds_spi_devs));
|
||||||
|
|
||||||
|
if (!mx31_3ds_init_expio())
|
||||||
platform_device_register(&smsc911x_device);
|
platform_device_register(&smsc911x_device);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __init mx31pdk_timer_init(void)
|
static void __init mx31_3ds_timer_init(void)
|
||||||
{
|
{
|
||||||
mx31_clocks_init(26000000);
|
mx31_clocks_init(26000000);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct sys_timer mx31pdk_timer = {
|
static struct sys_timer mx31_3ds_timer = {
|
||||||
.init = mx31pdk_timer_init,
|
.init = mx31_3ds_timer_init,
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The following uses standard kernel macros defined in arch.h in order to
|
* The following uses standard kernel macros defined in arch.h in order to
|
||||||
* initialize __mach_desc_MX31PDK data structure.
|
* initialize __mach_desc_MX31_3DS data structure.
|
||||||
*/
|
*/
|
||||||
MACHINE_START(MX31_3DS, "Freescale MX31PDK (3DS)")
|
MACHINE_START(MX31_3DS, "Freescale MX31PDK (3DS)")
|
||||||
/* Maintainer: Freescale Semiconductor, Inc. */
|
/* Maintainer: Freescale Semiconductor, Inc. */
|
||||||
.phys_io = MX31_AIPS1_BASE_ADDR,
|
.phys_io = MX31_AIPS1_BASE_ADDR,
|
||||||
.io_pg_offst = (MX31_AIPS1_BASE_ADDR_VIRT >> 18) & 0xfffc,
|
.io_pg_offst = (MX31_AIPS1_BASE_ADDR_VIRT >> 18) & 0xfffc,
|
||||||
.boot_params = MX3x_PHYS_OFFSET + 0x100,
|
.boot_params = MX3x_PHYS_OFFSET + 0x100,
|
||||||
.map_io = mx31pdk_map_io,
|
.map_io = mx31_3ds_map_io,
|
||||||
.init_irq = mx31_init_irq,
|
.init_irq = mx31_init_irq,
|
||||||
.init_machine = mxc_board_init,
|
.init_machine = mxc_board_init,
|
||||||
.timer = &mx31pdk_timer,
|
.timer = &mx31_3ds_timer,
|
||||||
MACHINE_END
|
MACHINE_END
|
||||||
|
|
|
@ -35,7 +35,6 @@
|
||||||
#include <linux/can/platform/sja1000.h>
|
#include <linux/can/platform/sja1000.h>
|
||||||
#include <linux/usb/otg.h>
|
#include <linux/usb/otg.h>
|
||||||
#include <linux/usb/ulpi.h>
|
#include <linux/usb/ulpi.h>
|
||||||
#include <linux/fsl_devices.h>
|
|
||||||
#include <linux/gfp.h>
|
#include <linux/gfp.h>
|
||||||
|
|
||||||
#include <media/soc_camera.h>
|
#include <media/soc_camera.h>
|
||||||
|
|
|
@ -28,7 +28,6 @@
|
||||||
#include <linux/types.h>
|
#include <linux/types.h>
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
#include <linux/gpio.h>
|
#include <linux/gpio.h>
|
||||||
#include <linux/platform_device.h>
|
|
||||||
#include <linux/leds.h>
|
#include <linux/leds.h>
|
||||||
#include <linux/platform_device.h>
|
#include <linux/platform_device.h>
|
||||||
|
|
||||||
|
@ -206,5 +205,6 @@ void __init mx31lite_db_init(void)
|
||||||
mxc_register_device(&mxcsdhc_device0, &mmc_pdata);
|
mxc_register_device(&mxcsdhc_device0, &mmc_pdata);
|
||||||
mxc_register_device(&mxc_spi_device0, &spi0_pdata);
|
mxc_register_device(&mxc_spi_device0, &spi0_pdata);
|
||||||
platform_device_register(&litekit_led_device);
|
platform_device_register(&litekit_led_device);
|
||||||
|
mxc_register_device(&imx_wdt_device0, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -757,7 +757,7 @@ DEFINE_CLOCK(uart3_ipg_clk, 2, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG7_OFFSET,
|
||||||
|
|
||||||
/* GPT */
|
/* GPT */
|
||||||
DEFINE_CLOCK(gpt_clk, 0, MXC_CCM_CCGR2, MXC_CCM_CCGRx_CG9_OFFSET,
|
DEFINE_CLOCK(gpt_clk, 0, MXC_CCM_CCGR2, MXC_CCM_CCGRx_CG9_OFFSET,
|
||||||
NULL, NULL, &ipg_perclk, NULL);
|
NULL, NULL, &ipg_clk, NULL);
|
||||||
DEFINE_CLOCK(gpt_ipg_clk, 0, MXC_CCM_CCGR2, MXC_CCM_CCGRx_CG10_OFFSET,
|
DEFINE_CLOCK(gpt_ipg_clk, 0, MXC_CCM_CCGR2, MXC_CCM_CCGRx_CG10_OFFSET,
|
||||||
NULL, NULL, &ipg_clk, NULL);
|
NULL, NULL, &ipg_clk, NULL);
|
||||||
|
|
||||||
|
|
|
@ -14,9 +14,62 @@
|
||||||
#include <linux/types.h>
|
#include <linux/types.h>
|
||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
|
#include <linux/module.h>
|
||||||
#include <mach/hardware.h>
|
#include <mach/hardware.h>
|
||||||
#include <asm/io.h>
|
#include <asm/io.h>
|
||||||
|
|
||||||
|
static int cpu_silicon_rev = -1;
|
||||||
|
|
||||||
|
#define SI_REV 0x48
|
||||||
|
|
||||||
|
static void query_silicon_parameter(void)
|
||||||
|
{
|
||||||
|
void __iomem *rom = ioremap(MX51_IROM_BASE_ADDR, MX51_IROM_SIZE);
|
||||||
|
u32 rev;
|
||||||
|
|
||||||
|
if (!rom) {
|
||||||
|
cpu_silicon_rev = -EINVAL;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
rev = readl(rom + SI_REV);
|
||||||
|
switch (rev) {
|
||||||
|
case 0x1:
|
||||||
|
cpu_silicon_rev = MX51_CHIP_REV_1_0;
|
||||||
|
break;
|
||||||
|
case 0x2:
|
||||||
|
cpu_silicon_rev = MX51_CHIP_REV_1_1;
|
||||||
|
break;
|
||||||
|
case 0x10:
|
||||||
|
cpu_silicon_rev = MX51_CHIP_REV_2_0;
|
||||||
|
break;
|
||||||
|
case 0x20:
|
||||||
|
cpu_silicon_rev = MX51_CHIP_REV_3_0;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
cpu_silicon_rev = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
iounmap(rom);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns:
|
||||||
|
* the silicon revision of the cpu
|
||||||
|
* -EINVAL - not a mx51
|
||||||
|
*/
|
||||||
|
int mx51_revision(void)
|
||||||
|
{
|
||||||
|
if (!cpu_is_mx51())
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
if (cpu_silicon_rev == -1)
|
||||||
|
query_silicon_parameter();
|
||||||
|
|
||||||
|
return cpu_silicon_rev;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(mx51_revision);
|
||||||
|
|
||||||
static int __init post_cpu_init(void)
|
static int __init post_cpu_init(void)
|
||||||
{
|
{
|
||||||
unsigned int reg;
|
unsigned int reg;
|
||||||
|
|
|
@ -34,11 +34,6 @@ static struct map_desc mxc_io_desc[] __initdata = {
|
||||||
.pfn = __phys_to_pfn(MX51_DEBUG_BASE_ADDR),
|
.pfn = __phys_to_pfn(MX51_DEBUG_BASE_ADDR),
|
||||||
.length = MX51_DEBUG_SIZE,
|
.length = MX51_DEBUG_SIZE,
|
||||||
.type = MT_DEVICE
|
.type = MT_DEVICE
|
||||||
}, {
|
|
||||||
.virtual = MX51_TZIC_BASE_ADDR_VIRT,
|
|
||||||
.pfn = __phys_to_pfn(MX51_TZIC_BASE_ADDR),
|
|
||||||
.length = MX51_TZIC_SIZE,
|
|
||||||
.type = MT_DEVICE
|
|
||||||
}, {
|
}, {
|
||||||
.virtual = MX51_AIPS1_BASE_ADDR_VIRT,
|
.virtual = MX51_AIPS1_BASE_ADDR_VIRT,
|
||||||
.pfn = __phys_to_pfn(MX51_AIPS1_BASE_ADDR),
|
.pfn = __phys_to_pfn(MX51_AIPS1_BASE_ADDR),
|
||||||
|
@ -54,11 +49,6 @@ static struct map_desc mxc_io_desc[] __initdata = {
|
||||||
.pfn = __phys_to_pfn(MX51_AIPS2_BASE_ADDR),
|
.pfn = __phys_to_pfn(MX51_AIPS2_BASE_ADDR),
|
||||||
.length = MX51_AIPS2_SIZE,
|
.length = MX51_AIPS2_SIZE,
|
||||||
.type = MT_DEVICE
|
.type = MT_DEVICE
|
||||||
}, {
|
|
||||||
.virtual = MX51_NFC_AXI_BASE_ADDR_VIRT,
|
|
||||||
.pfn = __phys_to_pfn(MX51_NFC_AXI_BASE_ADDR),
|
|
||||||
.length = MX51_NFC_AXI_SIZE,
|
|
||||||
.type = MT_DEVICE
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -69,14 +59,6 @@ static struct map_desc mxc_io_desc[] __initdata = {
|
||||||
*/
|
*/
|
||||||
void __init mx51_map_io(void)
|
void __init mx51_map_io(void)
|
||||||
{
|
{
|
||||||
u32 tzic_addr;
|
|
||||||
|
|
||||||
if (mx51_revision() < MX51_CHIP_REV_2_0)
|
|
||||||
tzic_addr = 0x8FFFC000;
|
|
||||||
else
|
|
||||||
tzic_addr = 0xE0003000;
|
|
||||||
mxc_io_desc[2].pfn = __phys_to_pfn(tzic_addr);
|
|
||||||
|
|
||||||
mxc_set_cpu_type(MXC_CPU_MX51);
|
mxc_set_cpu_type(MXC_CPU_MX51);
|
||||||
mxc_iomux_v3_init(MX51_IO_ADDRESS(MX51_IOMUXC_BASE_ADDR));
|
mxc_iomux_v3_init(MX51_IO_ADDRESS(MX51_IOMUXC_BASE_ADDR));
|
||||||
mxc_arch_reset_init(MX51_IO_ADDRESS(MX51_WDOG_BASE_ADDR));
|
mxc_arch_reset_init(MX51_IO_ADDRESS(MX51_WDOG_BASE_ADDR));
|
||||||
|
@ -85,5 +67,17 @@ void __init mx51_map_io(void)
|
||||||
|
|
||||||
void __init mx51_init_irq(void)
|
void __init mx51_init_irq(void)
|
||||||
{
|
{
|
||||||
tzic_init_irq(MX51_IO_ADDRESS(MX51_TZIC_BASE_ADDR));
|
unsigned long tzic_addr;
|
||||||
|
void __iomem *tzic_virt;
|
||||||
|
|
||||||
|
if (mx51_revision() < MX51_CHIP_REV_2_0)
|
||||||
|
tzic_addr = MX51_TZIC_BASE_ADDR_TO1;
|
||||||
|
else
|
||||||
|
tzic_addr = MX51_TZIC_BASE_ADDR;
|
||||||
|
|
||||||
|
tzic_virt = ioremap(tzic_addr, SZ_16K);
|
||||||
|
if (!tzic_virt)
|
||||||
|
panic("unable to map TZIC interrupt controller\n");
|
||||||
|
|
||||||
|
tzic_init_irq(tzic_virt);
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,13 +41,6 @@ static void v6_copy_user_highpage_nonaliasing(struct page *to,
|
||||||
kfrom = kmap_atomic(from, KM_USER0);
|
kfrom = kmap_atomic(from, KM_USER0);
|
||||||
kto = kmap_atomic(to, KM_USER1);
|
kto = kmap_atomic(to, KM_USER1);
|
||||||
copy_page(kto, kfrom);
|
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(kto, KM_USER1);
|
||||||
kunmap_atomic(kfrom, KM_USER0);
|
kunmap_atomic(kfrom, KM_USER0);
|
||||||
|
|
|
@ -464,6 +464,11 @@ static void dma_cache_maint_page(struct page *page, unsigned long offset,
|
||||||
vaddr += offset;
|
vaddr += offset;
|
||||||
op(vaddr, len, dir);
|
op(vaddr, len, dir);
|
||||||
kunmap_high(page);
|
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 {
|
} else {
|
||||||
vaddr = page_address(page) + offset;
|
vaddr = page_address(page) + offset;
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
|
|
||||||
#include <asm/cacheflush.h>
|
#include <asm/cacheflush.h>
|
||||||
#include <asm/cachetype.h>
|
#include <asm/cachetype.h>
|
||||||
|
#include <asm/highmem.h>
|
||||||
#include <asm/smp_plat.h>
|
#include <asm/smp_plat.h>
|
||||||
#include <asm/system.h>
|
#include <asm/system.h>
|
||||||
#include <asm/tlbflush.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 __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
|
* Writeback any data associated with the kernel mapping of this
|
||||||
* page. This ensures that data in the physical page is mutually
|
* page. This ensures that data in the physical page is mutually
|
||||||
* coherent with the kernels mapping.
|
* coherent with the kernels mapping.
|
||||||
*/
|
*/
|
||||||
#ifdef CONFIG_HIGHMEM
|
if (!PageHighMem(page)) {
|
||||||
/*
|
__cpuc_flush_dcache_area(page_address(page), PAGE_SIZE);
|
||||||
* kmap_atomic() doesn't set the page virtual address, and
|
} else {
|
||||||
* kunmap_atomic() takes care of cache flushing already.
|
void *addr = kmap_high_get(page);
|
||||||
*/
|
if (addr) {
|
||||||
if (addr)
|
|
||||||
#endif
|
|
||||||
__cpuc_flush_dcache_area(addr, PAGE_SIZE);
|
__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,
|
* If this is a page cache page, and we have an aliasing VIPT cache,
|
||||||
|
|
|
@ -79,6 +79,7 @@ void kunmap_atomic(void *kvaddr, enum km_type type)
|
||||||
unsigned int idx = type + KM_TYPE_NR * smp_processor_id();
|
unsigned int idx = type + KM_TYPE_NR * smp_processor_id();
|
||||||
|
|
||||||
if (kvaddr >= (void *)FIXADDR_START) {
|
if (kvaddr >= (void *)FIXADDR_START) {
|
||||||
|
if (cache_is_vivt())
|
||||||
__cpuc_flush_dcache_area((void *)vaddr, PAGE_SIZE);
|
__cpuc_flush_dcache_area((void *)vaddr, PAGE_SIZE);
|
||||||
#ifdef CONFIG_DEBUG_HIGHMEM
|
#ifdef CONFIG_DEBUG_HIGHMEM
|
||||||
BUG_ON(vaddr != __fix_to_virt(FIX_KMAP_BEGIN + idx));
|
BUG_ON(vaddr != __fix_to_virt(FIX_KMAP_BEGIN + idx));
|
||||||
|
@ -124,3 +125,87 @@ struct page *kmap_atomic_to_page(const void *ptr)
|
||||||
pte = TOP_PTE(vaddr);
|
pte = TOP_PTE(vaddr);
|
||||||
return pte_page(*pte);
|
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 */
|
||||||
|
|
|
@ -420,6 +420,10 @@ static void __init build_mem_type_table(void)
|
||||||
user_pgprot |= L_PTE_SHARED;
|
user_pgprot |= L_PTE_SHARED;
|
||||||
kern_pgprot |= L_PTE_SHARED;
|
kern_pgprot |= L_PTE_SHARED;
|
||||||
vecs_pgprot |= L_PTE_SHARED;
|
vecs_pgprot |= L_PTE_SHARED;
|
||||||
|
mem_types[MT_DEVICE_WC].prot_sect |= PMD_SECT_S;
|
||||||
|
mem_types[MT_DEVICE_WC].prot_pte |= L_PTE_SHARED;
|
||||||
|
mem_types[MT_DEVICE_CACHED].prot_sect |= PMD_SECT_S;
|
||||||
|
mem_types[MT_DEVICE_CACHED].prot_pte |= L_PTE_SHARED;
|
||||||
mem_types[MT_MEMORY].prot_sect |= PMD_SECT_S;
|
mem_types[MT_MEMORY].prot_sect |= PMD_SECT_S;
|
||||||
mem_types[MT_MEMORY_NONCACHED].prot_sect |= PMD_SECT_S;
|
mem_types[MT_MEMORY_NONCACHED].prot_sect |= PMD_SECT_S;
|
||||||
#endif
|
#endif
|
||||||
|
@ -1050,10 +1054,12 @@ void setup_mm_for_reboot(char mode)
|
||||||
pgd_t *pgd;
|
pgd_t *pgd;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (current->mm && current->mm->pgd)
|
/*
|
||||||
pgd = current->mm->pgd;
|
* We need to access to user-mode page tables here. For kernel threads
|
||||||
else
|
* we don't have any user-mode mappings so we use the context that we
|
||||||
pgd = init_mm.pgd;
|
* "borrowed".
|
||||||
|
*/
|
||||||
|
pgd = current->active_mm->pgd;
|
||||||
|
|
||||||
base_pmdval = PMD_SECT_AP_WRITE | PMD_SECT_AP_READ | PMD_TYPE_SECT;
|
base_pmdval = PMD_SECT_AP_WRITE | PMD_SECT_AP_READ | PMD_TYPE_SECT;
|
||||||
if (cpu_architecture() <= CPU_ARCH_ARMv5TEJ && !cpu_is_xscale())
|
if (cpu_architecture() <= CPU_ARCH_ARMv5TEJ && !cpu_is_xscale())
|
||||||
|
|
|
@ -8,8 +8,8 @@
|
||||||
* published by the Free Software Foundation.
|
* published by the Free Software Foundation.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __ASM_ARCH_MXC_BOARD_MX31PDK_H__
|
#ifndef __ASM_ARCH_MXC_BOARD_MX31_3DS_H__
|
||||||
#define __ASM_ARCH_MXC_BOARD_MX31PDK_H__
|
#define __ASM_ARCH_MXC_BOARD_MX31_3DS_H__
|
||||||
|
|
||||||
/* Definitions for components on the Debug board */
|
/* Definitions for components on the Debug board */
|
||||||
|
|
||||||
|
@ -56,4 +56,4 @@
|
||||||
|
|
||||||
#define MXC_MAX_EXP_IO_LINES 16
|
#define MXC_MAX_EXP_IO_LINES 16
|
||||||
|
|
||||||
#endif /* __ASM_ARCH_MXC_BOARD_MX31PDK_H__ */
|
#endif /* __ASM_ARCH_MXC_BOARD_MX31_3DS_H__ */
|
|
@ -14,7 +14,7 @@
|
||||||
* FB100000 70000000 1M SPBA 0
|
* FB100000 70000000 1M SPBA 0
|
||||||
* FB000000 73F00000 1M AIPS 1
|
* FB000000 73F00000 1M AIPS 1
|
||||||
* FB200000 83F00000 1M AIPS 2
|
* FB200000 83F00000 1M AIPS 2
|
||||||
* FA100000 8FFFC000 16K TZIC (interrupt controller)
|
* 8FFFC000 16K TZIC (interrupt controller)
|
||||||
* 90000000 256M CSD0 SDRAM/DDR
|
* 90000000 256M CSD0 SDRAM/DDR
|
||||||
* A0000000 256M CSD1 SDRAM/DDR
|
* A0000000 256M CSD1 SDRAM/DDR
|
||||||
* B0000000 128M CS0 Flash
|
* B0000000 128M CS0 Flash
|
||||||
|
@ -23,10 +23,16 @@
|
||||||
* C8000000 64M CS3 Flash
|
* C8000000 64M CS3 Flash
|
||||||
* CC000000 32M CS4 SRAM
|
* CC000000 32M CS4 SRAM
|
||||||
* CE000000 32M CS5 SRAM
|
* CE000000 32M CS5 SRAM
|
||||||
* F9000000 CFFF0000 64K NFC (NAND Flash AXI)
|
* CFFF0000 64K NFC (NAND Flash AXI)
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* IROM
|
||||||
|
*/
|
||||||
|
#define MX51_IROM_BASE_ADDR 0x0
|
||||||
|
#define MX51_IROM_SIZE SZ_64K
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* IRAM
|
* IRAM
|
||||||
*/
|
*/
|
||||||
|
@ -40,7 +46,6 @@
|
||||||
* NFC
|
* NFC
|
||||||
*/
|
*/
|
||||||
#define MX51_NFC_AXI_BASE_ADDR 0xCFFF0000 /* NAND flash AXI */
|
#define MX51_NFC_AXI_BASE_ADDR 0xCFFF0000 /* NAND flash AXI */
|
||||||
#define MX51_NFC_AXI_BASE_ADDR_VIRT 0xF9000000
|
|
||||||
#define MX51_NFC_AXI_SIZE SZ_64K
|
#define MX51_NFC_AXI_SIZE SZ_64K
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -49,9 +54,8 @@
|
||||||
#define MX51_GPU_BASE_ADDR 0x20000000
|
#define MX51_GPU_BASE_ADDR 0x20000000
|
||||||
#define MX51_GPU2D_BASE_ADDR 0xD0000000
|
#define MX51_GPU2D_BASE_ADDR 0xD0000000
|
||||||
|
|
||||||
#define MX51_TZIC_BASE_ADDR 0x8FFFC000
|
#define MX51_TZIC_BASE_ADDR_TO1 0x8FFFC000
|
||||||
#define MX51_TZIC_BASE_ADDR_VIRT 0xFA100000
|
#define MX51_TZIC_BASE_ADDR 0xE0000000
|
||||||
#define MX51_TZIC_SIZE SZ_16K
|
|
||||||
|
|
||||||
#define MX51_DEBUG_BASE_ADDR 0x60000000
|
#define MX51_DEBUG_BASE_ADDR 0x60000000
|
||||||
#define MX51_DEBUG_BASE_ADDR_VIRT 0xFA200000
|
#define MX51_DEBUG_BASE_ADDR_VIRT 0xFA200000
|
||||||
|
@ -232,12 +236,10 @@
|
||||||
#define MX51_IO_ADDRESS(x) \
|
#define MX51_IO_ADDRESS(x) \
|
||||||
(void __iomem *) \
|
(void __iomem *) \
|
||||||
(MX51_IS_MODULE(x, IRAM) ? MX51_IRAM_IO_ADDRESS(x) : \
|
(MX51_IS_MODULE(x, IRAM) ? MX51_IRAM_IO_ADDRESS(x) : \
|
||||||
MX51_IS_MODULE(x, TZIC) ? MX51_TZIC_IO_ADDRESS(x) : \
|
|
||||||
MX51_IS_MODULE(x, DEBUG) ? MX51_DEBUG_IO_ADDRESS(x) : \
|
MX51_IS_MODULE(x, DEBUG) ? MX51_DEBUG_IO_ADDRESS(x) : \
|
||||||
MX51_IS_MODULE(x, SPBA0) ? MX51_SPBA0_IO_ADDRESS(x) : \
|
MX51_IS_MODULE(x, SPBA0) ? MX51_SPBA0_IO_ADDRESS(x) : \
|
||||||
MX51_IS_MODULE(x, AIPS1) ? MX51_AIPS1_IO_ADDRESS(x) : \
|
MX51_IS_MODULE(x, AIPS1) ? MX51_AIPS1_IO_ADDRESS(x) : \
|
||||||
MX51_IS_MODULE(x, AIPS2) ? MX51_AIPS2_IO_ADDRESS(x) : \
|
MX51_IS_MODULE(x, AIPS2) ? MX51_AIPS2_IO_ADDRESS(x) : \
|
||||||
MX51_IS_MODULE(x, NFC_AXI) ? MX51_NFC_AXI_IO_ADDRESS(x) : \
|
|
||||||
0xDEADBEEF)
|
0xDEADBEEF)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -246,9 +248,6 @@
|
||||||
#define MX51_IRAM_IO_ADDRESS(x) \
|
#define MX51_IRAM_IO_ADDRESS(x) \
|
||||||
(((x) - MX51_IRAM_BASE_ADDR) + MX51_IRAM_BASE_ADDR_VIRT)
|
(((x) - MX51_IRAM_BASE_ADDR) + MX51_IRAM_BASE_ADDR_VIRT)
|
||||||
|
|
||||||
#define MX51_TZIC_IO_ADDRESS(x) \
|
|
||||||
(((x) - MX51_TZIC_BASE_ADDR) + MX51_TZIC_BASE_ADDR_VIRT)
|
|
||||||
|
|
||||||
#define MX51_DEBUG_IO_ADDRESS(x) \
|
#define MX51_DEBUG_IO_ADDRESS(x) \
|
||||||
(((x) - MX51_DEBUG_BASE_ADDR) + MX51_DEBUG_BASE_ADDR_VIRT)
|
(((x) - MX51_DEBUG_BASE_ADDR) + MX51_DEBUG_BASE_ADDR_VIRT)
|
||||||
|
|
||||||
|
@ -261,9 +260,6 @@
|
||||||
#define MX51_AIPS2_IO_ADDRESS(x) \
|
#define MX51_AIPS2_IO_ADDRESS(x) \
|
||||||
(((x) - MX51_AIPS2_BASE_ADDR) + MX51_AIPS2_BASE_ADDR_VIRT)
|
(((x) - MX51_AIPS2_BASE_ADDR) + MX51_AIPS2_BASE_ADDR_VIRT)
|
||||||
|
|
||||||
#define MX51_NFC_AXI_IO_ADDRESS(x) \
|
|
||||||
(((x) - MX51_NFC_AXI_BASE_ADDR) + MX51_NFC_AXI_BASE_ADDR_VIRT)
|
|
||||||
|
|
||||||
#define MX51_IS_MEM_DEVICE_NONSHARED(x) 0
|
#define MX51_IS_MEM_DEVICE_NONSHARED(x) 0
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -443,12 +439,7 @@
|
||||||
|
|
||||||
#if !defined(__ASSEMBLY__) && !defined(__MXC_BOOT_UNCOMPRESS)
|
#if !defined(__ASSEMBLY__) && !defined(__MXC_BOOT_UNCOMPRESS)
|
||||||
|
|
||||||
extern unsigned int system_rev;
|
extern int mx51_revision(void);
|
||||||
|
|
||||||
static inline unsigned int mx51_revision(void)
|
|
||||||
{
|
|
||||||
return system_rev;
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* __ASM_ARCH_MXC_MX51_H__ */
|
#endif /* __ASM_ARCH_MXC_MX51_H__ */
|
||||||
|
|
|
@ -66,6 +66,7 @@ static inline void flush(void)
|
||||||
#define MX2X_UART1_BASE_ADDR 0x1000a000
|
#define MX2X_UART1_BASE_ADDR 0x1000a000
|
||||||
#define MX3X_UART1_BASE_ADDR 0x43F90000
|
#define MX3X_UART1_BASE_ADDR 0x43F90000
|
||||||
#define MX3X_UART2_BASE_ADDR 0x43F94000
|
#define MX3X_UART2_BASE_ADDR 0x43F94000
|
||||||
|
#define MX51_UART1_BASE_ADDR 0x73fbc000
|
||||||
|
|
||||||
static __inline__ void __arch_decomp_setup(unsigned long arch_id)
|
static __inline__ void __arch_decomp_setup(unsigned long arch_id)
|
||||||
{
|
{
|
||||||
|
@ -101,6 +102,9 @@ static __inline__ void __arch_decomp_setup(unsigned long arch_id)
|
||||||
case MACH_TYPE_MAGX_ZN5:
|
case MACH_TYPE_MAGX_ZN5:
|
||||||
uart_base = MX3X_UART2_BASE_ADDR;
|
uart_base = MX3X_UART2_BASE_ADDR;
|
||||||
break;
|
break;
|
||||||
|
case MACH_TYPE_MX51_BABBAGE:
|
||||||
|
uart_base = MX51_UART1_BASE_ADDR;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -428,26 +428,6 @@ static void vfp_pm_init(void)
|
||||||
static inline void vfp_pm_init(void) { }
|
static inline void vfp_pm_init(void) { }
|
||||||
#endif /* CONFIG_PM */
|
#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)
|
void vfp_sync_hwstate(struct thread_info *thread)
|
||||||
{
|
{
|
||||||
unsigned int cpu = get_cpu();
|
unsigned int cpu = get_cpu();
|
||||||
|
@ -490,9 +470,18 @@ void vfp_flush_hwstate(struct thread_info *thread)
|
||||||
last_VFP_context[cpu] = NULL;
|
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();
|
put_cpu();
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <linux/smp.h>
|
#include <linux/smp.h>
|
||||||
|
|
||||||
|
|
|
@ -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)
|
static inline int atomic_sub_and_test(int i, atomic_t *v)
|
||||||
{
|
{
|
||||||
char c;
|
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;
|
return c != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int atomic_add_negative(int i, atomic_t *v)
|
static inline int atomic_add_negative(int i, atomic_t *v)
|
||||||
{
|
{
|
||||||
char c;
|
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;
|
return c != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,13 +17,11 @@ struct sigcontext {
|
||||||
#ifndef __uClinux__
|
#ifndef __uClinux__
|
||||||
# ifdef __mcoldfire__
|
# ifdef __mcoldfire__
|
||||||
unsigned long sc_fpregs[2][2]; /* room for two fp registers */
|
unsigned long sc_fpregs[2][2]; /* room for two fp registers */
|
||||||
unsigned long sc_fpcntl[3];
|
|
||||||
unsigned char sc_fpstate[16+6*8];
|
|
||||||
# else
|
# else
|
||||||
unsigned long sc_fpregs[2*3]; /* room for two fp registers */
|
unsigned long sc_fpregs[2*3]; /* room for two fp registers */
|
||||||
|
# endif
|
||||||
unsigned long sc_fpcntl[3];
|
unsigned long sc_fpcntl[3];
|
||||||
unsigned char sc_fpstate[216];
|
unsigned char sc_fpstate[216];
|
||||||
# endif
|
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -60,43 +60,6 @@ void __init board_setup(void)
|
||||||
wmb();
|
wmb();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* use the hexleds to count the number of times the cpu has entered
|
|
||||||
* wait, the dots to indicate whether the CPU is currently idle or
|
|
||||||
* active (dots off = sleeping, dots on = working) for cases where
|
|
||||||
* the number doesn't change for a long(er) period of time.
|
|
||||||
*/
|
|
||||||
static void db1200_wait(void)
|
|
||||||
{
|
|
||||||
__asm__(" .set push \n"
|
|
||||||
" .set mips3 \n"
|
|
||||||
" .set noreorder \n"
|
|
||||||
" cache 0x14, 0(%0) \n"
|
|
||||||
" cache 0x14, 32(%0) \n"
|
|
||||||
" cache 0x14, 64(%0) \n"
|
|
||||||
/* dots off: we're about to call wait */
|
|
||||||
" lui $26, 0xb980 \n"
|
|
||||||
" ori $27, $0, 3 \n"
|
|
||||||
" sb $27, 0x18($26) \n"
|
|
||||||
" sync \n"
|
|
||||||
" nop \n"
|
|
||||||
" wait \n"
|
|
||||||
" nop \n"
|
|
||||||
" nop \n"
|
|
||||||
" nop \n"
|
|
||||||
" nop \n"
|
|
||||||
" nop \n"
|
|
||||||
/* dots on: there's work to do, increment cntr */
|
|
||||||
" lui $26, 0xb980 \n"
|
|
||||||
" sb $0, 0x18($26) \n"
|
|
||||||
" lui $26, 0xb9c0 \n"
|
|
||||||
" lb $27, 0($26) \n"
|
|
||||||
" addiu $27, $27, 1 \n"
|
|
||||||
" sb $27, 0($26) \n"
|
|
||||||
" sync \n"
|
|
||||||
" .set pop \n"
|
|
||||||
: : "r" (db1200_wait));
|
|
||||||
}
|
|
||||||
|
|
||||||
static int __init db1200_arch_init(void)
|
static int __init db1200_arch_init(void)
|
||||||
{
|
{
|
||||||
/* GPIO7 is low-level triggered CPLD cascade */
|
/* GPIO7 is low-level triggered CPLD cascade */
|
||||||
|
@ -110,9 +73,6 @@ static int __init db1200_arch_init(void)
|
||||||
irq_to_desc(DB1200_SD0_INSERT_INT)->status |= IRQ_NOAUTOEN;
|
irq_to_desc(DB1200_SD0_INSERT_INT)->status |= IRQ_NOAUTOEN;
|
||||||
irq_to_desc(DB1200_SD0_EJECT_INT)->status |= IRQ_NOAUTOEN;
|
irq_to_desc(DB1200_SD0_EJECT_INT)->status |= IRQ_NOAUTOEN;
|
||||||
|
|
||||||
if (cpu_wait)
|
|
||||||
cpu_wait = db1200_wait;
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
arch_initcall(db1200_arch_init);
|
arch_initcall(db1200_arch_init);
|
||||||
|
|
|
@ -168,7 +168,7 @@ static struct plat_vlynq_data vlynq_high_data = {
|
||||||
.on = vlynq_on,
|
.on = vlynq_on,
|
||||||
.off = vlynq_off,
|
.off = vlynq_off,
|
||||||
},
|
},
|
||||||
.reset_bit = 26,
|
.reset_bit = 16,
|
||||||
.gpio_bit = 19,
|
.gpio_bit = 19,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -600,6 +600,7 @@ static int __init ar7_register_devices(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ar7_has_high_cpmac()) {
|
if (ar7_has_high_cpmac()) {
|
||||||
|
res = fixed_phy_add(PHY_POLL, cpmac_high.id, &fixed_phy_status);
|
||||||
if (!res) {
|
if (!res) {
|
||||||
cpmac_get_mac(1, cpmac_high_data.dev_addr);
|
cpmac_get_mac(1, cpmac_high_data.dev_addr);
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
#include <asm/addrspace.h>
|
#include <asm/addrspace.h>
|
||||||
#include <bcm63xx_board.h>
|
#include <bcm63xx_board.h>
|
||||||
#include <bcm63xx_cpu.h>
|
#include <bcm63xx_cpu.h>
|
||||||
|
#include <bcm63xx_dev_uart.h>
|
||||||
#include <bcm63xx_regs.h>
|
#include <bcm63xx_regs.h>
|
||||||
#include <bcm63xx_io.h>
|
#include <bcm63xx_io.h>
|
||||||
#include <bcm63xx_dev_pci.h>
|
#include <bcm63xx_dev_pci.h>
|
||||||
|
@ -40,6 +41,7 @@ static struct board_info __initdata board_96338gw = {
|
||||||
.name = "96338GW",
|
.name = "96338GW",
|
||||||
.expected_cpu_id = 0x6338,
|
.expected_cpu_id = 0x6338,
|
||||||
|
|
||||||
|
.has_uart0 = 1,
|
||||||
.has_enet0 = 1,
|
.has_enet0 = 1,
|
||||||
.enet0 = {
|
.enet0 = {
|
||||||
.force_speed_100 = 1,
|
.force_speed_100 = 1,
|
||||||
|
@ -82,6 +84,7 @@ static struct board_info __initdata board_96338w = {
|
||||||
.name = "96338W",
|
.name = "96338W",
|
||||||
.expected_cpu_id = 0x6338,
|
.expected_cpu_id = 0x6338,
|
||||||
|
|
||||||
|
.has_uart0 = 1,
|
||||||
.has_enet0 = 1,
|
.has_enet0 = 1,
|
||||||
.enet0 = {
|
.enet0 = {
|
||||||
.force_speed_100 = 1,
|
.force_speed_100 = 1,
|
||||||
|
@ -126,6 +129,8 @@ static struct board_info __initdata board_96338w = {
|
||||||
static struct board_info __initdata board_96345gw2 = {
|
static struct board_info __initdata board_96345gw2 = {
|
||||||
.name = "96345GW2",
|
.name = "96345GW2",
|
||||||
.expected_cpu_id = 0x6345,
|
.expected_cpu_id = 0x6345,
|
||||||
|
|
||||||
|
.has_uart0 = 1,
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -137,6 +142,7 @@ static struct board_info __initdata board_96348r = {
|
||||||
.name = "96348R",
|
.name = "96348R",
|
||||||
.expected_cpu_id = 0x6348,
|
.expected_cpu_id = 0x6348,
|
||||||
|
|
||||||
|
.has_uart0 = 1,
|
||||||
.has_enet0 = 1,
|
.has_enet0 = 1,
|
||||||
.has_pci = 1,
|
.has_pci = 1,
|
||||||
|
|
||||||
|
@ -180,6 +186,7 @@ static struct board_info __initdata board_96348gw_10 = {
|
||||||
.name = "96348GW-10",
|
.name = "96348GW-10",
|
||||||
.expected_cpu_id = 0x6348,
|
.expected_cpu_id = 0x6348,
|
||||||
|
|
||||||
|
.has_uart0 = 1,
|
||||||
.has_enet0 = 1,
|
.has_enet0 = 1,
|
||||||
.has_enet1 = 1,
|
.has_enet1 = 1,
|
||||||
.has_pci = 1,
|
.has_pci = 1,
|
||||||
|
@ -239,6 +246,7 @@ static struct board_info __initdata board_96348gw_11 = {
|
||||||
.name = "96348GW-11",
|
.name = "96348GW-11",
|
||||||
.expected_cpu_id = 0x6348,
|
.expected_cpu_id = 0x6348,
|
||||||
|
|
||||||
|
.has_uart0 = 1,
|
||||||
.has_enet0 = 1,
|
.has_enet0 = 1,
|
||||||
.has_enet1 = 1,
|
.has_enet1 = 1,
|
||||||
.has_pci = 1,
|
.has_pci = 1,
|
||||||
|
@ -292,6 +300,7 @@ static struct board_info __initdata board_96348gw = {
|
||||||
.name = "96348GW",
|
.name = "96348GW",
|
||||||
.expected_cpu_id = 0x6348,
|
.expected_cpu_id = 0x6348,
|
||||||
|
|
||||||
|
.has_uart0 = 1,
|
||||||
.has_enet0 = 1,
|
.has_enet0 = 1,
|
||||||
.has_enet1 = 1,
|
.has_enet1 = 1,
|
||||||
.has_pci = 1,
|
.has_pci = 1,
|
||||||
|
@ -349,6 +358,7 @@ static struct board_info __initdata board_FAST2404 = {
|
||||||
.name = "F@ST2404",
|
.name = "F@ST2404",
|
||||||
.expected_cpu_id = 0x6348,
|
.expected_cpu_id = 0x6348,
|
||||||
|
|
||||||
|
.has_uart0 = 1,
|
||||||
.has_enet0 = 1,
|
.has_enet0 = 1,
|
||||||
.has_enet1 = 1,
|
.has_enet1 = 1,
|
||||||
.has_pci = 1,
|
.has_pci = 1,
|
||||||
|
@ -368,10 +378,30 @@ static struct board_info __initdata board_FAST2404 = {
|
||||||
.has_ehci0 = 1,
|
.has_ehci0 = 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static struct board_info __initdata board_rta1025w_16 = {
|
||||||
|
.name = "RTA1025W_16",
|
||||||
|
.expected_cpu_id = 0x6348,
|
||||||
|
|
||||||
|
.has_enet0 = 1,
|
||||||
|
.has_enet1 = 1,
|
||||||
|
.has_pci = 1,
|
||||||
|
|
||||||
|
.enet0 = {
|
||||||
|
.has_phy = 1,
|
||||||
|
.use_internal_phy = 1,
|
||||||
|
},
|
||||||
|
.enet1 = {
|
||||||
|
.force_speed_100 = 1,
|
||||||
|
.force_duplex_full = 1,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
static struct board_info __initdata board_DV201AMR = {
|
static struct board_info __initdata board_DV201AMR = {
|
||||||
.name = "DV201AMR",
|
.name = "DV201AMR",
|
||||||
.expected_cpu_id = 0x6348,
|
.expected_cpu_id = 0x6348,
|
||||||
|
|
||||||
|
.has_uart0 = 1,
|
||||||
.has_pci = 1,
|
.has_pci = 1,
|
||||||
.has_ohci0 = 1,
|
.has_ohci0 = 1,
|
||||||
|
|
||||||
|
@ -391,6 +421,7 @@ static struct board_info __initdata board_96348gw_a = {
|
||||||
.name = "96348GW-A",
|
.name = "96348GW-A",
|
||||||
.expected_cpu_id = 0x6348,
|
.expected_cpu_id = 0x6348,
|
||||||
|
|
||||||
|
.has_uart0 = 1,
|
||||||
.has_enet0 = 1,
|
.has_enet0 = 1,
|
||||||
.has_enet1 = 1,
|
.has_enet1 = 1,
|
||||||
.has_pci = 1,
|
.has_pci = 1,
|
||||||
|
@ -416,6 +447,7 @@ static struct board_info __initdata board_96358vw = {
|
||||||
.name = "96358VW",
|
.name = "96358VW",
|
||||||
.expected_cpu_id = 0x6358,
|
.expected_cpu_id = 0x6358,
|
||||||
|
|
||||||
|
.has_uart0 = 1,
|
||||||
.has_enet0 = 1,
|
.has_enet0 = 1,
|
||||||
.has_enet1 = 1,
|
.has_enet1 = 1,
|
||||||
.has_pci = 1,
|
.has_pci = 1,
|
||||||
|
@ -467,6 +499,7 @@ static struct board_info __initdata board_96358vw2 = {
|
||||||
.name = "96358VW2",
|
.name = "96358VW2",
|
||||||
.expected_cpu_id = 0x6358,
|
.expected_cpu_id = 0x6358,
|
||||||
|
|
||||||
|
.has_uart0 = 1,
|
||||||
.has_enet0 = 1,
|
.has_enet0 = 1,
|
||||||
.has_enet1 = 1,
|
.has_enet1 = 1,
|
||||||
.has_pci = 1,
|
.has_pci = 1,
|
||||||
|
@ -514,6 +547,7 @@ static struct board_info __initdata board_AGPFS0 = {
|
||||||
.name = "AGPF-S0",
|
.name = "AGPF-S0",
|
||||||
.expected_cpu_id = 0x6358,
|
.expected_cpu_id = 0x6358,
|
||||||
|
|
||||||
|
.has_uart0 = 1,
|
||||||
.has_enet0 = 1,
|
.has_enet0 = 1,
|
||||||
.has_enet1 = 1,
|
.has_enet1 = 1,
|
||||||
.has_pci = 1,
|
.has_pci = 1,
|
||||||
|
@ -531,6 +565,27 @@ static struct board_info __initdata board_AGPFS0 = {
|
||||||
.has_ohci0 = 1,
|
.has_ohci0 = 1,
|
||||||
.has_ehci0 = 1,
|
.has_ehci0 = 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static struct board_info __initdata board_DWVS0 = {
|
||||||
|
.name = "DWV-S0",
|
||||||
|
.expected_cpu_id = 0x6358,
|
||||||
|
|
||||||
|
.has_enet0 = 1,
|
||||||
|
.has_enet1 = 1,
|
||||||
|
.has_pci = 1,
|
||||||
|
|
||||||
|
.enet0 = {
|
||||||
|
.has_phy = 1,
|
||||||
|
.use_internal_phy = 1,
|
||||||
|
},
|
||||||
|
|
||||||
|
.enet1 = {
|
||||||
|
.force_speed_100 = 1,
|
||||||
|
.force_duplex_full = 1,
|
||||||
|
},
|
||||||
|
|
||||||
|
.has_ohci0 = 1,
|
||||||
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -552,15 +607,87 @@ static const struct board_info __initdata *bcm963xx_boards[] = {
|
||||||
&board_FAST2404,
|
&board_FAST2404,
|
||||||
&board_DV201AMR,
|
&board_DV201AMR,
|
||||||
&board_96348gw_a,
|
&board_96348gw_a,
|
||||||
|
&board_rta1025w_16,
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_BCM63XX_CPU_6358
|
#ifdef CONFIG_BCM63XX_CPU_6358
|
||||||
&board_96358vw,
|
&board_96358vw,
|
||||||
&board_96358vw2,
|
&board_96358vw2,
|
||||||
&board_AGPFS0,
|
&board_AGPFS0,
|
||||||
|
&board_DWVS0,
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Register a sane SPROMv2 to make the on-board
|
||||||
|
* bcm4318 WLAN work
|
||||||
|
*/
|
||||||
|
#ifdef CONFIG_SSB_PCIHOST
|
||||||
|
static struct ssb_sprom bcm63xx_sprom = {
|
||||||
|
.revision = 0x02,
|
||||||
|
.board_rev = 0x17,
|
||||||
|
.country_code = 0x0,
|
||||||
|
.ant_available_bg = 0x3,
|
||||||
|
.pa0b0 = 0x15ae,
|
||||||
|
.pa0b1 = 0xfa85,
|
||||||
|
.pa0b2 = 0xfe8d,
|
||||||
|
.pa1b0 = 0xffff,
|
||||||
|
.pa1b1 = 0xffff,
|
||||||
|
.pa1b2 = 0xffff,
|
||||||
|
.gpio0 = 0xff,
|
||||||
|
.gpio1 = 0xff,
|
||||||
|
.gpio2 = 0xff,
|
||||||
|
.gpio3 = 0xff,
|
||||||
|
.maxpwr_bg = 0x004c,
|
||||||
|
.itssi_bg = 0x00,
|
||||||
|
.boardflags_lo = 0x2848,
|
||||||
|
.boardflags_hi = 0x0000,
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* return board name for /proc/cpuinfo
|
||||||
|
*/
|
||||||
|
const char *board_get_name(void)
|
||||||
|
{
|
||||||
|
return board.name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* register & return a new board mac address
|
||||||
|
*/
|
||||||
|
static int board_get_mac_address(u8 *mac)
|
||||||
|
{
|
||||||
|
u8 *p;
|
||||||
|
int count;
|
||||||
|
|
||||||
|
if (mac_addr_used >= nvram.mac_addr_count) {
|
||||||
|
printk(KERN_ERR PFX "not enough mac address\n");
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(mac, nvram.mac_addr_base, ETH_ALEN);
|
||||||
|
p = mac + ETH_ALEN - 1;
|
||||||
|
count = mac_addr_used;
|
||||||
|
|
||||||
|
while (count--) {
|
||||||
|
do {
|
||||||
|
(*p)++;
|
||||||
|
if (*p != 0)
|
||||||
|
break;
|
||||||
|
p--;
|
||||||
|
} while (p != mac);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (p == mac) {
|
||||||
|
printk(KERN_ERR PFX "unable to fetch mac address\n");
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
|
mac_addr_used++;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* early init callback, read nvram data from flash and checksum it
|
* early init callback, read nvram data from flash and checksum it
|
||||||
*/
|
*/
|
||||||
|
@ -659,6 +786,17 @@ void __init board_prom_init(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
bcm_gpio_writel(val, GPIO_MODE_REG);
|
bcm_gpio_writel(val, GPIO_MODE_REG);
|
||||||
|
|
||||||
|
/* Generate MAC address for WLAN and
|
||||||
|
* register our SPROM */
|
||||||
|
#ifdef CONFIG_SSB_PCIHOST
|
||||||
|
if (!board_get_mac_address(bcm63xx_sprom.il0mac)) {
|
||||||
|
memcpy(bcm63xx_sprom.et0mac, bcm63xx_sprom.il0mac, ETH_ALEN);
|
||||||
|
memcpy(bcm63xx_sprom.et1mac, bcm63xx_sprom.il0mac, ETH_ALEN);
|
||||||
|
if (ssb_arch_set_fallback_sprom(&bcm63xx_sprom) < 0)
|
||||||
|
printk(KERN_ERR "failed to register fallback SPROM\n");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -676,49 +814,6 @@ void __init board_setup(void)
|
||||||
panic("unexpected CPU for bcm963xx board");
|
panic("unexpected CPU for bcm963xx board");
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* return board name for /proc/cpuinfo
|
|
||||||
*/
|
|
||||||
const char *board_get_name(void)
|
|
||||||
{
|
|
||||||
return board.name;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* register & return a new board mac address
|
|
||||||
*/
|
|
||||||
static int board_get_mac_address(u8 *mac)
|
|
||||||
{
|
|
||||||
u8 *p;
|
|
||||||
int count;
|
|
||||||
|
|
||||||
if (mac_addr_used >= nvram.mac_addr_count) {
|
|
||||||
printk(KERN_ERR PFX "not enough mac address\n");
|
|
||||||
return -ENODEV;
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(mac, nvram.mac_addr_base, ETH_ALEN);
|
|
||||||
p = mac + ETH_ALEN - 1;
|
|
||||||
count = mac_addr_used;
|
|
||||||
|
|
||||||
while (count--) {
|
|
||||||
do {
|
|
||||||
(*p)++;
|
|
||||||
if (*p != 0)
|
|
||||||
break;
|
|
||||||
p--;
|
|
||||||
} while (p != mac);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (p == mac) {
|
|
||||||
printk(KERN_ERR PFX "unable to fetch mac address\n");
|
|
||||||
return -ENODEV;
|
|
||||||
}
|
|
||||||
|
|
||||||
mac_addr_used++;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct mtd_partition mtd_partitions[] = {
|
static struct mtd_partition mtd_partitions[] = {
|
||||||
{
|
{
|
||||||
.name = "cfe",
|
.name = "cfe",
|
||||||
|
@ -750,33 +845,6 @@ static struct platform_device mtd_dev = {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
|
||||||
* Register a sane SPROMv2 to make the on-board
|
|
||||||
* bcm4318 WLAN work
|
|
||||||
*/
|
|
||||||
#ifdef CONFIG_SSB_PCIHOST
|
|
||||||
static struct ssb_sprom bcm63xx_sprom = {
|
|
||||||
.revision = 0x02,
|
|
||||||
.board_rev = 0x17,
|
|
||||||
.country_code = 0x0,
|
|
||||||
.ant_available_bg = 0x3,
|
|
||||||
.pa0b0 = 0x15ae,
|
|
||||||
.pa0b1 = 0xfa85,
|
|
||||||
.pa0b2 = 0xfe8d,
|
|
||||||
.pa1b0 = 0xffff,
|
|
||||||
.pa1b1 = 0xffff,
|
|
||||||
.pa1b2 = 0xffff,
|
|
||||||
.gpio0 = 0xff,
|
|
||||||
.gpio1 = 0xff,
|
|
||||||
.gpio2 = 0xff,
|
|
||||||
.gpio3 = 0xff,
|
|
||||||
.maxpwr_bg = 0x004c,
|
|
||||||
.itssi_bg = 0x00,
|
|
||||||
.boardflags_lo = 0x2848,
|
|
||||||
.boardflags_hi = 0x0000,
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static struct gpio_led_platform_data bcm63xx_led_data;
|
static struct gpio_led_platform_data bcm63xx_led_data;
|
||||||
|
|
||||||
static struct platform_device bcm63xx_gpio_leds = {
|
static struct platform_device bcm63xx_gpio_leds = {
|
||||||
|
@ -792,6 +860,12 @@ int __init board_register_devices(void)
|
||||||
{
|
{
|
||||||
u32 val;
|
u32 val;
|
||||||
|
|
||||||
|
if (board.has_uart0)
|
||||||
|
bcm63xx_uart_register(0);
|
||||||
|
|
||||||
|
if (board.has_uart1)
|
||||||
|
bcm63xx_uart_register(1);
|
||||||
|
|
||||||
if (board.has_pccard)
|
if (board.has_pccard)
|
||||||
bcm63xx_pcmcia_register();
|
bcm63xx_pcmcia_register();
|
||||||
|
|
||||||
|
@ -806,17 +880,6 @@ int __init board_register_devices(void)
|
||||||
if (board.has_dsp)
|
if (board.has_dsp)
|
||||||
bcm63xx_dsp_register(&board.dsp);
|
bcm63xx_dsp_register(&board.dsp);
|
||||||
|
|
||||||
/* Generate MAC address for WLAN and
|
|
||||||
* register our SPROM */
|
|
||||||
#ifdef CONFIG_SSB_PCIHOST
|
|
||||||
if (!board_get_mac_address(bcm63xx_sprom.il0mac)) {
|
|
||||||
memcpy(bcm63xx_sprom.et0mac, bcm63xx_sprom.il0mac, ETH_ALEN);
|
|
||||||
memcpy(bcm63xx_sprom.et1mac, bcm63xx_sprom.il0mac, ETH_ALEN);
|
|
||||||
if (ssb_arch_set_fallback_sprom(&bcm63xx_sprom) < 0)
|
|
||||||
printk(KERN_ERR "failed to register fallback SPROM\n");
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* read base address of boot chip select (0) */
|
/* read base address of boot chip select (0) */
|
||||||
if (BCMCPU_IS_6345())
|
if (BCMCPU_IS_6345())
|
||||||
val = 0x1fc00000;
|
val = 0x1fc00000;
|
||||||
|
|
|
@ -36,6 +36,7 @@ static const unsigned long bcm96338_regs_base[] = {
|
||||||
[RSET_TIMER] = BCM_6338_TIMER_BASE,
|
[RSET_TIMER] = BCM_6338_TIMER_BASE,
|
||||||
[RSET_WDT] = BCM_6338_WDT_BASE,
|
[RSET_WDT] = BCM_6338_WDT_BASE,
|
||||||
[RSET_UART0] = BCM_6338_UART0_BASE,
|
[RSET_UART0] = BCM_6338_UART0_BASE,
|
||||||
|
[RSET_UART1] = BCM_6338_UART1_BASE,
|
||||||
[RSET_GPIO] = BCM_6338_GPIO_BASE,
|
[RSET_GPIO] = BCM_6338_GPIO_BASE,
|
||||||
[RSET_SPI] = BCM_6338_SPI_BASE,
|
[RSET_SPI] = BCM_6338_SPI_BASE,
|
||||||
[RSET_OHCI0] = BCM_6338_OHCI0_BASE,
|
[RSET_OHCI0] = BCM_6338_OHCI0_BASE,
|
||||||
|
@ -72,6 +73,7 @@ static const unsigned long bcm96345_regs_base[] = {
|
||||||
[RSET_TIMER] = BCM_6345_TIMER_BASE,
|
[RSET_TIMER] = BCM_6345_TIMER_BASE,
|
||||||
[RSET_WDT] = BCM_6345_WDT_BASE,
|
[RSET_WDT] = BCM_6345_WDT_BASE,
|
||||||
[RSET_UART0] = BCM_6345_UART0_BASE,
|
[RSET_UART0] = BCM_6345_UART0_BASE,
|
||||||
|
[RSET_UART1] = BCM_6345_UART1_BASE,
|
||||||
[RSET_GPIO] = BCM_6345_GPIO_BASE,
|
[RSET_GPIO] = BCM_6345_GPIO_BASE,
|
||||||
[RSET_SPI] = BCM_6345_SPI_BASE,
|
[RSET_SPI] = BCM_6345_SPI_BASE,
|
||||||
[RSET_UDC0] = BCM_6345_UDC0_BASE,
|
[RSET_UDC0] = BCM_6345_UDC0_BASE,
|
||||||
|
@ -109,6 +111,7 @@ static const unsigned long bcm96348_regs_base[] = {
|
||||||
[RSET_TIMER] = BCM_6348_TIMER_BASE,
|
[RSET_TIMER] = BCM_6348_TIMER_BASE,
|
||||||
[RSET_WDT] = BCM_6348_WDT_BASE,
|
[RSET_WDT] = BCM_6348_WDT_BASE,
|
||||||
[RSET_UART0] = BCM_6348_UART0_BASE,
|
[RSET_UART0] = BCM_6348_UART0_BASE,
|
||||||
|
[RSET_UART1] = BCM_6348_UART1_BASE,
|
||||||
[RSET_GPIO] = BCM_6348_GPIO_BASE,
|
[RSET_GPIO] = BCM_6348_GPIO_BASE,
|
||||||
[RSET_SPI] = BCM_6348_SPI_BASE,
|
[RSET_SPI] = BCM_6348_SPI_BASE,
|
||||||
[RSET_OHCI0] = BCM_6348_OHCI0_BASE,
|
[RSET_OHCI0] = BCM_6348_OHCI0_BASE,
|
||||||
|
@ -150,6 +153,7 @@ static const unsigned long bcm96358_regs_base[] = {
|
||||||
[RSET_TIMER] = BCM_6358_TIMER_BASE,
|
[RSET_TIMER] = BCM_6358_TIMER_BASE,
|
||||||
[RSET_WDT] = BCM_6358_WDT_BASE,
|
[RSET_WDT] = BCM_6358_WDT_BASE,
|
||||||
[RSET_UART0] = BCM_6358_UART0_BASE,
|
[RSET_UART0] = BCM_6358_UART0_BASE,
|
||||||
|
[RSET_UART1] = BCM_6358_UART1_BASE,
|
||||||
[RSET_GPIO] = BCM_6358_GPIO_BASE,
|
[RSET_GPIO] = BCM_6358_GPIO_BASE,
|
||||||
[RSET_SPI] = BCM_6358_SPI_BASE,
|
[RSET_SPI] = BCM_6358_SPI_BASE,
|
||||||
[RSET_OHCI0] = BCM_6358_OHCI0_BASE,
|
[RSET_OHCI0] = BCM_6358_OHCI0_BASE,
|
||||||
|
@ -170,6 +174,7 @@ static const unsigned long bcm96358_regs_base[] = {
|
||||||
static const int bcm96358_irqs[] = {
|
static const int bcm96358_irqs[] = {
|
||||||
[IRQ_TIMER] = BCM_6358_TIMER_IRQ,
|
[IRQ_TIMER] = BCM_6358_TIMER_IRQ,
|
||||||
[IRQ_UART0] = BCM_6358_UART0_IRQ,
|
[IRQ_UART0] = BCM_6358_UART0_IRQ,
|
||||||
|
[IRQ_UART1] = BCM_6358_UART1_IRQ,
|
||||||
[IRQ_DSL] = BCM_6358_DSL_IRQ,
|
[IRQ_DSL] = BCM_6358_DSL_IRQ,
|
||||||
[IRQ_ENET0] = BCM_6358_ENET0_IRQ,
|
[IRQ_ENET0] = BCM_6358_ENET0_IRQ,
|
||||||
[IRQ_ENET1] = BCM_6358_ENET1_IRQ,
|
[IRQ_ENET1] = BCM_6358_ENET1_IRQ,
|
||||||
|
|
|
@ -11,31 +11,65 @@
|
||||||
#include <linux/platform_device.h>
|
#include <linux/platform_device.h>
|
||||||
#include <bcm63xx_cpu.h>
|
#include <bcm63xx_cpu.h>
|
||||||
|
|
||||||
static struct resource uart_resources[] = {
|
static struct resource uart0_resources[] = {
|
||||||
{
|
{
|
||||||
.start = -1, /* filled at runtime */
|
/* start & end filled at runtime */
|
||||||
.end = -1, /* filled at runtime */
|
|
||||||
.flags = IORESOURCE_MEM,
|
.flags = IORESOURCE_MEM,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.start = -1, /* filled at runtime */
|
/* start filled at runtime */
|
||||||
.flags = IORESOURCE_IRQ,
|
.flags = IORESOURCE_IRQ,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct platform_device bcm63xx_uart_device = {
|
static struct resource uart1_resources[] = {
|
||||||
.name = "bcm63xx_uart",
|
{
|
||||||
.id = 0,
|
/* start & end filled at runtime */
|
||||||
.num_resources = ARRAY_SIZE(uart_resources),
|
.flags = IORESOURCE_MEM,
|
||||||
.resource = uart_resources,
|
},
|
||||||
|
{
|
||||||
|
/* start filled at runtime */
|
||||||
|
.flags = IORESOURCE_IRQ,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
int __init bcm63xx_uart_register(void)
|
static struct platform_device bcm63xx_uart_devices[] = {
|
||||||
|
{
|
||||||
|
.name = "bcm63xx_uart",
|
||||||
|
.id = 0,
|
||||||
|
.num_resources = ARRAY_SIZE(uart0_resources),
|
||||||
|
.resource = uart0_resources,
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
.name = "bcm63xx_uart",
|
||||||
|
.id = 1,
|
||||||
|
.num_resources = ARRAY_SIZE(uart1_resources),
|
||||||
|
.resource = uart1_resources,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
int __init bcm63xx_uart_register(unsigned int id)
|
||||||
{
|
{
|
||||||
uart_resources[0].start = bcm63xx_regset_address(RSET_UART0);
|
if (id >= ARRAY_SIZE(bcm63xx_uart_devices))
|
||||||
uart_resources[0].end = uart_resources[0].start;
|
return -ENODEV;
|
||||||
uart_resources[0].end += RSET_UART_SIZE - 1;
|
|
||||||
uart_resources[1].start = bcm63xx_get_irq_number(IRQ_UART0);
|
if (id == 1 && !BCMCPU_IS_6358())
|
||||||
return platform_device_register(&bcm63xx_uart_device);
|
return -ENODEV;
|
||||||
|
|
||||||
|
if (id == 0) {
|
||||||
|
uart0_resources[0].start = bcm63xx_regset_address(RSET_UART0);
|
||||||
|
uart0_resources[0].end = uart0_resources[0].start +
|
||||||
|
RSET_UART_SIZE - 1;
|
||||||
|
uart0_resources[1].start = bcm63xx_get_irq_number(IRQ_UART0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (id == 1) {
|
||||||
|
uart1_resources[0].start = bcm63xx_regset_address(RSET_UART1);
|
||||||
|
uart1_resources[0].end = uart1_resources[0].start +
|
||||||
|
RSET_UART_SIZE - 1;
|
||||||
|
uart1_resources[1].start = bcm63xx_get_irq_number(IRQ_UART1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return platform_device_register(&bcm63xx_uart_devices[id]);
|
||||||
}
|
}
|
||||||
arch_initcall(bcm63xx_uart_register);
|
|
||||||
|
|
|
@ -125,10 +125,10 @@ static struct gpio_chip bcm63xx_gpio_chip = {
|
||||||
|
|
||||||
int __init bcm63xx_gpio_init(void)
|
int __init bcm63xx_gpio_init(void)
|
||||||
{
|
{
|
||||||
|
gpio_out_low = bcm_gpio_readl(GPIO_DATA_LO_REG);
|
||||||
|
gpio_out_high = bcm_gpio_readl(GPIO_DATA_HI_REG);
|
||||||
bcm63xx_gpio_chip.ngpio = bcm63xx_gpio_count();
|
bcm63xx_gpio_chip.ngpio = bcm63xx_gpio_count();
|
||||||
pr_info("registering %d GPIOs\n", bcm63xx_gpio_chip.ngpio);
|
pr_info("registering %d GPIOs\n", bcm63xx_gpio_chip.ngpio);
|
||||||
|
|
||||||
return gpiochip_add(&bcm63xx_gpio_chip);
|
return gpiochip_add(&bcm63xx_gpio_chip);
|
||||||
}
|
}
|
||||||
|
|
||||||
arch_initcall(bcm63xx_gpio_init);
|
|
||||||
|
|
|
@ -45,9 +45,6 @@ extern struct plat_smp_ops octeon_smp_ops;
|
||||||
extern void pci_console_init(const char *arg);
|
extern void pci_console_init(const char *arg);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_CAVIUM_RESERVE32
|
|
||||||
extern uint64_t octeon_reserve32_memory;
|
|
||||||
#endif
|
|
||||||
static unsigned long long MAX_MEMORY = 512ull << 20;
|
static unsigned long long MAX_MEMORY = 512ull << 20;
|
||||||
|
|
||||||
struct octeon_boot_descriptor *octeon_boot_desc_ptr;
|
struct octeon_boot_descriptor *octeon_boot_desc_ptr;
|
||||||
|
@ -186,54 +183,6 @@ void octeon_check_cpu_bist(void)
|
||||||
write_octeon_c0_dcacheerr(0);
|
write_octeon_c0_dcacheerr(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_CAVIUM_RESERVE32_USE_WIRED_TLB
|
|
||||||
/**
|
|
||||||
* Called on every core to setup the wired tlb entry needed
|
|
||||||
* if CONFIG_CAVIUM_RESERVE32_USE_WIRED_TLB is set.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
static void octeon_hal_setup_per_cpu_reserved32(void *unused)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* The config has selected to wire the reserve32 memory for all
|
|
||||||
* userspace applications. We need to put a wired TLB entry in for each
|
|
||||||
* 512MB of reserve32 memory. We only handle double 256MB pages here,
|
|
||||||
* so reserve32 must be multiple of 512MB.
|
|
||||||
*/
|
|
||||||
uint32_t size = CONFIG_CAVIUM_RESERVE32;
|
|
||||||
uint32_t entrylo0 =
|
|
||||||
0x7 | ((octeon_reserve32_memory & ((1ul << 40) - 1)) >> 6);
|
|
||||||
uint32_t entrylo1 = entrylo0 + (256 << 14);
|
|
||||||
uint32_t entryhi = (0x80000000UL - (CONFIG_CAVIUM_RESERVE32 << 20));
|
|
||||||
while (size >= 512) {
|
|
||||||
#if 0
|
|
||||||
pr_info("CPU%d: Adding double wired TLB entry for 0x%lx\n",
|
|
||||||
smp_processor_id(), entryhi);
|
|
||||||
#endif
|
|
||||||
add_wired_entry(entrylo0, entrylo1, entryhi, PM_256M);
|
|
||||||
entrylo0 += 512 << 14;
|
|
||||||
entrylo1 += 512 << 14;
|
|
||||||
entryhi += 512 << 20;
|
|
||||||
size -= 512;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif /* CONFIG_CAVIUM_RESERVE32_USE_WIRED_TLB */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Called to release the named block which was used to made sure
|
|
||||||
* that nobody used the memory for something else during
|
|
||||||
* init. Now we'll free it so userspace apps can use this
|
|
||||||
* memory region with bootmem_alloc.
|
|
||||||
*
|
|
||||||
* This function is called only once from prom_free_prom_memory().
|
|
||||||
*/
|
|
||||||
void octeon_hal_setup_reserved32(void)
|
|
||||||
{
|
|
||||||
#ifdef CONFIG_CAVIUM_RESERVE32_USE_WIRED_TLB
|
|
||||||
on_each_cpu(octeon_hal_setup_per_cpu_reserved32, NULL, 0, 1);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reboot Octeon
|
* Reboot Octeon
|
||||||
*
|
*
|
||||||
|
@ -294,18 +243,6 @@ static void octeon_halt(void)
|
||||||
octeon_kill_core(NULL);
|
octeon_kill_core(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
/**
|
|
||||||
* Platform time init specifics.
|
|
||||||
* Returns
|
|
||||||
*/
|
|
||||||
void __init plat_time_init(void)
|
|
||||||
{
|
|
||||||
/* Nothing special here, but we are required to have one */
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handle all the error condition interrupts that might occur.
|
* Handle all the error condition interrupts that might occur.
|
||||||
*
|
*
|
||||||
|
@ -502,25 +439,13 @@ void __init prom_init(void)
|
||||||
* memory when it is getting memory from the
|
* memory when it is getting memory from the
|
||||||
* bootloader. Later, after the memory allocations are
|
* bootloader. Later, after the memory allocations are
|
||||||
* complete, the reserve32 will be freed.
|
* complete, the reserve32 will be freed.
|
||||||
*/
|
*
|
||||||
#ifdef CONFIG_CAVIUM_RESERVE32_USE_WIRED_TLB
|
|
||||||
if (CONFIG_CAVIUM_RESERVE32 & 0x1ff)
|
|
||||||
pr_err("CAVIUM_RESERVE32 isn't a multiple of 512MB. "
|
|
||||||
"This is required if CAVIUM_RESERVE32_USE_WIRED_TLB "
|
|
||||||
"is set\n");
|
|
||||||
else
|
|
||||||
addr = cvmx_bootmem_phy_named_block_alloc(CONFIG_CAVIUM_RESERVE32 << 20,
|
|
||||||
0, 0, 512 << 20,
|
|
||||||
"CAVIUM_RESERVE32", 0);
|
|
||||||
#else
|
|
||||||
/*
|
|
||||||
* Allocate memory for RESERVED32 aligned on 2MB boundary. This
|
* Allocate memory for RESERVED32 aligned on 2MB boundary. This
|
||||||
* is in case we later use hugetlb entries with it.
|
* is in case we later use hugetlb entries with it.
|
||||||
*/
|
*/
|
||||||
addr = cvmx_bootmem_phy_named_block_alloc(CONFIG_CAVIUM_RESERVE32 << 20,
|
addr = cvmx_bootmem_phy_named_block_alloc(CONFIG_CAVIUM_RESERVE32 << 20,
|
||||||
0, 0, 2 << 20,
|
0, 0, 2 << 20,
|
||||||
"CAVIUM_RESERVE32", 0);
|
"CAVIUM_RESERVE32", 0);
|
||||||
#endif
|
|
||||||
if (addr < 0)
|
if (addr < 0)
|
||||||
pr_err("Failed to allocate CAVIUM_RESERVE32 memory area\n");
|
pr_err("Failed to allocate CAVIUM_RESERVE32 memory area\n");
|
||||||
else
|
else
|
||||||
|
@ -817,9 +742,4 @@ void prom_free_prom_memory(void)
|
||||||
panic("Unable to request_irq(OCTEON_IRQ_RML)\n");
|
panic("Unable to request_irq(OCTEON_IRQ_RML)\n");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* This call is here so that it is performed after any TLB
|
|
||||||
initializations. It needs to be after these in case the
|
|
||||||
CONFIG_CAVIUM_RESERVE32_USE_WIRED_TLB option is set */
|
|
||||||
octeon_hal_setup_reserved32();
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -279,14 +279,6 @@ static void octeon_cpu_die(unsigned int cpu)
|
||||||
uint32_t avail_coremask;
|
uint32_t avail_coremask;
|
||||||
struct cvmx_bootmem_named_block_desc *block_desc;
|
struct cvmx_bootmem_named_block_desc *block_desc;
|
||||||
|
|
||||||
#ifdef CONFIG_CAVIUM_OCTEON_WATCHDOG
|
|
||||||
/* Disable the watchdog */
|
|
||||||
cvmx_ciu_wdogx_t ciu_wdog;
|
|
||||||
ciu_wdog.u64 = cvmx_read_csr(CVMX_CIU_WDOGX(cpu));
|
|
||||||
ciu_wdog.s.mode = 0;
|
|
||||||
cvmx_write_csr(CVMX_CIU_WDOGX(cpu), ciu_wdog.u64);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
while (per_cpu(cpu_state, cpu) != CPU_DEAD)
|
while (per_cpu(cpu_state, cpu) != CPU_DEAD)
|
||||||
cpu_relax();
|
cpu_relax();
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -13,12 +13,14 @@
|
||||||
#include <asm/siginfo.h>
|
#include <asm/siginfo.h>
|
||||||
|
|
||||||
struct mips_abi {
|
struct mips_abi {
|
||||||
int (* const setup_frame)(struct k_sigaction * ka,
|
int (* const setup_frame)(void *sig_return, struct k_sigaction *ka,
|
||||||
struct pt_regs *regs, int signr,
|
struct pt_regs *regs, int signr,
|
||||||
sigset_t *set);
|
sigset_t *set);
|
||||||
int (* const setup_rt_frame)(struct k_sigaction * ka,
|
const unsigned long signal_return_offset;
|
||||||
|
int (* const setup_rt_frame)(void *sig_return, struct k_sigaction *ka,
|
||||||
struct pt_regs *regs, int signr,
|
struct pt_regs *regs, int signr,
|
||||||
sigset_t *set, siginfo_t *info);
|
sigset_t *set, siginfo_t *info);
|
||||||
|
const unsigned long rt_signal_return_offset;
|
||||||
const unsigned long restart;
|
const unsigned long restart;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -310,6 +310,7 @@ do { \
|
||||||
|
|
||||||
#endif /* CONFIG_64BIT */
|
#endif /* CONFIG_64BIT */
|
||||||
|
|
||||||
|
struct pt_regs;
|
||||||
struct task_struct;
|
struct task_struct;
|
||||||
|
|
||||||
extern void elf_dump_regs(elf_greg_t *, struct pt_regs *regs);
|
extern void elf_dump_regs(elf_greg_t *, struct pt_regs *regs);
|
||||||
|
@ -367,4 +368,8 @@ extern const char *__elf_platform;
|
||||||
#define ELF_ET_DYN_BASE (TASK_SIZE / 3 * 2)
|
#define ELF_ET_DYN_BASE (TASK_SIZE / 3 * 2)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define ARCH_HAS_SETUP_ADDITIONAL_PAGES 1
|
||||||
|
struct linux_binprm;
|
||||||
|
extern int arch_setup_additional_pages(struct linux_binprm *bprm,
|
||||||
|
int uses_interp);
|
||||||
#endif /* _ASM_ELF_H */
|
#endif /* _ASM_ELF_H */
|
||||||
|
|
|
@ -41,7 +41,11 @@ struct mips_fpu_emulator_stats {
|
||||||
DECLARE_PER_CPU(struct mips_fpu_emulator_stats, fpuemustats);
|
DECLARE_PER_CPU(struct mips_fpu_emulator_stats, fpuemustats);
|
||||||
|
|
||||||
#define MIPS_FPU_EMU_INC_STATS(M) \
|
#define MIPS_FPU_EMU_INC_STATS(M) \
|
||||||
cpu_local_wrap(__local_inc(&__get_cpu_var(fpuemustats).M))
|
do { \
|
||||||
|
preempt_disable(); \
|
||||||
|
__local_inc(&__get_cpu_var(fpuemustats).M); \
|
||||||
|
preempt_enable(); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
#else
|
#else
|
||||||
#define MIPS_FPU_EMU_INC_STATS(M) do { } while (0)
|
#define MIPS_FPU_EMU_INC_STATS(M) do { } while (0)
|
||||||
|
|
|
@ -85,6 +85,7 @@ enum bcm63xx_regs_set {
|
||||||
RSET_TIMER,
|
RSET_TIMER,
|
||||||
RSET_WDT,
|
RSET_WDT,
|
||||||
RSET_UART0,
|
RSET_UART0,
|
||||||
|
RSET_UART1,
|
||||||
RSET_GPIO,
|
RSET_GPIO,
|
||||||
RSET_SPI,
|
RSET_SPI,
|
||||||
RSET_UDC0,
|
RSET_UDC0,
|
||||||
|
@ -123,6 +124,7 @@ enum bcm63xx_regs_set {
|
||||||
#define BCM_6338_TIMER_BASE (0xfffe0200)
|
#define BCM_6338_TIMER_BASE (0xfffe0200)
|
||||||
#define BCM_6338_WDT_BASE (0xfffe021c)
|
#define BCM_6338_WDT_BASE (0xfffe021c)
|
||||||
#define BCM_6338_UART0_BASE (0xfffe0300)
|
#define BCM_6338_UART0_BASE (0xfffe0300)
|
||||||
|
#define BCM_6338_UART1_BASE (0xdeadbeef)
|
||||||
#define BCM_6338_GPIO_BASE (0xfffe0400)
|
#define BCM_6338_GPIO_BASE (0xfffe0400)
|
||||||
#define BCM_6338_SPI_BASE (0xfffe0c00)
|
#define BCM_6338_SPI_BASE (0xfffe0c00)
|
||||||
#define BCM_6338_UDC0_BASE (0xdeadbeef)
|
#define BCM_6338_UDC0_BASE (0xdeadbeef)
|
||||||
|
@ -153,6 +155,7 @@ enum bcm63xx_regs_set {
|
||||||
#define BCM_6345_TIMER_BASE (0xfffe0200)
|
#define BCM_6345_TIMER_BASE (0xfffe0200)
|
||||||
#define BCM_6345_WDT_BASE (0xfffe021c)
|
#define BCM_6345_WDT_BASE (0xfffe021c)
|
||||||
#define BCM_6345_UART0_BASE (0xfffe0300)
|
#define BCM_6345_UART0_BASE (0xfffe0300)
|
||||||
|
#define BCM_6345_UART1_BASE (0xdeadbeef)
|
||||||
#define BCM_6345_GPIO_BASE (0xfffe0400)
|
#define BCM_6345_GPIO_BASE (0xfffe0400)
|
||||||
#define BCM_6345_SPI_BASE (0xdeadbeef)
|
#define BCM_6345_SPI_BASE (0xdeadbeef)
|
||||||
#define BCM_6345_UDC0_BASE (0xdeadbeef)
|
#define BCM_6345_UDC0_BASE (0xdeadbeef)
|
||||||
|
@ -182,6 +185,7 @@ enum bcm63xx_regs_set {
|
||||||
#define BCM_6348_TIMER_BASE (0xfffe0200)
|
#define BCM_6348_TIMER_BASE (0xfffe0200)
|
||||||
#define BCM_6348_WDT_BASE (0xfffe021c)
|
#define BCM_6348_WDT_BASE (0xfffe021c)
|
||||||
#define BCM_6348_UART0_BASE (0xfffe0300)
|
#define BCM_6348_UART0_BASE (0xfffe0300)
|
||||||
|
#define BCM_6348_UART1_BASE (0xdeadbeef)
|
||||||
#define BCM_6348_GPIO_BASE (0xfffe0400)
|
#define BCM_6348_GPIO_BASE (0xfffe0400)
|
||||||
#define BCM_6348_SPI_BASE (0xfffe0c00)
|
#define BCM_6348_SPI_BASE (0xfffe0c00)
|
||||||
#define BCM_6348_UDC0_BASE (0xfffe1000)
|
#define BCM_6348_UDC0_BASE (0xfffe1000)
|
||||||
|
@ -208,6 +212,7 @@ enum bcm63xx_regs_set {
|
||||||
#define BCM_6358_TIMER_BASE (0xfffe0040)
|
#define BCM_6358_TIMER_BASE (0xfffe0040)
|
||||||
#define BCM_6358_WDT_BASE (0xfffe005c)
|
#define BCM_6358_WDT_BASE (0xfffe005c)
|
||||||
#define BCM_6358_UART0_BASE (0xfffe0100)
|
#define BCM_6358_UART0_BASE (0xfffe0100)
|
||||||
|
#define BCM_6358_UART1_BASE (0xfffe0120)
|
||||||
#define BCM_6358_GPIO_BASE (0xfffe0080)
|
#define BCM_6358_GPIO_BASE (0xfffe0080)
|
||||||
#define BCM_6358_SPI_BASE (0xdeadbeef)
|
#define BCM_6358_SPI_BASE (0xdeadbeef)
|
||||||
#define BCM_6358_UDC0_BASE (0xfffe0800)
|
#define BCM_6358_UDC0_BASE (0xfffe0800)
|
||||||
|
@ -246,6 +251,8 @@ static inline unsigned long bcm63xx_regset_address(enum bcm63xx_regs_set set)
|
||||||
return BCM_6338_WDT_BASE;
|
return BCM_6338_WDT_BASE;
|
||||||
case RSET_UART0:
|
case RSET_UART0:
|
||||||
return BCM_6338_UART0_BASE;
|
return BCM_6338_UART0_BASE;
|
||||||
|
case RSET_UART1:
|
||||||
|
return BCM_6338_UART1_BASE;
|
||||||
case RSET_GPIO:
|
case RSET_GPIO:
|
||||||
return BCM_6338_GPIO_BASE;
|
return BCM_6338_GPIO_BASE;
|
||||||
case RSET_SPI:
|
case RSET_SPI:
|
||||||
|
@ -292,6 +299,8 @@ static inline unsigned long bcm63xx_regset_address(enum bcm63xx_regs_set set)
|
||||||
return BCM_6345_WDT_BASE;
|
return BCM_6345_WDT_BASE;
|
||||||
case RSET_UART0:
|
case RSET_UART0:
|
||||||
return BCM_6345_UART0_BASE;
|
return BCM_6345_UART0_BASE;
|
||||||
|
case RSET_UART1:
|
||||||
|
return BCM_6345_UART1_BASE;
|
||||||
case RSET_GPIO:
|
case RSET_GPIO:
|
||||||
return BCM_6345_GPIO_BASE;
|
return BCM_6345_GPIO_BASE;
|
||||||
case RSET_SPI:
|
case RSET_SPI:
|
||||||
|
@ -338,6 +347,8 @@ static inline unsigned long bcm63xx_regset_address(enum bcm63xx_regs_set set)
|
||||||
return BCM_6348_WDT_BASE;
|
return BCM_6348_WDT_BASE;
|
||||||
case RSET_UART0:
|
case RSET_UART0:
|
||||||
return BCM_6348_UART0_BASE;
|
return BCM_6348_UART0_BASE;
|
||||||
|
case RSET_UART1:
|
||||||
|
return BCM_6348_UART1_BASE;
|
||||||
case RSET_GPIO:
|
case RSET_GPIO:
|
||||||
return BCM_6348_GPIO_BASE;
|
return BCM_6348_GPIO_BASE;
|
||||||
case RSET_SPI:
|
case RSET_SPI:
|
||||||
|
@ -384,6 +395,8 @@ static inline unsigned long bcm63xx_regset_address(enum bcm63xx_regs_set set)
|
||||||
return BCM_6358_WDT_BASE;
|
return BCM_6358_WDT_BASE;
|
||||||
case RSET_UART0:
|
case RSET_UART0:
|
||||||
return BCM_6358_UART0_BASE;
|
return BCM_6358_UART0_BASE;
|
||||||
|
case RSET_UART1:
|
||||||
|
return BCM_6358_UART1_BASE;
|
||||||
case RSET_GPIO:
|
case RSET_GPIO:
|
||||||
return BCM_6358_GPIO_BASE;
|
return BCM_6358_GPIO_BASE;
|
||||||
case RSET_SPI:
|
case RSET_SPI:
|
||||||
|
@ -429,6 +442,7 @@ static inline unsigned long bcm63xx_regset_address(enum bcm63xx_regs_set set)
|
||||||
enum bcm63xx_irq {
|
enum bcm63xx_irq {
|
||||||
IRQ_TIMER = 0,
|
IRQ_TIMER = 0,
|
||||||
IRQ_UART0,
|
IRQ_UART0,
|
||||||
|
IRQ_UART1,
|
||||||
IRQ_DSL,
|
IRQ_DSL,
|
||||||
IRQ_ENET0,
|
IRQ_ENET0,
|
||||||
IRQ_ENET1,
|
IRQ_ENET1,
|
||||||
|
@ -510,6 +524,7 @@ enum bcm63xx_irq {
|
||||||
*/
|
*/
|
||||||
#define BCM_6358_TIMER_IRQ (IRQ_INTERNAL_BASE + 0)
|
#define BCM_6358_TIMER_IRQ (IRQ_INTERNAL_BASE + 0)
|
||||||
#define BCM_6358_UART0_IRQ (IRQ_INTERNAL_BASE + 2)
|
#define BCM_6358_UART0_IRQ (IRQ_INTERNAL_BASE + 2)
|
||||||
|
#define BCM_6358_UART1_IRQ (IRQ_INTERNAL_BASE + 3)
|
||||||
#define BCM_6358_OHCI0_IRQ (IRQ_INTERNAL_BASE + 5)
|
#define BCM_6358_OHCI0_IRQ (IRQ_INTERNAL_BASE + 5)
|
||||||
#define BCM_6358_ENET1_IRQ (IRQ_INTERNAL_BASE + 6)
|
#define BCM_6358_ENET1_IRQ (IRQ_INTERNAL_BASE + 6)
|
||||||
#define BCM_6358_ENET0_IRQ (IRQ_INTERNAL_BASE + 8)
|
#define BCM_6358_ENET0_IRQ (IRQ_INTERNAL_BASE + 8)
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
#ifndef BCM63XX_DEV_UART_H_
|
||||||
|
#define BCM63XX_DEV_UART_H_
|
||||||
|
|
||||||
|
int bcm63xx_uart_register(unsigned int id);
|
||||||
|
|
||||||
|
#endif /* BCM63XX_DEV_UART_H_ */
|
|
@ -10,6 +10,10 @@ static inline unsigned long bcm63xx_gpio_count(void)
|
||||||
switch (bcm63xx_get_cpu_id()) {
|
switch (bcm63xx_get_cpu_id()) {
|
||||||
case BCM6358_CPU_ID:
|
case BCM6358_CPU_ID:
|
||||||
return 40;
|
return 40;
|
||||||
|
case BCM6338_CPU_ID:
|
||||||
|
return 8;
|
||||||
|
case BCM6345_CPU_ID:
|
||||||
|
return 16;
|
||||||
case BCM6348_CPU_ID:
|
case BCM6348_CPU_ID:
|
||||||
default:
|
default:
|
||||||
return 37;
|
return 37;
|
||||||
|
|
|
@ -45,6 +45,8 @@ struct board_info {
|
||||||
unsigned int has_ohci0:1;
|
unsigned int has_ohci0:1;
|
||||||
unsigned int has_ehci0:1;
|
unsigned int has_ehci0:1;
|
||||||
unsigned int has_dsp:1;
|
unsigned int has_dsp:1;
|
||||||
|
unsigned int has_uart0:1;
|
||||||
|
unsigned int has_uart1:1;
|
||||||
|
|
||||||
/* ethernet config */
|
/* ethernet config */
|
||||||
struct bcm63xx_enet_platform_data enet0;
|
struct bcm63xx_enet_platform_data enet0;
|
||||||
|
|
|
@ -24,7 +24,7 @@
|
||||||
#define cpu_has_smartmips 0
|
#define cpu_has_smartmips 0
|
||||||
#define cpu_has_vtag_icache 0
|
#define cpu_has_vtag_icache 0
|
||||||
|
|
||||||
#if !defined(BCMCPU_RUNTIME_DETECT) && (defined(CONFIG_BCMCPU_IS_6348) || defined(CONFIG_CPU_IS_6338) || defined(CONFIG_CPU_IS_BCM6345))
|
#if !defined(BCMCPU_RUNTIME_DETECT) && (defined(CONFIG_BCM63XX_CPU_6348) || defined(CONFIG_BCM63XX_CPU_6345) || defined(CONFIG_BCM63XX_CPU_6338))
|
||||||
#define cpu_has_dc_aliases 0
|
#define cpu_has_dc_aliases 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,11 @@
|
||||||
#if defined(CONFIG_SB1_PASS_1_WORKAROUNDS) || \
|
#if defined(CONFIG_SB1_PASS_1_WORKAROUNDS) || \
|
||||||
defined(CONFIG_SB1_PASS_2_WORKAROUNDS)
|
defined(CONFIG_SB1_PASS_2_WORKAROUNDS)
|
||||||
|
|
||||||
#define BCM1250_M3_WAR 1
|
#ifndef __ASSEMBLY__
|
||||||
|
extern int sb1250_m3_workaround_needed(void);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define BCM1250_M3_WAR sb1250_m3_workaround_needed()
|
||||||
#define SIBYTE_1956_WAR 1
|
#define SIBYTE_1956_WAR 1
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
#ifndef __ASM_MMU_H
|
#ifndef __ASM_MMU_H
|
||||||
#define __ASM_MMU_H
|
#define __ASM_MMU_H
|
||||||
|
|
||||||
typedef unsigned long mm_context_t[NR_CPUS];
|
typedef struct {
|
||||||
|
unsigned long asid[NR_CPUS];
|
||||||
|
void *vdso;
|
||||||
|
} mm_context_t;
|
||||||
|
|
||||||
#endif /* __ASM_MMU_H */
|
#endif /* __ASM_MMU_H */
|
||||||
|
|
|
@ -104,7 +104,7 @@ extern unsigned long smtc_asid_mask;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define cpu_context(cpu, mm) ((mm)->context[cpu])
|
#define cpu_context(cpu, mm) ((mm)->context.asid[cpu])
|
||||||
#define cpu_asid(cpu, mm) (cpu_context((cpu), (mm)) & ASID_MASK)
|
#define cpu_asid(cpu, mm) (cpu_context((cpu), (mm)) & ASID_MASK)
|
||||||
#define asid_cache(cpu) (cpu_data[cpu].asid_cache)
|
#define asid_cache(cpu) (cpu_data[cpu].asid_cache)
|
||||||
|
|
||||||
|
|
|
@ -188,8 +188,10 @@ typedef struct { unsigned long pgprot; } pgprot_t;
|
||||||
#define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \
|
#define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \
|
||||||
VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
|
VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
|
||||||
|
|
||||||
#define UNCAC_ADDR(addr) ((addr) - PAGE_OFFSET + UNCAC_BASE)
|
#define UNCAC_ADDR(addr) ((addr) - PAGE_OFFSET + UNCAC_BASE + \
|
||||||
#define CAC_ADDR(addr) ((addr) - UNCAC_BASE + PAGE_OFFSET)
|
PHYS_OFFSET)
|
||||||
|
#define CAC_ADDR(addr) ((addr) - UNCAC_BASE + PAGE_OFFSET - \
|
||||||
|
PHYS_OFFSET)
|
||||||
|
|
||||||
#include <asm-generic/memory_model.h>
|
#include <asm-generic/memory_model.h>
|
||||||
#include <asm-generic/getorder.h>
|
#include <asm-generic/getorder.h>
|
||||||
|
|
|
@ -33,13 +33,19 @@ extern void (*cpu_wait)(void);
|
||||||
|
|
||||||
extern unsigned int vced_count, vcei_count;
|
extern unsigned int vced_count, vcei_count;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* A special page (the vdso) is mapped into all processes at the very
|
||||||
|
* top of the virtual memory space.
|
||||||
|
*/
|
||||||
|
#define SPECIAL_PAGES_SIZE PAGE_SIZE
|
||||||
|
|
||||||
#ifdef CONFIG_32BIT
|
#ifdef CONFIG_32BIT
|
||||||
/*
|
/*
|
||||||
* User space process size: 2GB. This is hardcoded into a few places,
|
* User space process size: 2GB. This is hardcoded into a few places,
|
||||||
* so don't change it unless you know what you are doing.
|
* so don't change it unless you know what you are doing.
|
||||||
*/
|
*/
|
||||||
#define TASK_SIZE 0x7fff8000UL
|
#define TASK_SIZE 0x7fff8000UL
|
||||||
#define STACK_TOP TASK_SIZE
|
#define STACK_TOP ((TASK_SIZE & PAGE_MASK) - SPECIAL_PAGES_SIZE)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This decides where the kernel will search for a free chunk of vm
|
* This decides where the kernel will search for a free chunk of vm
|
||||||
|
@ -59,7 +65,8 @@ extern unsigned int vced_count, vcei_count;
|
||||||
#define TASK_SIZE32 0x7fff8000UL
|
#define TASK_SIZE32 0x7fff8000UL
|
||||||
#define TASK_SIZE 0x10000000000UL
|
#define TASK_SIZE 0x10000000000UL
|
||||||
#define STACK_TOP \
|
#define STACK_TOP \
|
||||||
(test_thread_flag(TIF_32BIT_ADDR) ? TASK_SIZE32 : TASK_SIZE)
|
(((test_thread_flag(TIF_32BIT_ADDR) ? \
|
||||||
|
TASK_SIZE32 : TASK_SIZE) & PAGE_MASK) - SPECIAL_PAGES_SIZE)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This decides where the kernel will search for a free chunk of vm
|
* This decides where the kernel will search for a free chunk of vm
|
||||||
|
|
|
@ -121,6 +121,25 @@
|
||||||
.endm
|
.endm
|
||||||
#else
|
#else
|
||||||
.macro get_saved_sp /* Uniprocessor variation */
|
.macro get_saved_sp /* Uniprocessor variation */
|
||||||
|
#ifdef CONFIG_CPU_LOONGSON2F
|
||||||
|
/*
|
||||||
|
* Clear BTB (branch target buffer), forbid RAS (return address
|
||||||
|
* stack) to workaround the Out-of-order Issue in Loongson2F
|
||||||
|
* via its diagnostic register.
|
||||||
|
*/
|
||||||
|
move k0, ra
|
||||||
|
jal 1f
|
||||||
|
nop
|
||||||
|
1: jal 1f
|
||||||
|
nop
|
||||||
|
1: jal 1f
|
||||||
|
nop
|
||||||
|
1: jal 1f
|
||||||
|
nop
|
||||||
|
1: move ra, k0
|
||||||
|
li k0, 3
|
||||||
|
mtc0 k0, $22
|
||||||
|
#endif /* CONFIG_CPU_LOONGSON2F */
|
||||||
#if defined(CONFIG_32BIT) || defined(KBUILD_64BIT_SYM32)
|
#if defined(CONFIG_32BIT) || defined(KBUILD_64BIT_SYM32)
|
||||||
lui k1, %hi(kernelsp)
|
lui k1, %hi(kernelsp)
|
||||||
#else
|
#else
|
||||||
|
|
|
@ -84,6 +84,7 @@ Ip_u2s3u1(_lw);
|
||||||
Ip_u1u2u3(_mfc0);
|
Ip_u1u2u3(_mfc0);
|
||||||
Ip_u1u2u3(_mtc0);
|
Ip_u1u2u3(_mtc0);
|
||||||
Ip_u2u1u3(_ori);
|
Ip_u2u1u3(_ori);
|
||||||
|
Ip_u3u1u2(_or);
|
||||||
Ip_u2s3u1(_pref);
|
Ip_u2s3u1(_pref);
|
||||||
Ip_0(_rfe);
|
Ip_0(_rfe);
|
||||||
Ip_u2s3u1(_sc);
|
Ip_u2s3u1(_sc);
|
||||||
|
@ -102,6 +103,7 @@ Ip_0(_tlbwr);
|
||||||
Ip_u3u1u2(_xor);
|
Ip_u3u1u2(_xor);
|
||||||
Ip_u2u1u3(_xori);
|
Ip_u2u1u3(_xori);
|
||||||
Ip_u2u1msbu3(_dins);
|
Ip_u2u1msbu3(_dins);
|
||||||
|
Ip_u1(_syscall);
|
||||||
|
|
||||||
/* Handle labels. */
|
/* Handle labels. */
|
||||||
struct uasm_label {
|
struct uasm_label {
|
||||||
|
|
|
@ -0,0 +1,29 @@
|
||||||
|
/*
|
||||||
|
* This file is subject to the terms and conditions of the GNU General Public
|
||||||
|
* License. See the file "COPYING" in the main directory of this archive
|
||||||
|
* for more details.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2009 Cavium Networks
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __ASM_VDSO_H
|
||||||
|
#define __ASM_VDSO_H
|
||||||
|
|
||||||
|
#include <linux/types.h>
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef CONFIG_32BIT
|
||||||
|
struct mips_vdso {
|
||||||
|
u32 signal_trampoline[2];
|
||||||
|
u32 rt_signal_trampoline[2];
|
||||||
|
};
|
||||||
|
#else /* !CONFIG_32BIT */
|
||||||
|
struct mips_vdso {
|
||||||
|
u32 o32_signal_trampoline[2];
|
||||||
|
u32 o32_rt_signal_trampoline[2];
|
||||||
|
u32 rt_signal_trampoline[2];
|
||||||
|
u32 n32_rt_signal_trampoline[2];
|
||||||
|
};
|
||||||
|
#endif /* CONFIG_32BIT */
|
||||||
|
|
||||||
|
#endif /* __ASM_VDSO_H */
|
|
@ -6,7 +6,7 @@ extra-y := head.o init_task.o vmlinux.lds
|
||||||
|
|
||||||
obj-y += cpu-probe.o branch.o entry.o genex.o irq.o process.o \
|
obj-y += cpu-probe.o branch.o entry.o genex.o irq.o process.o \
|
||||||
ptrace.o reset.o setup.o signal.o syscall.o \
|
ptrace.o reset.o setup.o signal.o syscall.o \
|
||||||
time.o topology.o traps.o unaligned.o watch.o
|
time.o topology.o traps.o unaligned.o watch.o vdso.o
|
||||||
|
|
||||||
ifdef CONFIG_FUNCTION_TRACER
|
ifdef CONFIG_FUNCTION_TRACER
|
||||||
CFLAGS_REMOVE_ftrace.o = -pg
|
CFLAGS_REMOVE_ftrace.o = -pg
|
||||||
|
|
|
@ -164,3 +164,7 @@ void loongson2_cpu_wait(void)
|
||||||
spin_unlock_irqrestore(&loongson2_wait_lock, flags);
|
spin_unlock_irqrestore(&loongson2_wait_lock, flags);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(loongson2_cpu_wait);
|
EXPORT_SYMBOL_GPL(loongson2_cpu_wait);
|
||||||
|
|
||||||
|
MODULE_AUTHOR("Yanhua <yanh@lemote.com>");
|
||||||
|
MODULE_DESCRIPTION("cpufreq driver for Loongson 2F");
|
||||||
|
MODULE_LICENSE("GPL");
|
||||||
|
|
|
@ -63,8 +63,13 @@ void __noreturn cpu_idle(void)
|
||||||
|
|
||||||
smtc_idle_loop_hook();
|
smtc_idle_loop_hook();
|
||||||
#endif
|
#endif
|
||||||
if (cpu_wait)
|
|
||||||
|
if (cpu_wait) {
|
||||||
|
/* Don't trace irqs off for idle */
|
||||||
|
stop_critical_timings();
|
||||||
(*cpu_wait)();
|
(*cpu_wait)();
|
||||||
|
start_critical_timings();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#ifdef CONFIG_HOTPLUG_CPU
|
#ifdef CONFIG_HOTPLUG_CPU
|
||||||
if (!cpu_online(cpu) && !cpu_isset(cpu, cpu_callin_map) &&
|
if (!cpu_online(cpu) && !cpu_isset(cpu, cpu_callin_map) &&
|
||||||
|
|
|
@ -26,11 +26,6 @@
|
||||||
*/
|
*/
|
||||||
extern void __user *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs,
|
extern void __user *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs,
|
||||||
size_t frame_size);
|
size_t frame_size);
|
||||||
/*
|
|
||||||
* install trampoline code to get back from the sig handler
|
|
||||||
*/
|
|
||||||
extern int install_sigtramp(unsigned int __user *tramp, unsigned int syscall);
|
|
||||||
|
|
||||||
/* Check and clear pending FPU exceptions in saved CSR */
|
/* Check and clear pending FPU exceptions in saved CSR */
|
||||||
extern int fpcsr_pending(unsigned int __user *fpcsr);
|
extern int fpcsr_pending(unsigned int __user *fpcsr);
|
||||||
|
|
||||||
|
|
|
@ -32,6 +32,7 @@
|
||||||
#include <asm/ucontext.h>
|
#include <asm/ucontext.h>
|
||||||
#include <asm/cpu-features.h>
|
#include <asm/cpu-features.h>
|
||||||
#include <asm/war.h>
|
#include <asm/war.h>
|
||||||
|
#include <asm/vdso.h>
|
||||||
|
|
||||||
#include "signal-common.h"
|
#include "signal-common.h"
|
||||||
|
|
||||||
|
@ -44,47 +45,20 @@ extern asmlinkage int _restore_fp_context(struct sigcontext __user *sc);
|
||||||
extern asmlinkage int fpu_emulator_save_context(struct sigcontext __user *sc);
|
extern asmlinkage int fpu_emulator_save_context(struct sigcontext __user *sc);
|
||||||
extern asmlinkage int fpu_emulator_restore_context(struct sigcontext __user *sc);
|
extern asmlinkage int fpu_emulator_restore_context(struct sigcontext __user *sc);
|
||||||
|
|
||||||
/*
|
|
||||||
* Horribly complicated - with the bloody RM9000 workarounds enabled
|
|
||||||
* the signal trampolines is moving to the end of the structure so we can
|
|
||||||
* increase the alignment without breaking software compatibility.
|
|
||||||
*/
|
|
||||||
#if ICACHE_REFILLS_WORKAROUND_WAR == 0
|
|
||||||
|
|
||||||
struct sigframe {
|
struct sigframe {
|
||||||
u32 sf_ass[4]; /* argument save space for o32 */
|
u32 sf_ass[4]; /* argument save space for o32 */
|
||||||
u32 sf_code[2]; /* signal trampoline */
|
u32 sf_pad[2]; /* Was: signal trampoline */
|
||||||
struct sigcontext sf_sc;
|
struct sigcontext sf_sc;
|
||||||
sigset_t sf_mask;
|
sigset_t sf_mask;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct rt_sigframe {
|
struct rt_sigframe {
|
||||||
u32 rs_ass[4]; /* argument save space for o32 */
|
u32 rs_ass[4]; /* argument save space for o32 */
|
||||||
u32 rs_code[2]; /* signal trampoline */
|
u32 rs_pad[2]; /* Was: signal trampoline */
|
||||||
struct siginfo rs_info;
|
struct siginfo rs_info;
|
||||||
struct ucontext rs_uc;
|
struct ucontext rs_uc;
|
||||||
};
|
};
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
struct sigframe {
|
|
||||||
u32 sf_ass[4]; /* argument save space for o32 */
|
|
||||||
u32 sf_pad[2];
|
|
||||||
struct sigcontext sf_sc; /* hw context */
|
|
||||||
sigset_t sf_mask;
|
|
||||||
u32 sf_code[8] ____cacheline_aligned; /* signal trampoline */
|
|
||||||
};
|
|
||||||
|
|
||||||
struct rt_sigframe {
|
|
||||||
u32 rs_ass[4]; /* argument save space for o32 */
|
|
||||||
u32 rs_pad[2];
|
|
||||||
struct siginfo rs_info;
|
|
||||||
struct ucontext rs_uc;
|
|
||||||
u32 rs_code[8] ____cacheline_aligned; /* signal trampoline */
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Helper routines
|
* Helper routines
|
||||||
*/
|
*/
|
||||||
|
@ -266,32 +240,6 @@ void __user *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs,
|
||||||
return (void __user *)((sp - frame_size) & (ICACHE_REFILLS_WORKAROUND_WAR ? ~(cpu_icache_line_size()-1) : ALMASK));
|
return (void __user *)((sp - frame_size) & (ICACHE_REFILLS_WORKAROUND_WAR ? ~(cpu_icache_line_size()-1) : ALMASK));
|
||||||
}
|
}
|
||||||
|
|
||||||
int install_sigtramp(unsigned int __user *tramp, unsigned int syscall)
|
|
||||||
{
|
|
||||||
int err;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Set up the return code ...
|
|
||||||
*
|
|
||||||
* li v0, __NR__foo_sigreturn
|
|
||||||
* syscall
|
|
||||||
*/
|
|
||||||
|
|
||||||
err = __put_user(0x24020000 + syscall, tramp + 0);
|
|
||||||
err |= __put_user(0x0000000c , tramp + 1);
|
|
||||||
if (ICACHE_REFILLS_WORKAROUND_WAR) {
|
|
||||||
err |= __put_user(0, tramp + 2);
|
|
||||||
err |= __put_user(0, tramp + 3);
|
|
||||||
err |= __put_user(0, tramp + 4);
|
|
||||||
err |= __put_user(0, tramp + 5);
|
|
||||||
err |= __put_user(0, tramp + 6);
|
|
||||||
err |= __put_user(0, tramp + 7);
|
|
||||||
}
|
|
||||||
flush_cache_sigtramp((unsigned long) tramp);
|
|
||||||
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Atomically swap in the new signal mask, and wait for a signal.
|
* Atomically swap in the new signal mask, and wait for a signal.
|
||||||
*/
|
*/
|
||||||
|
@ -484,8 +432,8 @@ badframe:
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_TRAD_SIGNALS
|
#ifdef CONFIG_TRAD_SIGNALS
|
||||||
static int setup_frame(struct k_sigaction * ka, struct pt_regs *regs,
|
static int setup_frame(void *sig_return, struct k_sigaction *ka,
|
||||||
int signr, sigset_t *set)
|
struct pt_regs *regs, int signr, sigset_t *set)
|
||||||
{
|
{
|
||||||
struct sigframe __user *frame;
|
struct sigframe __user *frame;
|
||||||
int err = 0;
|
int err = 0;
|
||||||
|
@ -494,8 +442,6 @@ static int setup_frame(struct k_sigaction * ka, struct pt_regs *regs,
|
||||||
if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
|
if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
|
||||||
goto give_sigsegv;
|
goto give_sigsegv;
|
||||||
|
|
||||||
err |= install_sigtramp(frame->sf_code, __NR_sigreturn);
|
|
||||||
|
|
||||||
err |= setup_sigcontext(regs, &frame->sf_sc);
|
err |= setup_sigcontext(regs, &frame->sf_sc);
|
||||||
err |= __copy_to_user(&frame->sf_mask, set, sizeof(*set));
|
err |= __copy_to_user(&frame->sf_mask, set, sizeof(*set));
|
||||||
if (err)
|
if (err)
|
||||||
|
@ -515,7 +461,7 @@ static int setup_frame(struct k_sigaction * ka, struct pt_regs *regs,
|
||||||
regs->regs[ 5] = 0;
|
regs->regs[ 5] = 0;
|
||||||
regs->regs[ 6] = (unsigned long) &frame->sf_sc;
|
regs->regs[ 6] = (unsigned long) &frame->sf_sc;
|
||||||
regs->regs[29] = (unsigned long) frame;
|
regs->regs[29] = (unsigned long) frame;
|
||||||
regs->regs[31] = (unsigned long) frame->sf_code;
|
regs->regs[31] = (unsigned long) sig_return;
|
||||||
regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;
|
regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;
|
||||||
|
|
||||||
DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n",
|
DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n",
|
||||||
|
@ -529,8 +475,9 @@ give_sigsegv:
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static int setup_rt_frame(struct k_sigaction * ka, struct pt_regs *regs,
|
static int setup_rt_frame(void *sig_return, struct k_sigaction *ka,
|
||||||
int signr, sigset_t *set, siginfo_t *info)
|
struct pt_regs *regs, int signr, sigset_t *set,
|
||||||
|
siginfo_t *info)
|
||||||
{
|
{
|
||||||
struct rt_sigframe __user *frame;
|
struct rt_sigframe __user *frame;
|
||||||
int err = 0;
|
int err = 0;
|
||||||
|
@ -539,8 +486,6 @@ static int setup_rt_frame(struct k_sigaction * ka, struct pt_regs *regs,
|
||||||
if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
|
if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
|
||||||
goto give_sigsegv;
|
goto give_sigsegv;
|
||||||
|
|
||||||
err |= install_sigtramp(frame->rs_code, __NR_rt_sigreturn);
|
|
||||||
|
|
||||||
/* Create siginfo. */
|
/* Create siginfo. */
|
||||||
err |= copy_siginfo_to_user(&frame->rs_info, info);
|
err |= copy_siginfo_to_user(&frame->rs_info, info);
|
||||||
|
|
||||||
|
@ -573,7 +518,7 @@ static int setup_rt_frame(struct k_sigaction * ka, struct pt_regs *regs,
|
||||||
regs->regs[ 5] = (unsigned long) &frame->rs_info;
|
regs->regs[ 5] = (unsigned long) &frame->rs_info;
|
||||||
regs->regs[ 6] = (unsigned long) &frame->rs_uc;
|
regs->regs[ 6] = (unsigned long) &frame->rs_uc;
|
||||||
regs->regs[29] = (unsigned long) frame;
|
regs->regs[29] = (unsigned long) frame;
|
||||||
regs->regs[31] = (unsigned long) frame->rs_code;
|
regs->regs[31] = (unsigned long) sig_return;
|
||||||
regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;
|
regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;
|
||||||
|
|
||||||
DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n",
|
DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n",
|
||||||
|
@ -590,8 +535,11 @@ give_sigsegv:
|
||||||
struct mips_abi mips_abi = {
|
struct mips_abi mips_abi = {
|
||||||
#ifdef CONFIG_TRAD_SIGNALS
|
#ifdef CONFIG_TRAD_SIGNALS
|
||||||
.setup_frame = setup_frame,
|
.setup_frame = setup_frame,
|
||||||
|
.signal_return_offset = offsetof(struct mips_vdso, signal_trampoline),
|
||||||
#endif
|
#endif
|
||||||
.setup_rt_frame = setup_rt_frame,
|
.setup_rt_frame = setup_rt_frame,
|
||||||
|
.rt_signal_return_offset =
|
||||||
|
offsetof(struct mips_vdso, rt_signal_trampoline),
|
||||||
.restart = __NR_restart_syscall
|
.restart = __NR_restart_syscall
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -599,6 +547,8 @@ static int handle_signal(unsigned long sig, siginfo_t *info,
|
||||||
struct k_sigaction *ka, sigset_t *oldset, struct pt_regs *regs)
|
struct k_sigaction *ka, sigset_t *oldset, struct pt_regs *regs)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
struct mips_abi *abi = current->thread.abi;
|
||||||
|
void *vdso = current->mm->context.vdso;
|
||||||
|
|
||||||
switch(regs->regs[0]) {
|
switch(regs->regs[0]) {
|
||||||
case ERESTART_RESTARTBLOCK:
|
case ERESTART_RESTARTBLOCK:
|
||||||
|
@ -619,9 +569,11 @@ static int handle_signal(unsigned long sig, siginfo_t *info,
|
||||||
regs->regs[0] = 0; /* Don't deal with this again. */
|
regs->regs[0] = 0; /* Don't deal with this again. */
|
||||||
|
|
||||||
if (sig_uses_siginfo(ka))
|
if (sig_uses_siginfo(ka))
|
||||||
ret = current->thread.abi->setup_rt_frame(ka, regs, sig, oldset, info);
|
ret = abi->setup_rt_frame(vdso + abi->rt_signal_return_offset,
|
||||||
|
ka, regs, sig, oldset, info);
|
||||||
else
|
else
|
||||||
ret = current->thread.abi->setup_frame(ka, regs, sig, oldset);
|
ret = abi->setup_frame(vdso + abi->signal_return_offset,
|
||||||
|
ka, regs, sig, oldset);
|
||||||
|
|
||||||
spin_lock_irq(¤t->sighand->siglock);
|
spin_lock_irq(¤t->sighand->siglock);
|
||||||
sigorsets(¤t->blocked, ¤t->blocked, &ka->sa.sa_mask);
|
sigorsets(¤t->blocked, ¤t->blocked, &ka->sa.sa_mask);
|
||||||
|
|
|
@ -32,6 +32,7 @@
|
||||||
#include <asm/system.h>
|
#include <asm/system.h>
|
||||||
#include <asm/fpu.h>
|
#include <asm/fpu.h>
|
||||||
#include <asm/war.h>
|
#include <asm/war.h>
|
||||||
|
#include <asm/vdso.h>
|
||||||
|
|
||||||
#include "signal-common.h"
|
#include "signal-common.h"
|
||||||
|
|
||||||
|
@ -47,8 +48,6 @@ extern asmlinkage int fpu_emulator_restore_context32(struct sigcontext32 __user
|
||||||
/*
|
/*
|
||||||
* Including <asm/unistd.h> would give use the 64-bit syscall numbers ...
|
* Including <asm/unistd.h> would give use the 64-bit syscall numbers ...
|
||||||
*/
|
*/
|
||||||
#define __NR_O32_sigreturn 4119
|
|
||||||
#define __NR_O32_rt_sigreturn 4193
|
|
||||||
#define __NR_O32_restart_syscall 4253
|
#define __NR_O32_restart_syscall 4253
|
||||||
|
|
||||||
/* 32-bit compatibility types */
|
/* 32-bit compatibility types */
|
||||||
|
@ -77,47 +76,20 @@ struct ucontext32 {
|
||||||
compat_sigset_t uc_sigmask; /* mask last for extensibility */
|
compat_sigset_t uc_sigmask; /* mask last for extensibility */
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
|
||||||
* Horribly complicated - with the bloody RM9000 workarounds enabled
|
|
||||||
* the signal trampolines is moving to the end of the structure so we can
|
|
||||||
* increase the alignment without breaking software compatibility.
|
|
||||||
*/
|
|
||||||
#if ICACHE_REFILLS_WORKAROUND_WAR == 0
|
|
||||||
|
|
||||||
struct sigframe32 {
|
struct sigframe32 {
|
||||||
u32 sf_ass[4]; /* argument save space for o32 */
|
u32 sf_ass[4]; /* argument save space for o32 */
|
||||||
u32 sf_code[2]; /* signal trampoline */
|
u32 sf_pad[2]; /* Was: signal trampoline */
|
||||||
struct sigcontext32 sf_sc;
|
struct sigcontext32 sf_sc;
|
||||||
compat_sigset_t sf_mask;
|
compat_sigset_t sf_mask;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct rt_sigframe32 {
|
struct rt_sigframe32 {
|
||||||
u32 rs_ass[4]; /* argument save space for o32 */
|
u32 rs_ass[4]; /* argument save space for o32 */
|
||||||
u32 rs_code[2]; /* signal trampoline */
|
u32 rs_pad[2]; /* Was: signal trampoline */
|
||||||
compat_siginfo_t rs_info;
|
compat_siginfo_t rs_info;
|
||||||
struct ucontext32 rs_uc;
|
struct ucontext32 rs_uc;
|
||||||
};
|
};
|
||||||
|
|
||||||
#else /* ICACHE_REFILLS_WORKAROUND_WAR */
|
|
||||||
|
|
||||||
struct sigframe32 {
|
|
||||||
u32 sf_ass[4]; /* argument save space for o32 */
|
|
||||||
u32 sf_pad[2];
|
|
||||||
struct sigcontext32 sf_sc; /* hw context */
|
|
||||||
compat_sigset_t sf_mask;
|
|
||||||
u32 sf_code[8] ____cacheline_aligned; /* signal trampoline */
|
|
||||||
};
|
|
||||||
|
|
||||||
struct rt_sigframe32 {
|
|
||||||
u32 rs_ass[4]; /* argument save space for o32 */
|
|
||||||
u32 rs_pad[2];
|
|
||||||
compat_siginfo_t rs_info;
|
|
||||||
struct ucontext32 rs_uc;
|
|
||||||
u32 rs_code[8] __attribute__((aligned(32))); /* signal trampoline */
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /* !ICACHE_REFILLS_WORKAROUND_WAR */
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* sigcontext handlers
|
* sigcontext handlers
|
||||||
*/
|
*/
|
||||||
|
@ -598,8 +570,8 @@ badframe:
|
||||||
force_sig(SIGSEGV, current);
|
force_sig(SIGSEGV, current);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int setup_frame_32(struct k_sigaction * ka, struct pt_regs *regs,
|
static int setup_frame_32(void *sig_return, struct k_sigaction *ka,
|
||||||
int signr, sigset_t *set)
|
struct pt_regs *regs, int signr, sigset_t *set)
|
||||||
{
|
{
|
||||||
struct sigframe32 __user *frame;
|
struct sigframe32 __user *frame;
|
||||||
int err = 0;
|
int err = 0;
|
||||||
|
@ -608,8 +580,6 @@ static int setup_frame_32(struct k_sigaction * ka, struct pt_regs *regs,
|
||||||
if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
|
if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
|
||||||
goto give_sigsegv;
|
goto give_sigsegv;
|
||||||
|
|
||||||
err |= install_sigtramp(frame->sf_code, __NR_O32_sigreturn);
|
|
||||||
|
|
||||||
err |= setup_sigcontext32(regs, &frame->sf_sc);
|
err |= setup_sigcontext32(regs, &frame->sf_sc);
|
||||||
err |= __copy_conv_sigset_to_user(&frame->sf_mask, set);
|
err |= __copy_conv_sigset_to_user(&frame->sf_mask, set);
|
||||||
|
|
||||||
|
@ -630,7 +600,7 @@ static int setup_frame_32(struct k_sigaction * ka, struct pt_regs *regs,
|
||||||
regs->regs[ 5] = 0;
|
regs->regs[ 5] = 0;
|
||||||
regs->regs[ 6] = (unsigned long) &frame->sf_sc;
|
regs->regs[ 6] = (unsigned long) &frame->sf_sc;
|
||||||
regs->regs[29] = (unsigned long) frame;
|
regs->regs[29] = (unsigned long) frame;
|
||||||
regs->regs[31] = (unsigned long) frame->sf_code;
|
regs->regs[31] = (unsigned long) sig_return;
|
||||||
regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;
|
regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;
|
||||||
|
|
||||||
DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n",
|
DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n",
|
||||||
|
@ -644,8 +614,9 @@ give_sigsegv:
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int setup_rt_frame_32(struct k_sigaction * ka, struct pt_regs *regs,
|
static int setup_rt_frame_32(void *sig_return, struct k_sigaction *ka,
|
||||||
int signr, sigset_t *set, siginfo_t *info)
|
struct pt_regs *regs, int signr, sigset_t *set,
|
||||||
|
siginfo_t *info)
|
||||||
{
|
{
|
||||||
struct rt_sigframe32 __user *frame;
|
struct rt_sigframe32 __user *frame;
|
||||||
int err = 0;
|
int err = 0;
|
||||||
|
@ -655,8 +626,6 @@ static int setup_rt_frame_32(struct k_sigaction * ka, struct pt_regs *regs,
|
||||||
if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
|
if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
|
||||||
goto give_sigsegv;
|
goto give_sigsegv;
|
||||||
|
|
||||||
err |= install_sigtramp(frame->rs_code, __NR_O32_rt_sigreturn);
|
|
||||||
|
|
||||||
/* Convert (siginfo_t -> compat_siginfo_t) and copy to user. */
|
/* Convert (siginfo_t -> compat_siginfo_t) and copy to user. */
|
||||||
err |= copy_siginfo_to_user32(&frame->rs_info, info);
|
err |= copy_siginfo_to_user32(&frame->rs_info, info);
|
||||||
|
|
||||||
|
@ -690,7 +659,7 @@ static int setup_rt_frame_32(struct k_sigaction * ka, struct pt_regs *regs,
|
||||||
regs->regs[ 5] = (unsigned long) &frame->rs_info;
|
regs->regs[ 5] = (unsigned long) &frame->rs_info;
|
||||||
regs->regs[ 6] = (unsigned long) &frame->rs_uc;
|
regs->regs[ 6] = (unsigned long) &frame->rs_uc;
|
||||||
regs->regs[29] = (unsigned long) frame;
|
regs->regs[29] = (unsigned long) frame;
|
||||||
regs->regs[31] = (unsigned long) frame->rs_code;
|
regs->regs[31] = (unsigned long) sig_return;
|
||||||
regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;
|
regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;
|
||||||
|
|
||||||
DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n",
|
DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n",
|
||||||
|
@ -709,7 +678,11 @@ give_sigsegv:
|
||||||
*/
|
*/
|
||||||
struct mips_abi mips_abi_32 = {
|
struct mips_abi mips_abi_32 = {
|
||||||
.setup_frame = setup_frame_32,
|
.setup_frame = setup_frame_32,
|
||||||
|
.signal_return_offset =
|
||||||
|
offsetof(struct mips_vdso, o32_signal_trampoline),
|
||||||
.setup_rt_frame = setup_rt_frame_32,
|
.setup_rt_frame = setup_rt_frame_32,
|
||||||
|
.rt_signal_return_offset =
|
||||||
|
offsetof(struct mips_vdso, o32_rt_signal_trampoline),
|
||||||
.restart = __NR_O32_restart_syscall
|
.restart = __NR_O32_restart_syscall
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -39,13 +39,13 @@
|
||||||
#include <asm/fpu.h>
|
#include <asm/fpu.h>
|
||||||
#include <asm/cpu-features.h>
|
#include <asm/cpu-features.h>
|
||||||
#include <asm/war.h>
|
#include <asm/war.h>
|
||||||
|
#include <asm/vdso.h>
|
||||||
|
|
||||||
#include "signal-common.h"
|
#include "signal-common.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Including <asm/unistd.h> would give use the 64-bit syscall numbers ...
|
* Including <asm/unistd.h> would give use the 64-bit syscall numbers ...
|
||||||
*/
|
*/
|
||||||
#define __NR_N32_rt_sigreturn 6211
|
|
||||||
#define __NR_N32_restart_syscall 6214
|
#define __NR_N32_restart_syscall 6214
|
||||||
|
|
||||||
extern int setup_sigcontext(struct pt_regs *, struct sigcontext __user *);
|
extern int setup_sigcontext(struct pt_regs *, struct sigcontext __user *);
|
||||||
|
@ -67,27 +67,13 @@ struct ucontextn32 {
|
||||||
compat_sigset_t uc_sigmask; /* mask last for extensibility */
|
compat_sigset_t uc_sigmask; /* mask last for extensibility */
|
||||||
};
|
};
|
||||||
|
|
||||||
#if ICACHE_REFILLS_WORKAROUND_WAR == 0
|
|
||||||
|
|
||||||
struct rt_sigframe_n32 {
|
struct rt_sigframe_n32 {
|
||||||
u32 rs_ass[4]; /* argument save space for o32 */
|
u32 rs_ass[4]; /* argument save space for o32 */
|
||||||
u32 rs_code[2]; /* signal trampoline */
|
u32 rs_pad[2]; /* Was: signal trampoline */
|
||||||
struct compat_siginfo rs_info;
|
struct compat_siginfo rs_info;
|
||||||
struct ucontextn32 rs_uc;
|
struct ucontextn32 rs_uc;
|
||||||
};
|
};
|
||||||
|
|
||||||
#else /* ICACHE_REFILLS_WORKAROUND_WAR */
|
|
||||||
|
|
||||||
struct rt_sigframe_n32 {
|
|
||||||
u32 rs_ass[4]; /* argument save space for o32 */
|
|
||||||
u32 rs_pad[2];
|
|
||||||
struct compat_siginfo rs_info;
|
|
||||||
struct ucontextn32 rs_uc;
|
|
||||||
u32 rs_code[8] ____cacheline_aligned; /* signal trampoline */
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /* !ICACHE_REFILLS_WORKAROUND_WAR */
|
|
||||||
|
|
||||||
extern void sigset_from_compat(sigset_t *set, compat_sigset_t *compat);
|
extern void sigset_from_compat(sigset_t *set, compat_sigset_t *compat);
|
||||||
|
|
||||||
asmlinkage int sysn32_rt_sigsuspend(nabi_no_regargs struct pt_regs regs)
|
asmlinkage int sysn32_rt_sigsuspend(nabi_no_regargs struct pt_regs regs)
|
||||||
|
@ -173,7 +159,7 @@ badframe:
|
||||||
force_sig(SIGSEGV, current);
|
force_sig(SIGSEGV, current);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int setup_rt_frame_n32(struct k_sigaction * ka,
|
static int setup_rt_frame_n32(void *sig_return, struct k_sigaction *ka,
|
||||||
struct pt_regs *regs, int signr, sigset_t *set, siginfo_t *info)
|
struct pt_regs *regs, int signr, sigset_t *set, siginfo_t *info)
|
||||||
{
|
{
|
||||||
struct rt_sigframe_n32 __user *frame;
|
struct rt_sigframe_n32 __user *frame;
|
||||||
|
@ -184,8 +170,6 @@ static int setup_rt_frame_n32(struct k_sigaction * ka,
|
||||||
if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
|
if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
|
||||||
goto give_sigsegv;
|
goto give_sigsegv;
|
||||||
|
|
||||||
install_sigtramp(frame->rs_code, __NR_N32_rt_sigreturn);
|
|
||||||
|
|
||||||
/* Create siginfo. */
|
/* Create siginfo. */
|
||||||
err |= copy_siginfo_to_user32(&frame->rs_info, info);
|
err |= copy_siginfo_to_user32(&frame->rs_info, info);
|
||||||
|
|
||||||
|
@ -219,7 +203,7 @@ static int setup_rt_frame_n32(struct k_sigaction * ka,
|
||||||
regs->regs[ 5] = (unsigned long) &frame->rs_info;
|
regs->regs[ 5] = (unsigned long) &frame->rs_info;
|
||||||
regs->regs[ 6] = (unsigned long) &frame->rs_uc;
|
regs->regs[ 6] = (unsigned long) &frame->rs_uc;
|
||||||
regs->regs[29] = (unsigned long) frame;
|
regs->regs[29] = (unsigned long) frame;
|
||||||
regs->regs[31] = (unsigned long) frame->rs_code;
|
regs->regs[31] = (unsigned long) sig_return;
|
||||||
regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;
|
regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;
|
||||||
|
|
||||||
DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n",
|
DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n",
|
||||||
|
@ -235,5 +219,7 @@ give_sigsegv:
|
||||||
|
|
||||||
struct mips_abi mips_abi_n32 = {
|
struct mips_abi mips_abi_n32 = {
|
||||||
.setup_rt_frame = setup_rt_frame_n32,
|
.setup_rt_frame = setup_rt_frame_n32,
|
||||||
|
.rt_signal_return_offset =
|
||||||
|
offsetof(struct mips_vdso, n32_rt_signal_trampoline),
|
||||||
.restart = __NR_N32_restart_syscall
|
.restart = __NR_N32_restart_syscall
|
||||||
};
|
};
|
||||||
|
|
|
@ -182,7 +182,7 @@ static int vpemask[2][8] = {
|
||||||
{0, 0, 0, 0, 0, 0, 0, 1}
|
{0, 0, 0, 0, 0, 0, 0, 1}
|
||||||
};
|
};
|
||||||
int tcnoprog[NR_CPUS];
|
int tcnoprog[NR_CPUS];
|
||||||
static atomic_t idle_hook_initialized = {0};
|
static atomic_t idle_hook_initialized = ATOMIC_INIT(0);
|
||||||
static int clock_hang_reported[NR_CPUS];
|
static int clock_hang_reported[NR_CPUS];
|
||||||
|
|
||||||
#endif /* CONFIG_SMTC_IDLE_HOOK_DEBUG */
|
#endif /* CONFIG_SMTC_IDLE_HOOK_DEBUG */
|
||||||
|
|
|
@ -79,7 +79,11 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr,
|
||||||
int do_color_align;
|
int do_color_align;
|
||||||
unsigned long task_size;
|
unsigned long task_size;
|
||||||
|
|
||||||
task_size = STACK_TOP;
|
#ifdef CONFIG_32BIT
|
||||||
|
task_size = TASK_SIZE;
|
||||||
|
#else /* Must be CONFIG_64BIT*/
|
||||||
|
task_size = test_thread_flag(TIF_32BIT_ADDR) ? TASK_SIZE32 : TASK_SIZE;
|
||||||
|
#endif
|
||||||
|
|
||||||
if (len > task_size)
|
if (len > task_size)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
|
@ -1599,7 +1599,7 @@ void __init trap_init(void)
|
||||||
ebase = (unsigned long)
|
ebase = (unsigned long)
|
||||||
__alloc_bootmem(size, 1 << fls(size), 0);
|
__alloc_bootmem(size, 1 << fls(size), 0);
|
||||||
} else {
|
} else {
|
||||||
ebase = CAC_BASE;
|
ebase = CKSEG0;
|
||||||
if (cpu_has_mips_r2)
|
if (cpu_has_mips_r2)
|
||||||
ebase += (read_c0_ebase() & 0x3ffff000);
|
ebase += (read_c0_ebase() & 0x3ffff000);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,112 @@
|
||||||
|
/*
|
||||||
|
* This file is subject to the terms and conditions of the GNU General Public
|
||||||
|
* License. See the file "COPYING" in the main directory of this archive
|
||||||
|
* for more details.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2009, 2010 Cavium Networks, Inc.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <linux/kernel.h>
|
||||||
|
#include <linux/err.h>
|
||||||
|
#include <linux/sched.h>
|
||||||
|
#include <linux/mm.h>
|
||||||
|
#include <linux/init.h>
|
||||||
|
#include <linux/binfmts.h>
|
||||||
|
#include <linux/elf.h>
|
||||||
|
#include <linux/vmalloc.h>
|
||||||
|
#include <linux/unistd.h>
|
||||||
|
|
||||||
|
#include <asm/vdso.h>
|
||||||
|
#include <asm/uasm.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Including <asm/unistd.h> would give use the 64-bit syscall numbers ...
|
||||||
|
*/
|
||||||
|
#define __NR_O32_sigreturn 4119
|
||||||
|
#define __NR_O32_rt_sigreturn 4193
|
||||||
|
#define __NR_N32_rt_sigreturn 6211
|
||||||
|
|
||||||
|
static struct page *vdso_page;
|
||||||
|
|
||||||
|
static void __init install_trampoline(u32 *tramp, unsigned int sigreturn)
|
||||||
|
{
|
||||||
|
uasm_i_addiu(&tramp, 2, 0, sigreturn); /* li v0, sigreturn */
|
||||||
|
uasm_i_syscall(&tramp, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int __init init_vdso(void)
|
||||||
|
{
|
||||||
|
struct mips_vdso *vdso;
|
||||||
|
|
||||||
|
vdso_page = alloc_page(GFP_KERNEL);
|
||||||
|
if (!vdso_page)
|
||||||
|
panic("Cannot allocate vdso");
|
||||||
|
|
||||||
|
vdso = vmap(&vdso_page, 1, 0, PAGE_KERNEL);
|
||||||
|
if (!vdso)
|
||||||
|
panic("Cannot map vdso");
|
||||||
|
clear_page(vdso);
|
||||||
|
|
||||||
|
install_trampoline(vdso->rt_signal_trampoline, __NR_rt_sigreturn);
|
||||||
|
#ifdef CONFIG_32BIT
|
||||||
|
install_trampoline(vdso->signal_trampoline, __NR_sigreturn);
|
||||||
|
#else
|
||||||
|
install_trampoline(vdso->n32_rt_signal_trampoline,
|
||||||
|
__NR_N32_rt_sigreturn);
|
||||||
|
install_trampoline(vdso->o32_signal_trampoline, __NR_O32_sigreturn);
|
||||||
|
install_trampoline(vdso->o32_rt_signal_trampoline,
|
||||||
|
__NR_O32_rt_sigreturn);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
vunmap(vdso);
|
||||||
|
|
||||||
|
pr_notice("init_vdso successfull\n");
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
device_initcall(init_vdso);
|
||||||
|
|
||||||
|
static unsigned long vdso_addr(unsigned long start)
|
||||||
|
{
|
||||||
|
return STACK_TOP;
|
||||||
|
}
|
||||||
|
|
||||||
|
int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
unsigned long addr;
|
||||||
|
struct mm_struct *mm = current->mm;
|
||||||
|
|
||||||
|
down_write(&mm->mmap_sem);
|
||||||
|
|
||||||
|
addr = vdso_addr(mm->start_stack);
|
||||||
|
|
||||||
|
addr = get_unmapped_area(NULL, addr, PAGE_SIZE, 0, 0);
|
||||||
|
if (IS_ERR_VALUE(addr)) {
|
||||||
|
ret = addr;
|
||||||
|
goto up_fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = install_special_mapping(mm, addr, PAGE_SIZE,
|
||||||
|
VM_READ|VM_EXEC|
|
||||||
|
VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC|
|
||||||
|
VM_ALWAYSDUMP,
|
||||||
|
&vdso_page);
|
||||||
|
|
||||||
|
if (ret)
|
||||||
|
goto up_fail;
|
||||||
|
|
||||||
|
mm->context.vdso = (void *)addr;
|
||||||
|
|
||||||
|
up_fail:
|
||||||
|
up_write(&mm->mmap_sem);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *arch_vma_name(struct vm_area_struct *vma)
|
||||||
|
{
|
||||||
|
if (vma->vm_mm && vma->vm_start == (long)vma->vm_mm->context.vdso)
|
||||||
|
return "[vdso]";
|
||||||
|
return NULL;
|
||||||
|
}
|
|
@ -41,7 +41,7 @@ EXPORT_SYMBOL(__delay);
|
||||||
|
|
||||||
void __udelay(unsigned long us)
|
void __udelay(unsigned long us)
|
||||||
{
|
{
|
||||||
unsigned int lpj = current_cpu_data.udelay_val;
|
unsigned int lpj = raw_current_cpu_data.udelay_val;
|
||||||
|
|
||||||
__delay((us * 0x000010c7ull * HZ * lpj) >> 32);
|
__delay((us * 0x000010c7ull * HZ * lpj) >> 32);
|
||||||
}
|
}
|
||||||
|
@ -49,7 +49,7 @@ EXPORT_SYMBOL(__udelay);
|
||||||
|
|
||||||
void __ndelay(unsigned long ns)
|
void __ndelay(unsigned long ns)
|
||||||
{
|
{
|
||||||
unsigned int lpj = current_cpu_data.udelay_val;
|
unsigned int lpj = raw_current_cpu_data.udelay_val;
|
||||||
|
|
||||||
__delay((ns * 0x00000005ull * HZ * lpj) >> 32);
|
__delay((ns * 0x00000005ull * HZ * lpj) >> 32);
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,8 +17,7 @@ struct DWstruct {
|
||||||
#error I feel sick.
|
#error I feel sick.
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef union
|
typedef union {
|
||||||
{
|
|
||||||
struct DWstruct s;
|
struct DWstruct s;
|
||||||
long long ll;
|
long long ll;
|
||||||
} DWunion;
|
} DWunion;
|
||||||
|
|
|
@ -133,7 +133,7 @@ void __update_cache(struct vm_area_struct *vma, unsigned long address,
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned long _page_cachable_default;
|
unsigned long _page_cachable_default;
|
||||||
EXPORT_SYMBOL_GPL(_page_cachable_default);
|
EXPORT_SYMBOL(_page_cachable_default);
|
||||||
|
|
||||||
static inline void setup_protection_map(void)
|
static inline void setup_protection_map(void)
|
||||||
{
|
{
|
||||||
|
|
|
@ -788,10 +788,15 @@ static void __cpuinit build_r4000_tlb_refill_handler(void)
|
||||||
* create the plain linear handler
|
* create the plain linear handler
|
||||||
*/
|
*/
|
||||||
if (bcm1250_m3_war()) {
|
if (bcm1250_m3_war()) {
|
||||||
UASM_i_MFC0(&p, K0, C0_BADVADDR);
|
unsigned int segbits = 44;
|
||||||
UASM_i_MFC0(&p, K1, C0_ENTRYHI);
|
|
||||||
|
uasm_i_dmfc0(&p, K0, C0_BADVADDR);
|
||||||
|
uasm_i_dmfc0(&p, K1, C0_ENTRYHI);
|
||||||
uasm_i_xor(&p, K0, K0, K1);
|
uasm_i_xor(&p, K0, K0, K1);
|
||||||
UASM_i_SRL(&p, K0, K0, PAGE_SHIFT + 1);
|
uasm_i_dsrl32(&p, K1, K0, 62 - 32);
|
||||||
|
uasm_i_dsrl(&p, K0, K0, 12 + 1);
|
||||||
|
uasm_i_dsll32(&p, K0, K0, 64 + 12 + 1 - segbits - 32);
|
||||||
|
uasm_i_or(&p, K0, K0, K1);
|
||||||
uasm_il_bnez(&p, &r, K0, label_leave);
|
uasm_il_bnez(&p, &r, K0, label_leave);
|
||||||
/* No need for uasm_i_nop */
|
/* No need for uasm_i_nop */
|
||||||
}
|
}
|
||||||
|
@ -1312,10 +1317,15 @@ static void __cpuinit build_r4000_tlb_load_handler(void)
|
||||||
memset(relocs, 0, sizeof(relocs));
|
memset(relocs, 0, sizeof(relocs));
|
||||||
|
|
||||||
if (bcm1250_m3_war()) {
|
if (bcm1250_m3_war()) {
|
||||||
UASM_i_MFC0(&p, K0, C0_BADVADDR);
|
unsigned int segbits = 44;
|
||||||
UASM_i_MFC0(&p, K1, C0_ENTRYHI);
|
|
||||||
|
uasm_i_dmfc0(&p, K0, C0_BADVADDR);
|
||||||
|
uasm_i_dmfc0(&p, K1, C0_ENTRYHI);
|
||||||
uasm_i_xor(&p, K0, K0, K1);
|
uasm_i_xor(&p, K0, K0, K1);
|
||||||
UASM_i_SRL(&p, K0, K0, PAGE_SHIFT + 1);
|
uasm_i_dsrl32(&p, K1, K0, 62 - 32);
|
||||||
|
uasm_i_dsrl(&p, K0, K0, 12 + 1);
|
||||||
|
uasm_i_dsll32(&p, K0, K0, 64 + 12 + 1 - segbits - 32);
|
||||||
|
uasm_i_or(&p, K0, K0, K1);
|
||||||
uasm_il_bnez(&p, &r, K0, label_leave);
|
uasm_il_bnez(&p, &r, K0, label_leave);
|
||||||
/* No need for uasm_i_nop */
|
/* No need for uasm_i_nop */
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,7 +31,8 @@ enum fields {
|
||||||
BIMM = 0x040,
|
BIMM = 0x040,
|
||||||
JIMM = 0x080,
|
JIMM = 0x080,
|
||||||
FUNC = 0x100,
|
FUNC = 0x100,
|
||||||
SET = 0x200
|
SET = 0x200,
|
||||||
|
SCIMM = 0x400
|
||||||
};
|
};
|
||||||
|
|
||||||
#define OP_MASK 0x3f
|
#define OP_MASK 0x3f
|
||||||
|
@ -52,6 +53,8 @@ enum fields {
|
||||||
#define FUNC_SH 0
|
#define FUNC_SH 0
|
||||||
#define SET_MASK 0x7
|
#define SET_MASK 0x7
|
||||||
#define SET_SH 0
|
#define SET_SH 0
|
||||||
|
#define SCIMM_MASK 0xfffff
|
||||||
|
#define SCIMM_SH 6
|
||||||
|
|
||||||
enum opcode {
|
enum opcode {
|
||||||
insn_invalid,
|
insn_invalid,
|
||||||
|
@ -61,10 +64,10 @@ enum opcode {
|
||||||
insn_dmtc0, insn_dsll, insn_dsll32, insn_dsra, insn_dsrl,
|
insn_dmtc0, insn_dsll, insn_dsll32, insn_dsra, insn_dsrl,
|
||||||
insn_dsrl32, insn_drotr, insn_dsubu, insn_eret, insn_j, insn_jal,
|
insn_dsrl32, insn_drotr, insn_dsubu, insn_eret, insn_j, insn_jal,
|
||||||
insn_jr, insn_ld, insn_ll, insn_lld, insn_lui, insn_lw, insn_mfc0,
|
insn_jr, insn_ld, insn_ll, insn_lld, insn_lui, insn_lw, insn_mfc0,
|
||||||
insn_mtc0, insn_ori, insn_pref, insn_rfe, insn_sc, insn_scd,
|
insn_mtc0, insn_or, insn_ori, insn_pref, insn_rfe, insn_sc, insn_scd,
|
||||||
insn_sd, insn_sll, insn_sra, insn_srl, insn_rotr, insn_subu, insn_sw,
|
insn_sd, insn_sll, insn_sra, insn_srl, insn_rotr, insn_subu, insn_sw,
|
||||||
insn_tlbp, insn_tlbr, insn_tlbwi, insn_tlbwr, insn_xor, insn_xori,
|
insn_tlbp, insn_tlbr, insn_tlbwi, insn_tlbwr, insn_xor, insn_xori,
|
||||||
insn_dins
|
insn_dins, insn_syscall
|
||||||
};
|
};
|
||||||
|
|
||||||
struct insn {
|
struct insn {
|
||||||
|
@ -117,6 +120,7 @@ static struct insn insn_table[] __cpuinitdata = {
|
||||||
{ insn_lw, M(lw_op, 0, 0, 0, 0, 0), RS | RT | SIMM },
|
{ insn_lw, M(lw_op, 0, 0, 0, 0, 0), RS | RT | SIMM },
|
||||||
{ insn_mfc0, M(cop0_op, mfc_op, 0, 0, 0, 0), RT | RD | SET},
|
{ insn_mfc0, M(cop0_op, mfc_op, 0, 0, 0, 0), RT | RD | SET},
|
||||||
{ insn_mtc0, M(cop0_op, mtc_op, 0, 0, 0, 0), RT | RD | SET},
|
{ insn_mtc0, M(cop0_op, mtc_op, 0, 0, 0, 0), RT | RD | SET},
|
||||||
|
{ insn_or, M(spec_op, 0, 0, 0, 0, or_op), RS | RT | RD },
|
||||||
{ insn_ori, M(ori_op, 0, 0, 0, 0, 0), RS | RT | UIMM },
|
{ insn_ori, M(ori_op, 0, 0, 0, 0, 0), RS | RT | UIMM },
|
||||||
{ insn_pref, M(pref_op, 0, 0, 0, 0, 0), RS | RT | SIMM },
|
{ insn_pref, M(pref_op, 0, 0, 0, 0, 0), RS | RT | SIMM },
|
||||||
{ insn_rfe, M(cop0_op, cop_op, 0, 0, 0, rfe_op), 0 },
|
{ insn_rfe, M(cop0_op, cop_op, 0, 0, 0, rfe_op), 0 },
|
||||||
|
@ -136,6 +140,7 @@ static struct insn insn_table[] __cpuinitdata = {
|
||||||
{ insn_xor, M(spec_op, 0, 0, 0, 0, xor_op), RS | RT | RD },
|
{ insn_xor, M(spec_op, 0, 0, 0, 0, xor_op), RS | RT | RD },
|
||||||
{ insn_xori, M(xori_op, 0, 0, 0, 0, 0), RS | RT | UIMM },
|
{ insn_xori, M(xori_op, 0, 0, 0, 0, 0), RS | RT | UIMM },
|
||||||
{ insn_dins, M(spec3_op, 0, 0, 0, 0, dins_op), RS | RT | RD | RE },
|
{ insn_dins, M(spec3_op, 0, 0, 0, 0, dins_op), RS | RT | RD | RE },
|
||||||
|
{ insn_syscall, M(spec_op, 0, 0, 0, 0, syscall_op), SCIMM},
|
||||||
{ insn_invalid, 0, 0 }
|
{ insn_invalid, 0, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -208,6 +213,14 @@ static inline __cpuinit u32 build_jimm(u32 arg)
|
||||||
return (arg >> 2) & JIMM_MASK;
|
return (arg >> 2) & JIMM_MASK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline __cpuinit u32 build_scimm(u32 arg)
|
||||||
|
{
|
||||||
|
if (arg & ~SCIMM_MASK)
|
||||||
|
printk(KERN_WARNING "Micro-assembler field overflow\n");
|
||||||
|
|
||||||
|
return (arg & SCIMM_MASK) << SCIMM_SH;
|
||||||
|
}
|
||||||
|
|
||||||
static inline __cpuinit u32 build_func(u32 arg)
|
static inline __cpuinit u32 build_func(u32 arg)
|
||||||
{
|
{
|
||||||
if (arg & ~FUNC_MASK)
|
if (arg & ~FUNC_MASK)
|
||||||
|
@ -266,6 +279,8 @@ static void __cpuinit build_insn(u32 **buf, enum opcode opc, ...)
|
||||||
op |= build_func(va_arg(ap, u32));
|
op |= build_func(va_arg(ap, u32));
|
||||||
if (ip->fields & SET)
|
if (ip->fields & SET)
|
||||||
op |= build_set(va_arg(ap, u32));
|
op |= build_set(va_arg(ap, u32));
|
||||||
|
if (ip->fields & SCIMM)
|
||||||
|
op |= build_scimm(va_arg(ap, u32));
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
|
|
||||||
**buf = op;
|
**buf = op;
|
||||||
|
@ -373,6 +388,7 @@ I_u2s3u1(_lw)
|
||||||
I_u1u2u3(_mfc0)
|
I_u1u2u3(_mfc0)
|
||||||
I_u1u2u3(_mtc0)
|
I_u1u2u3(_mtc0)
|
||||||
I_u2u1u3(_ori)
|
I_u2u1u3(_ori)
|
||||||
|
I_u3u1u2(_or)
|
||||||
I_u2s3u1(_pref)
|
I_u2s3u1(_pref)
|
||||||
I_0(_rfe)
|
I_0(_rfe)
|
||||||
I_u2s3u1(_sc)
|
I_u2s3u1(_sc)
|
||||||
|
@ -391,6 +407,7 @@ I_0(_tlbwr)
|
||||||
I_u3u1u2(_xor)
|
I_u3u1u2(_xor)
|
||||||
I_u2u1u3(_xori)
|
I_u2u1u3(_xori)
|
||||||
I_u2u1msbu3(_dins);
|
I_u2u1msbu3(_dins);
|
||||||
|
I_u1(_syscall);
|
||||||
|
|
||||||
/* Handle labels. */
|
/* Handle labels. */
|
||||||
void __cpuinit uasm_build_label(struct uasm_label **lab, u32 *addr, int lid)
|
void __cpuinit uasm_build_label(struct uasm_label **lab, u32 *addr, int lid)
|
||||||
|
|
|
@ -180,15 +180,21 @@ struct pci_ops loongson_pci_ops = {
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef CONFIG_CS5536
|
#ifdef CONFIG_CS5536
|
||||||
|
DEFINE_RAW_SPINLOCK(msr_lock);
|
||||||
|
|
||||||
void _rdmsr(u32 msr, u32 *hi, u32 *lo)
|
void _rdmsr(u32 msr, u32 *hi, u32 *lo)
|
||||||
{
|
{
|
||||||
struct pci_bus bus = {
|
struct pci_bus bus = {
|
||||||
.number = PCI_BUS_CS5536
|
.number = PCI_BUS_CS5536
|
||||||
};
|
};
|
||||||
u32 devfn = PCI_DEVFN(PCI_IDSEL_CS5536, 0);
|
u32 devfn = PCI_DEVFN(PCI_IDSEL_CS5536, 0);
|
||||||
|
unsigned long flags;
|
||||||
|
|
||||||
|
raw_spin_lock_irqsave(&msr_lock, flags);
|
||||||
loongson_pcibios_write(&bus, devfn, PCI_MSR_ADDR, 4, msr);
|
loongson_pcibios_write(&bus, devfn, PCI_MSR_ADDR, 4, msr);
|
||||||
loongson_pcibios_read(&bus, devfn, PCI_MSR_DATA_LO, 4, lo);
|
loongson_pcibios_read(&bus, devfn, PCI_MSR_DATA_LO, 4, lo);
|
||||||
loongson_pcibios_read(&bus, devfn, PCI_MSR_DATA_HI, 4, hi);
|
loongson_pcibios_read(&bus, devfn, PCI_MSR_DATA_HI, 4, hi);
|
||||||
|
raw_spin_unlock_irqrestore(&msr_lock, flags);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(_rdmsr);
|
EXPORT_SYMBOL(_rdmsr);
|
||||||
|
|
||||||
|
@ -198,9 +204,13 @@ void _wrmsr(u32 msr, u32 hi, u32 lo)
|
||||||
.number = PCI_BUS_CS5536
|
.number = PCI_BUS_CS5536
|
||||||
};
|
};
|
||||||
u32 devfn = PCI_DEVFN(PCI_IDSEL_CS5536, 0);
|
u32 devfn = PCI_DEVFN(PCI_IDSEL_CS5536, 0);
|
||||||
|
unsigned long flags;
|
||||||
|
|
||||||
|
raw_spin_lock_irqsave(&msr_lock, flags);
|
||||||
loongson_pcibios_write(&bus, devfn, PCI_MSR_ADDR, 4, msr);
|
loongson_pcibios_write(&bus, devfn, PCI_MSR_ADDR, 4, msr);
|
||||||
loongson_pcibios_write(&bus, devfn, PCI_MSR_DATA_LO, 4, lo);
|
loongson_pcibios_write(&bus, devfn, PCI_MSR_DATA_LO, 4, lo);
|
||||||
loongson_pcibios_write(&bus, devfn, PCI_MSR_DATA_HI, 4, hi);
|
loongson_pcibios_write(&bus, devfn, PCI_MSR_DATA_HI, 4, hi);
|
||||||
|
raw_spin_unlock_irqrestore(&msr_lock, flags);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(_wrmsr);
|
EXPORT_SYMBOL(_wrmsr);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -87,6 +87,21 @@ static int __init setup_bcm1250(void)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int sb1250_m3_workaround_needed(void)
|
||||||
|
{
|
||||||
|
switch (soc_type) {
|
||||||
|
case K_SYS_SOC_TYPE_BCM1250:
|
||||||
|
case K_SYS_SOC_TYPE_BCM1250_ALT:
|
||||||
|
case K_SYS_SOC_TYPE_BCM1250_ALT2:
|
||||||
|
case K_SYS_SOC_TYPE_BCM1125:
|
||||||
|
case K_SYS_SOC_TYPE_BCM1125H:
|
||||||
|
return soc_pass < K_SYS_REVISION_BCM1250_C0;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int __init setup_bcm112x(void)
|
static int __init setup_bcm112x(void)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
|
@ -37,6 +37,9 @@ config SPARC64
|
||||||
def_bool 64BIT
|
def_bool 64BIT
|
||||||
select ARCH_SUPPORTS_MSI
|
select ARCH_SUPPORTS_MSI
|
||||||
select HAVE_FUNCTION_TRACER
|
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_KRETPROBES
|
||||||
select HAVE_KPROBES
|
select HAVE_KPROBES
|
||||||
select HAVE_LMB
|
select HAVE_LMB
|
||||||
|
|
|
@ -19,13 +19,10 @@ config DEBUG_DCFLUSH
|
||||||
bool "D-cache flush debugging"
|
bool "D-cache flush debugging"
|
||||||
depends on SPARC64 && DEBUG_KERNEL
|
depends on SPARC64 && DEBUG_KERNEL
|
||||||
|
|
||||||
config STACK_DEBUG
|
|
||||||
bool "Stack Overflow Detection Support"
|
|
||||||
|
|
||||||
config MCOUNT
|
config MCOUNT
|
||||||
bool
|
bool
|
||||||
depends on SPARC64
|
depends on SPARC64
|
||||||
depends on STACK_DEBUG || FUNCTION_TRACER
|
depends on FUNCTION_TRACER
|
||||||
default y
|
default y
|
||||||
|
|
||||||
config FRAME_POINTER
|
config FRAME_POINTER
|
||||||
|
|
|
@ -17,7 +17,7 @@ typedef struct {
|
||||||
unsigned int __nmi_count;
|
unsigned int __nmi_count;
|
||||||
unsigned long clock_tick; /* %tick's per second */
|
unsigned long clock_tick; /* %tick's per second */
|
||||||
unsigned long __pad;
|
unsigned long __pad;
|
||||||
unsigned int __pad1;
|
unsigned int irq0_irqs;
|
||||||
unsigned int __pad2;
|
unsigned int __pad2;
|
||||||
|
|
||||||
/* Dcache line 2, rarely used */
|
/* 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)
|
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;
|
return flags;
|
||||||
}
|
}
|
||||||
|
|
|
@ -111,7 +111,7 @@ struct thread_info {
|
||||||
#define THREAD_SHIFT PAGE_SHIFT
|
#define THREAD_SHIFT PAGE_SHIFT
|
||||||
#endif /* PAGE_SHIFT == 13 */
|
#endif /* PAGE_SHIFT == 13 */
|
||||||
|
|
||||||
#define PREEMPT_ACTIVE 0x4000000
|
#define PREEMPT_ACTIVE 0x10000000
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* macros/functions for gaining access to the thread information structure
|
* 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)
|
CPPFLAGS_vmlinux.lds := -Usparc -m$(BITS)
|
||||||
extra-y += vmlinux.lds
|
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) += entry.o wof.o wuf.o
|
||||||
obj-$(CONFIG_SPARC32) += etrap_32.o
|
obj-$(CONFIG_SPARC32) += etrap_32.o
|
||||||
obj-$(CONFIG_SPARC32) += rtrap_32.o
|
obj-$(CONFIG_SPARC32) += rtrap_32.o
|
||||||
|
@ -85,7 +93,7 @@ obj-$(CONFIG_KGDB) += kgdb_$(BITS).o
|
||||||
|
|
||||||
|
|
||||||
obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.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_EARLYFB) += btext.o
|
||||||
obj-$(CONFIG_STACKTRACE) += stacktrace.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 ftrace_call_replace(unsigned long ip, unsigned long addr)
|
||||||
{
|
{
|
||||||
static u32 call;
|
u32 call;
|
||||||
s32 off;
|
s32 off;
|
||||||
|
|
||||||
off = ((s32)addr - (s32)ip);
|
off = ((s32)addr - (s32)ip);
|
||||||
|
@ -91,3 +91,61 @@ int __init ftrace_dyn_arch_init(void *data)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
#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/delay.h>
|
||||||
#include <linux/proc_fs.h>
|
#include <linux/proc_fs.h>
|
||||||
#include <linux/seq_file.h>
|
#include <linux/seq_file.h>
|
||||||
|
#include <linux/ftrace.h>
|
||||||
#include <linux/irq.h>
|
#include <linux/irq.h>
|
||||||
|
#include <linux/kmemleak.h>
|
||||||
|
|
||||||
#include <asm/ptrace.h>
|
#include <asm/ptrace.h>
|
||||||
#include <asm/processor.h>
|
#include <asm/processor.h>
|
||||||
|
@ -45,6 +47,7 @@
|
||||||
|
|
||||||
#include "entry.h"
|
#include "entry.h"
|
||||||
#include "cpumap.h"
|
#include "cpumap.h"
|
||||||
|
#include "kstack.h"
|
||||||
|
|
||||||
#define NUM_IVECS (IMAP_INR + 1)
|
#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);
|
bucket = kzalloc(sizeof(struct ino_bucket), GFP_ATOMIC);
|
||||||
if (unlikely(!bucket))
|
if (unlikely(!bucket))
|
||||||
return 0;
|
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,
|
__flush_dcache_range((unsigned long) bucket,
|
||||||
((unsigned long) bucket +
|
((unsigned long) bucket +
|
||||||
sizeof(struct ino_bucket)));
|
sizeof(struct ino_bucket)));
|
||||||
|
@ -703,25 +714,7 @@ void ack_bad_irq(unsigned int virt_irq)
|
||||||
void *hardirq_stack[NR_CPUS];
|
void *hardirq_stack[NR_CPUS];
|
||||||
void *softirq_stack[NR_CPUS];
|
void *softirq_stack[NR_CPUS];
|
||||||
|
|
||||||
static __attribute__((always_inline)) void *set_hardirq_stack(void)
|
void __irq_entry handler_irq(int irq, struct pt_regs *regs)
|
||||||
{
|
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
unsigned long pstate, bucket_pa;
|
unsigned long pstate, bucket_pa;
|
||||||
struct pt_regs *old_regs;
|
struct pt_regs *old_regs;
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
|
|
||||||
#include <linux/kgdb.h>
|
#include <linux/kgdb.h>
|
||||||
#include <linux/kdebug.h>
|
#include <linux/kdebug.h>
|
||||||
|
#include <linux/ftrace.h>
|
||||||
|
|
||||||
#include <asm/kdebug.h>
|
#include <asm/kdebug.h>
|
||||||
#include <asm/ptrace.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
|
#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;
|
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 */
|
#endif /* _KSTACK_H */
|
||||||
|
|
|
@ -23,6 +23,8 @@
|
||||||
#include <asm/ptrace.h>
|
#include <asm/ptrace.h>
|
||||||
#include <asm/pcr.h>
|
#include <asm/pcr.h>
|
||||||
|
|
||||||
|
#include "kstack.h"
|
||||||
|
|
||||||
/* We don't have a real NMI on sparc64, but we can fake one
|
/* We don't have a real NMI on sparc64, but we can fake one
|
||||||
* up using profiling counter overflow interrupts and interrupt
|
* up using profiling counter overflow interrupts and interrupt
|
||||||
* levels.
|
* 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)
|
notrace __kprobes void perfctr_irq(int irq, struct pt_regs *regs)
|
||||||
{
|
{
|
||||||
unsigned int sum, touched = 0;
|
unsigned int sum, touched = 0;
|
||||||
int cpu = smp_processor_id();
|
void *orig_sp;
|
||||||
|
|
||||||
clear_softint(1 << irq);
|
clear_softint(1 << irq);
|
||||||
|
|
||||||
|
@ -100,13 +102,15 @@ notrace __kprobes void perfctr_irq(int irq, struct pt_regs *regs)
|
||||||
|
|
||||||
nmi_enter();
|
nmi_enter();
|
||||||
|
|
||||||
|
orig_sp = set_hardirq_stack();
|
||||||
|
|
||||||
if (notify_die(DIE_NMI, "nmi", regs, 0,
|
if (notify_die(DIE_NMI, "nmi", regs, 0,
|
||||||
pt_regs_trap_type(regs), SIGINT) == NOTIFY_STOP)
|
pt_regs_trap_type(regs), SIGINT) == NOTIFY_STOP)
|
||||||
touched = 1;
|
touched = 1;
|
||||||
else
|
else
|
||||||
pcr_ops->write(PCR_PIC_PRIV);
|
pcr_ops->write(PCR_PIC_PRIV);
|
||||||
|
|
||||||
sum = kstat_irqs_cpu(0, cpu);
|
sum = local_cpu_data().irq0_irqs;
|
||||||
if (__get_cpu_var(nmi_touch)) {
|
if (__get_cpu_var(nmi_touch)) {
|
||||||
__get_cpu_var(nmi_touch) = 0;
|
__get_cpu_var(nmi_touch) = 0;
|
||||||
touched = 1;
|
touched = 1;
|
||||||
|
@ -125,6 +129,8 @@ notrace __kprobes void perfctr_irq(int irq, struct pt_regs *regs)
|
||||||
pcr_ops->write(pcr_enable);
|
pcr_ops->write(pcr_enable);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
restore_hardirq_stack(orig_sp);
|
||||||
|
|
||||||
nmi_exit();
|
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);
|
struct resource *rp = kzalloc(sizeof(*rp), GFP_KERNEL);
|
||||||
|
|
||||||
if (!rp) {
|
if (!rp) {
|
||||||
prom_printf("Cannot allocate IOMMU resource.\n");
|
pr_info("%s: Cannot allocate IOMMU resource.\n",
|
||||||
prom_halt();
|
pbm->name);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
rp->name = "IOMMU";
|
rp->name = "IOMMU";
|
||||||
rp->start = pbm->mem_space.start + (unsigned long) vdma[0];
|
rp->start = pbm->mem_space.start + (unsigned long) vdma[0];
|
||||||
rp->end = rp->start + (unsigned long) vdma[1] - 1UL;
|
rp->end = rp->start + (unsigned long) vdma[1] - 1UL;
|
||||||
rp->flags = IORESOURCE_BUSY;
|
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/irq.h>
|
||||||
|
|
||||||
#include <linux/perf_event.h>
|
#include <linux/perf_event.h>
|
||||||
|
#include <linux/ftrace.h>
|
||||||
|
|
||||||
#include <asm/pil.h>
|
#include <asm/pil.h>
|
||||||
#include <asm/pcr.h>
|
#include <asm/pcr.h>
|
||||||
|
@ -34,7 +35,7 @@ unsigned int picl_shift;
|
||||||
* Therefore in such situations we defer the work by signalling
|
* Therefore in such situations we defer the work by signalling
|
||||||
* a lower level cpu IRQ.
|
* 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;
|
struct pt_regs *old_regs;
|
||||||
|
|
||||||
|
|
|
@ -130,7 +130,17 @@ rtrap_xcall:
|
||||||
nop
|
nop
|
||||||
call trace_hardirqs_on
|
call trace_hardirqs_on
|
||||||
nop
|
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
|
#endif
|
||||||
rtrap_no_irq_enable:
|
rtrap_no_irq_enable:
|
||||||
andcc %l1, TSTATE_PRIV, %l3
|
andcc %l1, TSTATE_PRIV, %l3
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
#include <linux/profile.h>
|
#include <linux/profile.h>
|
||||||
#include <linux/bootmem.h>
|
#include <linux/bootmem.h>
|
||||||
#include <linux/vmalloc.h>
|
#include <linux/vmalloc.h>
|
||||||
|
#include <linux/ftrace.h>
|
||||||
#include <linux/cpu.h>
|
#include <linux/cpu.h>
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
|
|
||||||
|
@ -823,13 +824,13 @@ void arch_send_call_function_single_ipi(int cpu)
|
||||||
&cpumask_of_cpu(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);
|
clear_softint(1 << irq);
|
||||||
generic_smp_call_function_interrupt();
|
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);
|
clear_softint(1 << irq);
|
||||||
generic_smp_call_function_single_interrupt();
|
generic_smp_call_function_single_interrupt();
|
||||||
|
@ -965,7 +966,7 @@ void flush_dcache_page_all(struct mm_struct *mm, struct page *page)
|
||||||
put_cpu();
|
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;
|
struct mm_struct *mm;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
@ -1149,7 +1150,7 @@ void smp_release(void)
|
||||||
*/
|
*/
|
||||||
extern void prom_world(int);
|
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);
|
clear_softint(1 << irq);
|
||||||
|
|
||||||
|
@ -1365,7 +1366,7 @@ void smp_send_reschedule(int cpu)
|
||||||
&cpumask_of_cpu(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);
|
clear_softint(1 << irq);
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,6 +35,7 @@
|
||||||
#include <linux/clocksource.h>
|
#include <linux/clocksource.h>
|
||||||
#include <linux/of_device.h>
|
#include <linux/of_device.h>
|
||||||
#include <linux/platform_device.h>
|
#include <linux/platform_device.h>
|
||||||
|
#include <linux/ftrace.h>
|
||||||
|
|
||||||
#include <asm/oplib.h>
|
#include <asm/oplib.h>
|
||||||
#include <asm/timer.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);
|
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);
|
struct pt_regs *old_regs = set_irq_regs(regs);
|
||||||
unsigned long tick_mask = tick_ops->softint_mask;
|
unsigned long tick_mask = tick_ops->softint_mask;
|
||||||
|
@ -728,6 +729,7 @@ void timer_interrupt(int irq, struct pt_regs *regs)
|
||||||
|
|
||||||
irq_enter();
|
irq_enter();
|
||||||
|
|
||||||
|
local_cpu_data().irq0_irqs++;
|
||||||
kstat_incr_irqs_this_cpu(0, irq_to_desc(0));
|
kstat_incr_irqs_this_cpu(0, irq_to_desc(0));
|
||||||
|
|
||||||
if (unlikely(!evt->event_handler)) {
|
if (unlikely(!evt->event_handler)) {
|
||||||
|
|
|
@ -2203,27 +2203,6 @@ void dump_stack(void)
|
||||||
|
|
||||||
EXPORT_SYMBOL(dump_stack);
|
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)
|
static inline struct reg_window *kernel_stack_up(struct reg_window *rw)
|
||||||
{
|
{
|
||||||
unsigned long fp = rw->ins[6];
|
unsigned long fp = rw->ins[6];
|
||||||
|
@ -2252,6 +2231,7 @@ void die_if_kernel(char *str, struct pt_regs *regs)
|
||||||
show_regs(regs);
|
show_regs(regs);
|
||||||
add_taint(TAINT_DIE);
|
add_taint(TAINT_DIE);
|
||||||
if (regs->tstate & TSTATE_PRIV) {
|
if (regs->tstate & TSTATE_PRIV) {
|
||||||
|
struct thread_info *tp = current_thread_info();
|
||||||
struct reg_window *rw = (struct reg_window *)
|
struct reg_window *rw = (struct reg_window *)
|
||||||
(regs->u_regs[UREG_FP] + STACK_BIAS);
|
(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.
|
* find some badly aligned kernel stack.
|
||||||
*/
|
*/
|
||||||
while (rw &&
|
while (rw &&
|
||||||
count++ < 30&&
|
count++ < 30 &&
|
||||||
is_kernel_stack(current, rw)) {
|
kstack_valid(tp, (unsigned long) rw)) {
|
||||||
printk("Caller[%016lx]: %pS\n", rw->ins[7],
|
printk("Caller[%016lx]: %pS\n", rw->ins[7],
|
||||||
(void *) rw->ins[7]);
|
(void *) rw->ins[7]);
|
||||||
|
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue