mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-17 01:04:19 +08:00
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/vapier/blackfin
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/vapier/blackfin: (27 commits) Blackfin: hook up new rt_tgsigqueueinfo syscall Blackfin: improve CLKIN_HZ config default Blackfin: initial support for ftrace grapher Blackfin: initial support for ftrace Blackfin: enable support for LOCKDEP Blackfin: add preliminary support for STACKTRACE Blackfin: move custom sections into sections.h Blackfin: punt unused/wrong mutex-dec.h Blackfin: add support for irqflags Blackfin: add support for bzip2/lzma compressed kernel images Blackfin: convert Kconfig style to def_bool Blackfin: bf548-ezkit: update smsc911x resources Blackfin: update aedos-ipipe code to upstream 1.10-00 Blackfin: bf537-stamp: update ADP5520 resources Blackfin: bf518f-ezbrd: fix SPI CS for SPI flash Blackfin: define SPI IRQ in board resources Blackfin: do not configure the UART early if on wrong processor Blackfin: fix deadlock in SMP IPI handler Blackfin: fix flag storage for irq funcs Blackfin: push down exception oops checking ...
This commit is contained in:
commit
8d6cea5111
@ -6,59 +6,65 @@
|
||||
mainmenu "Blackfin Kernel Configuration"
|
||||
|
||||
config MMU
|
||||
bool
|
||||
default n
|
||||
def_bool n
|
||||
|
||||
config FPU
|
||||
bool
|
||||
default n
|
||||
def_bool n
|
||||
|
||||
config RWSEM_GENERIC_SPINLOCK
|
||||
bool
|
||||
default y
|
||||
def_bool y
|
||||
|
||||
config RWSEM_XCHGADD_ALGORITHM
|
||||
bool
|
||||
default n
|
||||
def_bool n
|
||||
|
||||
config BLACKFIN
|
||||
bool
|
||||
default y
|
||||
def_bool y
|
||||
select HAVE_FUNCTION_GRAPH_TRACER
|
||||
select HAVE_FUNCTION_TRACER
|
||||
select HAVE_IDE
|
||||
select HAVE_KERNEL_GZIP
|
||||
select HAVE_KERNEL_BZIP2
|
||||
select HAVE_KERNEL_LZMA
|
||||
select HAVE_OPROFILE
|
||||
select ARCH_WANT_OPTIONAL_GPIOLIB
|
||||
|
||||
config GENERIC_BUG
|
||||
def_bool y
|
||||
depends on BUG
|
||||
|
||||
config ZONE_DMA
|
||||
bool
|
||||
default y
|
||||
def_bool y
|
||||
|
||||
config GENERIC_FIND_NEXT_BIT
|
||||
bool
|
||||
default y
|
||||
def_bool y
|
||||
|
||||
config GENERIC_HWEIGHT
|
||||
bool
|
||||
default y
|
||||
def_bool y
|
||||
|
||||
config GENERIC_HARDIRQS
|
||||
bool
|
||||
default y
|
||||
def_bool y
|
||||
|
||||
config GENERIC_IRQ_PROBE
|
||||
bool
|
||||
default y
|
||||
def_bool y
|
||||
|
||||
config GENERIC_GPIO
|
||||
bool
|
||||
default y
|
||||
def_bool y
|
||||
|
||||
config FORCE_MAX_ZONEORDER
|
||||
int
|
||||
default "14"
|
||||
|
||||
config GENERIC_CALIBRATE_DELAY
|
||||
bool
|
||||
default y
|
||||
def_bool y
|
||||
|
||||
config LOCKDEP_SUPPORT
|
||||
def_bool y
|
||||
|
||||
config STACKTRACE_SUPPORT
|
||||
def_bool y
|
||||
|
||||
config TRACE_IRQFLAGS_SUPPORT
|
||||
def_bool y
|
||||
|
||||
source "init/Kconfig"
|
||||
|
||||
@ -408,12 +414,12 @@ comment "Clock/PLL Setup"
|
||||
|
||||
config CLKIN_HZ
|
||||
int "Frequency of the crystal on the board in Hz"
|
||||
default "11059200" if BFIN533_STAMP
|
||||
default "27000000" if BFIN533_EZKIT
|
||||
default "25000000" if (BFIN537_STAMP || BFIN527_EZKIT || H8606_HVSISTEMAS || BLACKSTAMP || BFIN526_EZBRD || BFIN538_EZKIT || BFIN518F-EZBRD)
|
||||
default "30000000" if BFIN561_EZKIT
|
||||
default "24576000" if PNAV10
|
||||
default "10000000" if BFIN532_IP0X
|
||||
default "11059200" if BFIN533_STAMP
|
||||
default "24576000" if PNAV10
|
||||
default "25000000" # most people use this
|
||||
default "27000000" if BFIN533_EZKIT
|
||||
default "30000000" if BFIN561_EZKIT
|
||||
help
|
||||
The frequency of CLKIN crystal oscillator on the board in Hz.
|
||||
Warning: This value should match the crystal on the board. Otherwise,
|
||||
|
@ -137,7 +137,7 @@ archclean:
|
||||
|
||||
INSTALL_PATH ?= /tftpboot
|
||||
boot := arch/$(ARCH)/boot
|
||||
BOOT_TARGETS = vmImage
|
||||
BOOT_TARGETS = vmImage vmImage.bz2 vmImage.gz vmImage.lzma
|
||||
PHONY += $(BOOT_TARGETS) install
|
||||
KBUILD_IMAGE := $(boot)/vmImage
|
||||
|
||||
@ -150,7 +150,10 @@ install:
|
||||
$(Q)$(MAKE) $(build)=$(boot) BOOTIMAGE=$(KBUILD_IMAGE) install
|
||||
|
||||
define archhelp
|
||||
echo '* vmImage - Kernel-only image for U-Boot (arch/$(ARCH)/boot/vmImage)'
|
||||
echo '* vmImage - Alias to selected kernel format (vmImage.gz by default)'
|
||||
echo ' vmImage.bz2 - Kernel-only image for U-Boot (arch/$(ARCH)/boot/vmImage.bz2)'
|
||||
echo '* vmImage.gz - Kernel-only image for U-Boot (arch/$(ARCH)/boot/vmImage.gz)'
|
||||
echo ' vmImage.lzma - Kernel-only image for U-Boot (arch/$(ARCH)/boot/vmImage.lzma)'
|
||||
echo ' install - Install kernel using'
|
||||
echo ' (your) ~/bin/$(CROSS_COMPILE)installkernel or'
|
||||
echo ' (distribution) PATH: $(CROSS_COMPILE)installkernel or'
|
||||
|
3
arch/blackfin/boot/.gitignore
vendored
3
arch/blackfin/boot/.gitignore
vendored
@ -1 +1,2 @@
|
||||
+vmImage
|
||||
vmImage*
|
||||
vmlinux*
|
||||
|
@ -8,24 +8,41 @@
|
||||
|
||||
MKIMAGE := $(srctree)/scripts/mkuboot.sh
|
||||
|
||||
targets := vmImage
|
||||
extra-y += vmlinux.bin vmlinux.gz
|
||||
targets := vmImage vmImage.bz2 vmImage.gz vmImage.lzma
|
||||
extra-y += vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2 vmlinux.bin.lzma
|
||||
|
||||
quiet_cmd_uimage = UIMAGE $@
|
||||
cmd_uimage = $(CONFIG_SHELL) $(MKIMAGE) -A $(ARCH) -O linux -T kernel \
|
||||
-C gzip -n 'Linux-$(KERNELRELEASE)' -a $(CONFIG_BOOT_LOAD) \
|
||||
-C $(2) -n 'Linux-$(KERNELRELEASE)' -a $(CONFIG_BOOT_LOAD) \
|
||||
-e $(shell $(NM) vmlinux | awk '$$NF == "__start" {print $$1}') \
|
||||
-d $< $@
|
||||
|
||||
$(obj)/vmlinux.bin: vmlinux FORCE
|
||||
$(call if_changed,objcopy)
|
||||
|
||||
$(obj)/vmlinux.gz: $(obj)/vmlinux.bin FORCE
|
||||
$(obj)/vmlinux.bin.gz: $(obj)/vmlinux.bin FORCE
|
||||
$(call if_changed,gzip)
|
||||
|
||||
$(obj)/vmImage: $(obj)/vmlinux.gz
|
||||
$(call if_changed,uimage)
|
||||
@$(kecho) 'Kernel: $@ is ready'
|
||||
$(obj)/vmlinux.bin.bz2: $(obj)/vmlinux.bin FORCE
|
||||
$(call if_changed,bzip2)
|
||||
|
||||
$(obj)/vmlinux.bin.lzma: $(obj)/vmlinux.bin FORCE
|
||||
$(call if_changed,lzma)
|
||||
|
||||
$(obj)/vmImage.bz2: $(obj)/vmlinux.bin.bz2
|
||||
$(call if_changed,uimage,bzip2)
|
||||
|
||||
$(obj)/vmImage.gz: $(obj)/vmlinux.bin.gz
|
||||
$(call if_changed,uimage,gzip)
|
||||
|
||||
$(obj)/vmImage.lzma: $(obj)/vmlinux.bin.lzma
|
||||
$(call if_changed,uimage,lzma)
|
||||
|
||||
suffix-$(CONFIG_KERNEL_GZIP) := gz
|
||||
suffix-$(CONFIG_KERNEL_BZIP2) := bz2
|
||||
suffix-$(CONFIG_KERNEL_LZMA) := lzma
|
||||
$(obj)/vmImage: $(obj)/vmImage.$(suffix-y)
|
||||
@ln -sf $(notdir $<) $@
|
||||
|
||||
install:
|
||||
sh $(srctree)/$(src)/install.sh $(KERNELRELEASE) $(BOOTIMAGE) System.map "$(INSTALL_PATH)"
|
||||
|
@ -90,7 +90,7 @@ static inline int atomic_test_mask(int mask, atomic_t *v)
|
||||
|
||||
static inline void atomic_add(int i, atomic_t *v)
|
||||
{
|
||||
long flags;
|
||||
unsigned long flags;
|
||||
|
||||
local_irq_save_hw(flags);
|
||||
v->counter += i;
|
||||
@ -99,7 +99,7 @@ static inline void atomic_add(int i, atomic_t *v)
|
||||
|
||||
static inline void atomic_sub(int i, atomic_t *v)
|
||||
{
|
||||
long flags;
|
||||
unsigned long flags;
|
||||
|
||||
local_irq_save_hw(flags);
|
||||
v->counter -= i;
|
||||
@ -110,7 +110,7 @@ static inline void atomic_sub(int i, atomic_t *v)
|
||||
static inline int atomic_add_return(int i, atomic_t *v)
|
||||
{
|
||||
int __temp = 0;
|
||||
long flags;
|
||||
unsigned long flags;
|
||||
|
||||
local_irq_save_hw(flags);
|
||||
v->counter += i;
|
||||
@ -124,7 +124,7 @@ static inline int atomic_add_return(int i, atomic_t *v)
|
||||
static inline int atomic_sub_return(int i, atomic_t *v)
|
||||
{
|
||||
int __temp = 0;
|
||||
long flags;
|
||||
unsigned long flags;
|
||||
|
||||
local_irq_save_hw(flags);
|
||||
v->counter -= i;
|
||||
@ -136,7 +136,7 @@ static inline int atomic_sub_return(int i, atomic_t *v)
|
||||
|
||||
static inline void atomic_inc(volatile atomic_t *v)
|
||||
{
|
||||
long flags;
|
||||
unsigned long flags;
|
||||
|
||||
local_irq_save_hw(flags);
|
||||
v->counter++;
|
||||
@ -145,7 +145,7 @@ static inline void atomic_inc(volatile atomic_t *v)
|
||||
|
||||
static inline void atomic_dec(volatile atomic_t *v)
|
||||
{
|
||||
long flags;
|
||||
unsigned long flags;
|
||||
|
||||
local_irq_save_hw(flags);
|
||||
v->counter--;
|
||||
@ -154,7 +154,7 @@ static inline void atomic_dec(volatile atomic_t *v)
|
||||
|
||||
static inline void atomic_clear_mask(unsigned int mask, atomic_t *v)
|
||||
{
|
||||
long flags;
|
||||
unsigned long flags;
|
||||
|
||||
local_irq_save_hw(flags);
|
||||
v->counter &= ~mask;
|
||||
@ -163,7 +163,7 @@ static inline void atomic_clear_mask(unsigned int mask, atomic_t *v)
|
||||
|
||||
static inline void atomic_set_mask(unsigned int mask, atomic_t *v)
|
||||
{
|
||||
long flags;
|
||||
unsigned long flags;
|
||||
|
||||
local_irq_save_hw(flags);
|
||||
v->counter |= mask;
|
||||
|
@ -31,7 +31,7 @@
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
#include <asm-generic/sections.h>
|
||||
#include <asm/sections.h>
|
||||
#include <asm/ptrace.h>
|
||||
#include <asm/user.h>
|
||||
#include <linux/linkage.h>
|
||||
@ -99,15 +99,6 @@ extern const char bfin_board_name[];
|
||||
extern unsigned long bfin_sic_iwr[];
|
||||
extern unsigned vr_wakeup;
|
||||
extern u16 _bfin_swrst; /* shadow for Software Reset Register (SWRST) */
|
||||
extern unsigned long _ramstart, _ramend, _rambase;
|
||||
extern unsigned long memory_start, memory_end, physical_mem_end;
|
||||
extern char _stext_l1[], _etext_l1[], _sdata_l1[], _edata_l1[], _sbss_l1[],
|
||||
_ebss_l1[], _l1_lma_start[], _sdata_b_l1[], _sbss_b_l1[], _ebss_b_l1[],
|
||||
_stext_l2[], _etext_l2[], _sdata_l2[], _edata_l2[], _sbss_l2[],
|
||||
_ebss_l2[], _l2_lma_start[];
|
||||
|
||||
/* only used when MTD_UCLINUX */
|
||||
extern unsigned long memory_mtd_start, memory_mtd_end, mtd_size;
|
||||
|
||||
#ifdef CONFIG_BFIN_ICACHE_LOCK
|
||||
extern void cache_grab_lock(int way);
|
||||
|
@ -109,7 +109,8 @@ static inline void clear_bit(int nr, volatile unsigned long *addr)
|
||||
|
||||
static inline void change_bit(int nr, volatile unsigned long *addr)
|
||||
{
|
||||
int mask, flags;
|
||||
int mask;
|
||||
unsigned long flags;
|
||||
unsigned long *ADDR = (unsigned long *)addr;
|
||||
|
||||
ADDR += nr >> 5;
|
||||
|
@ -2,13 +2,58 @@
|
||||
#define _BLACKFIN_BUG_H
|
||||
|
||||
#ifdef CONFIG_BUG
|
||||
#define HAVE_ARCH_BUG
|
||||
|
||||
#define BUG() do { \
|
||||
dump_bfin_trace_buffer(); \
|
||||
printk(KERN_EMERG "BUG: failure at %s:%d/%s()!\n", __FILE__, __LINE__, __func__); \
|
||||
panic("BUG!"); \
|
||||
} while (0)
|
||||
#define BFIN_BUG_OPCODE 0xefcd
|
||||
|
||||
#ifdef CONFIG_DEBUG_BUGVERBOSE
|
||||
|
||||
#define _BUG_OR_WARN(flags) \
|
||||
asm volatile( \
|
||||
"1: .hword %0\n" \
|
||||
" .section __bug_table,\"a\",@progbits\n" \
|
||||
"2: .long 1b\n" \
|
||||
" .long %1\n" \
|
||||
" .short %2\n" \
|
||||
" .short %3\n" \
|
||||
" .org 2b + %4\n" \
|
||||
" .previous" \
|
||||
: \
|
||||
: "i"(BFIN_BUG_OPCODE), "i"(__FILE__), \
|
||||
"i"(__LINE__), "i"(flags), \
|
||||
"i"(sizeof(struct bug_entry)))
|
||||
|
||||
#else
|
||||
|
||||
#define _BUG_OR_WARN(flags) \
|
||||
asm volatile( \
|
||||
"1: .hword %0\n" \
|
||||
" .section __bug_table,\"a\",@progbits\n" \
|
||||
"2: .long 1b\n" \
|
||||
" .short %1\n" \
|
||||
" .org 2b + %2\n" \
|
||||
" .previous" \
|
||||
: \
|
||||
: "i"(BFIN_BUG_OPCODE), "i"(flags), \
|
||||
"i"(sizeof(struct bug_entry)))
|
||||
|
||||
#endif /* CONFIG_DEBUG_BUGVERBOSE */
|
||||
|
||||
#define BUG() \
|
||||
do { \
|
||||
_BUG_OR_WARN(0); \
|
||||
for (;;); \
|
||||
} while (0)
|
||||
|
||||
#define WARN_ON(condition) \
|
||||
({ \
|
||||
int __ret_warn_on = !!(condition); \
|
||||
if (unlikely(__ret_warn_on)) \
|
||||
_BUG_OR_WARN(BUGFLAG_WARNING); \
|
||||
unlikely(__ret_warn_on); \
|
||||
})
|
||||
|
||||
#define HAVE_ARCH_BUG
|
||||
#define HAVE_ARCH_WARN_ON
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -34,9 +34,13 @@
|
||||
#define L1_CACHE_SHIFT_MAX 5
|
||||
|
||||
#if defined(CONFIG_SMP) && \
|
||||
!defined(CONFIG_BFIN_CACHE_COHERENT) && \
|
||||
defined(CONFIG_BFIN_DCACHE)
|
||||
#define __ARCH_SYNC_CORE_DCACHE
|
||||
!defined(CONFIG_BFIN_CACHE_COHERENT)
|
||||
# if defined(CONFIG_BFIN_ICACHE)
|
||||
# define __ARCH_SYNC_CORE_ICACHE
|
||||
# endif
|
||||
# if defined(CONFIG_BFIN_DCACHE)
|
||||
# define __ARCH_SYNC_CORE_DCACHE
|
||||
# endif
|
||||
#ifndef __ASSEMBLY__
|
||||
asmlinkage void __raw_smp_mark_barrier_asm(void);
|
||||
asmlinkage void __raw_smp_check_barrier_asm(void);
|
||||
@ -51,6 +55,7 @@ static inline void smp_check_barrier(void)
|
||||
}
|
||||
|
||||
void resync_core_dcache(void);
|
||||
void resync_core_icache(void);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
@ -37,6 +37,7 @@ extern void blackfin_dcache_flush_range(unsigned long start_address, unsigned lo
|
||||
extern void blackfin_dcache_invalidate_range(unsigned long start_address, unsigned long end_address);
|
||||
extern void blackfin_dflush_page(void *page);
|
||||
extern void blackfin_invalidate_entire_dcache(void);
|
||||
extern void blackfin_invalidate_entire_icache(void);
|
||||
|
||||
#define flush_dcache_mmap_lock(mapping) do { } while (0)
|
||||
#define flush_dcache_mmap_unlock(mapping) do { } while (0)
|
||||
@ -97,7 +98,7 @@ do { memcpy(dst, src, len); \
|
||||
extern unsigned long reserved_mem_dcache_on;
|
||||
extern unsigned long reserved_mem_icache_on;
|
||||
|
||||
static inline int bfin_addr_dcachable(unsigned long addr)
|
||||
static inline int bfin_addr_dcacheable(unsigned long addr)
|
||||
{
|
||||
#ifdef CONFIG_BFIN_DCACHE
|
||||
if (addr < (_ramend - DMA_UNCACHED_REGION))
|
||||
|
@ -34,6 +34,7 @@ struct blackfin_cpudata {
|
||||
unsigned int dmemctl;
|
||||
unsigned long loops_per_jiffy;
|
||||
unsigned long dcache_invld_count;
|
||||
unsigned long icache_invld_count;
|
||||
};
|
||||
|
||||
DECLARE_PER_CPU(struct blackfin_cpudata, cpu_data);
|
||||
|
@ -1 +1,13 @@
|
||||
/* empty */
|
||||
/*
|
||||
* Blackfin ftrace code
|
||||
*
|
||||
* Copyright 2009 Analog Devices Inc.
|
||||
* Licensed under the GPL-2 or later.
|
||||
*/
|
||||
|
||||
#ifndef __ASM_BFIN_FTRACE_H__
|
||||
#define __ASM_BFIN_FTRACE_H__
|
||||
|
||||
#define MCOUNT_INSN_SIZE 8 /* sizeof mcount call: LINK + CALL */
|
||||
|
||||
#endif
|
||||
|
@ -35,10 +35,10 @@
|
||||
#include <asm/atomic.h>
|
||||
#include <asm/traps.h>
|
||||
|
||||
#define IPIPE_ARCH_STRING "1.9-01"
|
||||
#define IPIPE_ARCH_STRING "1.10-00"
|
||||
#define IPIPE_MAJOR_NUMBER 1
|
||||
#define IPIPE_MINOR_NUMBER 9
|
||||
#define IPIPE_PATCH_NUMBER 1
|
||||
#define IPIPE_MINOR_NUMBER 10
|
||||
#define IPIPE_PATCH_NUMBER 0
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
#error "I-pipe/blackfin: SMP not implemented"
|
||||
@ -54,10 +54,11 @@ do { \
|
||||
|
||||
#define task_hijacked(p) \
|
||||
({ \
|
||||
int __x__ = ipipe_current_domain != ipipe_root_domain; \
|
||||
/* We would need to clear the SYNC flag for the root domain */ \
|
||||
/* over the current processor in SMP mode. */ \
|
||||
local_irq_enable_hw(); __x__; \
|
||||
int __x__ = __ipipe_root_domain_p; \
|
||||
__clear_bit(IPIPE_SYNC_FLAG, &ipipe_root_cpudom_var(status)); \
|
||||
if (__x__) \
|
||||
local_irq_enable_hw(); \
|
||||
!__x__; \
|
||||
})
|
||||
|
||||
struct ipipe_domain;
|
||||
@ -179,23 +180,24 @@ static inline unsigned long __ipipe_ffnz(unsigned long ul)
|
||||
|
||||
#define __ipipe_run_isr(ipd, irq) \
|
||||
do { \
|
||||
if (ipd == ipipe_root_domain) { \
|
||||
if (!__ipipe_pipeline_head_p(ipd)) \
|
||||
local_irq_enable_hw(); \
|
||||
if (ipipe_virtual_irq_p(irq)) \
|
||||
if (ipd == ipipe_root_domain) { \
|
||||
if (unlikely(ipipe_virtual_irq_p(irq))) { \
|
||||
irq_enter(); \
|
||||
ipd->irqs[irq].handler(irq, ipd->irqs[irq].cookie); \
|
||||
else \
|
||||
irq_exit(); \
|
||||
} else \
|
||||
ipd->irqs[irq].handler(irq, &__raw_get_cpu_var(__ipipe_tick_regs)); \
|
||||
local_irq_disable_hw(); \
|
||||
} else { \
|
||||
__clear_bit(IPIPE_SYNC_FLAG, &ipipe_cpudom_var(ipd, status)); \
|
||||
local_irq_enable_nohead(ipd); \
|
||||
ipd->irqs[irq].handler(irq, ipd->irqs[irq].cookie); \
|
||||
/* Attempt to exit the outer interrupt level before \
|
||||
* starting the deferred IRQ processing. */ \
|
||||
local_irq_disable_nohead(ipd); \
|
||||
__ipipe_run_irqtail(); \
|
||||
__set_bit(IPIPE_SYNC_FLAG, &ipipe_cpudom_var(ipd, status)); \
|
||||
} \
|
||||
local_irq_disable_hw(); \
|
||||
} while (0)
|
||||
|
||||
#define __ipipe_syscall_watched_p(p, sc) \
|
||||
|
@ -17,270 +17,17 @@
|
||||
#ifndef _BFIN_IRQ_H_
|
||||
#define _BFIN_IRQ_H_
|
||||
|
||||
/* SYS_IRQS and NR_IRQS are defined in <mach-bf5xx/irq.h>*/
|
||||
#include <linux/irqflags.h>
|
||||
|
||||
/* SYS_IRQS and NR_IRQS are defined in <mach-bf5xx/irq.h> */
|
||||
#include <mach/irq.h>
|
||||
#include <asm/pda.h>
|
||||
#include <asm/processor.h>
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
/* Forward decl needed due to cdef inter dependencies */
|
||||
static inline uint32_t __pure bfin_dspid(void);
|
||||
# define blackfin_core_id() (bfin_dspid() & 0xff)
|
||||
# define bfin_irq_flags cpu_pda[blackfin_core_id()].imask
|
||||
#else
|
||||
extern unsigned long bfin_irq_flags;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_IPIPE
|
||||
|
||||
#include <linux/ipipe_trace.h>
|
||||
|
||||
void __ipipe_unstall_root(void);
|
||||
|
||||
void __ipipe_restore_root(unsigned long flags);
|
||||
|
||||
#ifdef CONFIG_DEBUG_HWERR
|
||||
# define __all_masked_irq_flags 0x3f
|
||||
# define __save_and_cli_hw(x) \
|
||||
__asm__ __volatile__( \
|
||||
"cli %0;" \
|
||||
"sti %1;" \
|
||||
: "=&d"(x) \
|
||||
: "d" (0x3F) \
|
||||
)
|
||||
#else
|
||||
# define __all_masked_irq_flags 0x1f
|
||||
# define __save_and_cli_hw(x) \
|
||||
__asm__ __volatile__( \
|
||||
"cli %0;" \
|
||||
: "=&d"(x) \
|
||||
)
|
||||
#endif
|
||||
|
||||
#define irqs_enabled_from_flags_hw(x) ((x) != __all_masked_irq_flags)
|
||||
#define raw_irqs_disabled_flags(flags) (!irqs_enabled_from_flags_hw(flags))
|
||||
#define local_test_iflag_hw(x) irqs_enabled_from_flags_hw(x)
|
||||
|
||||
#define local_save_flags(x) \
|
||||
do { \
|
||||
(x) = __ipipe_test_root() ? \
|
||||
__all_masked_irq_flags : bfin_irq_flags; \
|
||||
barrier(); \
|
||||
} while (0)
|
||||
|
||||
#define local_irq_save(x) \
|
||||
do { \
|
||||
(x) = __ipipe_test_and_stall_root() ? \
|
||||
__all_masked_irq_flags : bfin_irq_flags; \
|
||||
barrier(); \
|
||||
} while (0)
|
||||
|
||||
static inline void local_irq_restore(unsigned long x)
|
||||
{
|
||||
barrier();
|
||||
__ipipe_restore_root(x == __all_masked_irq_flags);
|
||||
}
|
||||
|
||||
#define local_irq_disable() \
|
||||
do { \
|
||||
__ipipe_stall_root(); \
|
||||
barrier(); \
|
||||
} while (0)
|
||||
|
||||
static inline void local_irq_enable(void)
|
||||
{
|
||||
barrier();
|
||||
__ipipe_unstall_root();
|
||||
}
|
||||
|
||||
#define irqs_disabled() __ipipe_test_root()
|
||||
|
||||
#define local_save_flags_hw(x) \
|
||||
__asm__ __volatile__( \
|
||||
"cli %0;" \
|
||||
"sti %0;" \
|
||||
: "=d"(x) \
|
||||
)
|
||||
|
||||
#define irqs_disabled_hw() \
|
||||
({ \
|
||||
unsigned long flags; \
|
||||
local_save_flags_hw(flags); \
|
||||
!irqs_enabled_from_flags_hw(flags); \
|
||||
})
|
||||
|
||||
static inline unsigned long raw_mangle_irq_bits(int virt, unsigned long real)
|
||||
{
|
||||
/* Merge virtual and real interrupt mask bits into a single
|
||||
32bit word. */
|
||||
return (real & ~(1 << 31)) | ((virt != 0) << 31);
|
||||
}
|
||||
|
||||
static inline int raw_demangle_irq_bits(unsigned long *x)
|
||||
{
|
||||
int virt = (*x & (1 << 31)) != 0;
|
||||
*x &= ~(1L << 31);
|
||||
return virt;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_IPIPE_TRACE_IRQSOFF
|
||||
|
||||
#define local_irq_disable_hw() \
|
||||
do { \
|
||||
int _tmp_dummy; \
|
||||
if (!irqs_disabled_hw()) \
|
||||
ipipe_trace_begin(0x80000000); \
|
||||
__asm__ __volatile__ ("cli %0;" : "=d" (_tmp_dummy) : ); \
|
||||
} while (0)
|
||||
|
||||
#define local_irq_enable_hw() \
|
||||
do { \
|
||||
if (irqs_disabled_hw()) \
|
||||
ipipe_trace_end(0x80000000); \
|
||||
__asm__ __volatile__ ("sti %0;" : : "d"(bfin_irq_flags)); \
|
||||
} while (0)
|
||||
|
||||
#define local_irq_save_hw(x) \
|
||||
do { \
|
||||
__save_and_cli_hw(x); \
|
||||
if (local_test_iflag_hw(x)) \
|
||||
ipipe_trace_begin(0x80000001); \
|
||||
} while (0)
|
||||
|
||||
#define local_irq_restore_hw(x) \
|
||||
do { \
|
||||
if (local_test_iflag_hw(x)) { \
|
||||
ipipe_trace_end(0x80000001); \
|
||||
local_irq_enable_hw_notrace(); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define local_irq_disable_hw_notrace() \
|
||||
do { \
|
||||
int _tmp_dummy; \
|
||||
__asm__ __volatile__ ("cli %0;" : "=d" (_tmp_dummy) : ); \
|
||||
} while (0)
|
||||
|
||||
#define local_irq_enable_hw_notrace() \
|
||||
__asm__ __volatile__( \
|
||||
"sti %0;" \
|
||||
: \
|
||||
: "d"(bfin_irq_flags) \
|
||||
)
|
||||
|
||||
#define local_irq_save_hw_notrace(x) __save_and_cli_hw(x)
|
||||
|
||||
#define local_irq_restore_hw_notrace(x) \
|
||||
do { \
|
||||
if (local_test_iflag_hw(x)) \
|
||||
local_irq_enable_hw_notrace(); \
|
||||
} while (0)
|
||||
|
||||
#else /* CONFIG_IPIPE_TRACE_IRQSOFF */
|
||||
|
||||
#define local_irq_enable_hw() \
|
||||
__asm__ __volatile__( \
|
||||
"sti %0;" \
|
||||
: \
|
||||
: "d"(bfin_irq_flags) \
|
||||
)
|
||||
|
||||
#define local_irq_disable_hw() \
|
||||
do { \
|
||||
int _tmp_dummy; \
|
||||
__asm__ __volatile__ ( \
|
||||
"cli %0;" \
|
||||
: "=d" (_tmp_dummy)); \
|
||||
} while (0)
|
||||
|
||||
#define local_irq_restore_hw(x) \
|
||||
do { \
|
||||
if (irqs_enabled_from_flags_hw(x)) \
|
||||
local_irq_enable_hw(); \
|
||||
} while (0)
|
||||
|
||||
#define local_irq_save_hw(x) __save_and_cli_hw(x)
|
||||
|
||||
#define local_irq_disable_hw_notrace() local_irq_disable_hw()
|
||||
#define local_irq_enable_hw_notrace() local_irq_enable_hw()
|
||||
#define local_irq_save_hw_notrace(x) local_irq_save_hw(x)
|
||||
#define local_irq_restore_hw_notrace(x) local_irq_restore_hw(x)
|
||||
|
||||
#endif /* CONFIG_IPIPE_TRACE_IRQSOFF */
|
||||
|
||||
#else /* !CONFIG_IPIPE */
|
||||
|
||||
/*
|
||||
* Interrupt configuring macros.
|
||||
*/
|
||||
#define local_irq_disable() \
|
||||
do { \
|
||||
int __tmp_dummy; \
|
||||
__asm__ __volatile__( \
|
||||
"cli %0;" \
|
||||
: "=d" (__tmp_dummy) \
|
||||
); \
|
||||
} while (0)
|
||||
|
||||
#define local_irq_enable() \
|
||||
__asm__ __volatile__( \
|
||||
"sti %0;" \
|
||||
: \
|
||||
: "d" (bfin_irq_flags) \
|
||||
)
|
||||
|
||||
#ifdef CONFIG_DEBUG_HWERR
|
||||
# define __save_and_cli(x) \
|
||||
__asm__ __volatile__( \
|
||||
"cli %0;" \
|
||||
"sti %1;" \
|
||||
: "=&d" (x) \
|
||||
: "d" (0x3F) \
|
||||
)
|
||||
#else
|
||||
# define __save_and_cli(x) \
|
||||
__asm__ __volatile__( \
|
||||
"cli %0;" \
|
||||
: "=&d" (x) \
|
||||
)
|
||||
#endif
|
||||
|
||||
#define local_save_flags(x) \
|
||||
__asm__ __volatile__( \
|
||||
"cli %0;" \
|
||||
"sti %0;" \
|
||||
: "=d" (x) \
|
||||
)
|
||||
|
||||
#ifdef CONFIG_DEBUG_HWERR
|
||||
#define irqs_enabled_from_flags(x) (((x) & ~0x3f) != 0)
|
||||
#else
|
||||
#define irqs_enabled_from_flags(x) ((x) != 0x1f)
|
||||
#endif
|
||||
|
||||
#define local_irq_restore(x) \
|
||||
do { \
|
||||
if (irqs_enabled_from_flags(x)) \
|
||||
local_irq_enable(); \
|
||||
} while (0)
|
||||
|
||||
/* For spinlocks etc */
|
||||
#define local_irq_save(x) __save_and_cli(x)
|
||||
|
||||
#define irqs_disabled() \
|
||||
({ \
|
||||
unsigned long flags; \
|
||||
local_save_flags(flags); \
|
||||
!irqs_enabled_from_flags(flags); \
|
||||
})
|
||||
|
||||
#define local_irq_save_hw(x) local_irq_save(x)
|
||||
#define local_irq_restore_hw(x) local_irq_restore(x)
|
||||
#define local_irq_enable_hw() local_irq_enable()
|
||||
#define local_irq_disable_hw() local_irq_disable()
|
||||
#define irqs_disabled_hw() irqs_disabled()
|
||||
|
||||
#endif /* !CONFIG_IPIPE */
|
||||
/* Xenomai IPIPE helpers */
|
||||
#define local_irq_restore_hw(x) local_irq_restore(x)
|
||||
#define local_irq_save_hw(x) local_irq_save(x)
|
||||
#define local_irq_enable_hw(x) local_irq_enable(x)
|
||||
#define local_irq_disable_hw(x) local_irq_disable(x)
|
||||
#define irqs_disabled_hw(x) irqs_disabled(x)
|
||||
|
||||
#if ANOMALY_05000244 && defined(CONFIG_BFIN_ICACHE)
|
||||
# define NOP_PAD_ANOMALY_05000244 "nop; nop;"
|
||||
|
63
arch/blackfin/include/asm/irqflags.h
Normal file
63
arch/blackfin/include/asm/irqflags.h
Normal file
@ -0,0 +1,63 @@
|
||||
/*
|
||||
* interface to Blackfin CEC
|
||||
*
|
||||
* Copyright 2009 Analog Devices Inc.
|
||||
* Licensed under the GPL-2 or later.
|
||||
*/
|
||||
|
||||
#ifndef __ASM_BFIN_IRQFLAGS_H__
|
||||
#define __ASM_BFIN_IRQFLAGS_H__
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
# include <asm/pda.h>
|
||||
# include <asm/processor.h>
|
||||
/* Forward decl needed due to cdef inter dependencies */
|
||||
static inline uint32_t __pure bfin_dspid(void);
|
||||
# define blackfin_core_id() (bfin_dspid() & 0xff)
|
||||
# define bfin_irq_flags cpu_pda[blackfin_core_id()].imask
|
||||
#else
|
||||
extern unsigned long bfin_irq_flags;
|
||||
#endif
|
||||
|
||||
static inline void bfin_sti(unsigned long flags)
|
||||
{
|
||||
asm volatile("sti %0;" : : "d" (flags));
|
||||
}
|
||||
|
||||
static inline unsigned long bfin_cli(void)
|
||||
{
|
||||
unsigned long flags;
|
||||
asm volatile("cli %0;" : "=d" (flags));
|
||||
return flags;
|
||||
}
|
||||
|
||||
static inline void raw_local_irq_disable(void)
|
||||
{
|
||||
bfin_cli();
|
||||
}
|
||||
static inline void raw_local_irq_enable(void)
|
||||
{
|
||||
bfin_sti(bfin_irq_flags);
|
||||
}
|
||||
|
||||
#define raw_local_save_flags(flags) do { (flags) = bfin_read_IMASK(); } while (0)
|
||||
|
||||
#define raw_irqs_disabled_flags(flags) (((flags) & ~0x3f) == 0)
|
||||
|
||||
static inline void raw_local_irq_restore(unsigned long flags)
|
||||
{
|
||||
if (!raw_irqs_disabled_flags(flags))
|
||||
raw_local_irq_enable();
|
||||
}
|
||||
|
||||
static inline unsigned long __raw_local_irq_save(void)
|
||||
{
|
||||
unsigned long flags = bfin_cli();
|
||||
#ifdef CONFIG_DEBUG_HWERR
|
||||
bfin_sti(0x3f);
|
||||
#endif
|
||||
return flags;
|
||||
}
|
||||
#define raw_local_irq_save(flags) do { (flags) = __raw_local_irq_save(); } while (0)
|
||||
|
||||
#endif
|
@ -1,112 +0,0 @@
|
||||
/*
|
||||
* include/asm-generic/mutex-dec.h
|
||||
*
|
||||
* Generic implementation of the mutex fastpath, based on atomic
|
||||
* decrement/increment.
|
||||
*/
|
||||
#ifndef _ASM_GENERIC_MUTEX_DEC_H
|
||||
#define _ASM_GENERIC_MUTEX_DEC_H
|
||||
|
||||
/**
|
||||
* __mutex_fastpath_lock - try to take the lock by moving the count
|
||||
* from 1 to a 0 value
|
||||
* @count: pointer of type atomic_t
|
||||
* @fail_fn: function to call if the original value was not 1
|
||||
*
|
||||
* Change the count from 1 to a value lower than 1, and call <fail_fn> if
|
||||
* it wasn't 1 originally. This function MUST leave the value lower than
|
||||
* 1 even when the "1" assertion wasn't true.
|
||||
*/
|
||||
static inline void
|
||||
__mutex_fastpath_lock(atomic_t *count, fastcall void (*fail_fn)(atomic_t *))
|
||||
{
|
||||
if (unlikely(atomic_dec_return(count) < 0))
|
||||
fail_fn(count);
|
||||
else
|
||||
smp_mb();
|
||||
}
|
||||
|
||||
/**
|
||||
* __mutex_fastpath_lock_retval - try to take the lock by moving the count
|
||||
* from 1 to a 0 value
|
||||
* @count: pointer of type atomic_t
|
||||
* @fail_fn: function to call if the original value was not 1
|
||||
*
|
||||
* Change the count from 1 to a value lower than 1, and call <fail_fn> if
|
||||
* it wasn't 1 originally. This function returns 0 if the fastpath succeeds,
|
||||
* or anything the slow path function returns.
|
||||
*/
|
||||
static inline int
|
||||
__mutex_fastpath_lock_retval(atomic_t *count, fastcall int (*fail_fn)(atomic_t *))
|
||||
{
|
||||
if (unlikely(atomic_dec_return(count) < 0))
|
||||
return fail_fn(count);
|
||||
else {
|
||||
smp_mb();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* __mutex_fastpath_unlock - try to promote the count from 0 to 1
|
||||
* @count: pointer of type atomic_t
|
||||
* @fail_fn: function to call if the original value was not 0
|
||||
*
|
||||
* Try to promote the count from 0 to 1. If it wasn't 0, call <fail_fn>.
|
||||
* In the failure case, this function is allowed to either set the value to
|
||||
* 1, or to set it to a value lower than 1.
|
||||
*
|
||||
* If the implementation sets it to a value of lower than 1, then the
|
||||
* __mutex_slowpath_needs_to_unlock() macro needs to return 1, it needs
|
||||
* to return 0 otherwise.
|
||||
*/
|
||||
static inline void
|
||||
__mutex_fastpath_unlock(atomic_t *count, fastcall void (*fail_fn)(atomic_t *))
|
||||
{
|
||||
smp_mb();
|
||||
if (unlikely(atomic_inc_return(count) <= 0))
|
||||
fail_fn(count);
|
||||
}
|
||||
|
||||
#define __mutex_slowpath_needs_to_unlock() 1
|
||||
|
||||
/**
|
||||
* __mutex_fastpath_trylock - try to acquire the mutex, without waiting
|
||||
*
|
||||
* @count: pointer of type atomic_t
|
||||
* @fail_fn: fallback function
|
||||
*
|
||||
* Change the count from 1 to a value lower than 1, and return 0 (failure)
|
||||
* if it wasn't 1 originally, or return 1 (success) otherwise. This function
|
||||
* MUST leave the value lower than 1 even when the "1" assertion wasn't true.
|
||||
* Additionally, if the value was < 0 originally, this function must not leave
|
||||
* it to 0 on failure.
|
||||
*
|
||||
* If the architecture has no effective trylock variant, it should call the
|
||||
* <fail_fn> spinlock-based trylock variant unconditionally.
|
||||
*/
|
||||
static inline int
|
||||
__mutex_fastpath_trylock(atomic_t *count, int (*fail_fn)(atomic_t *))
|
||||
{
|
||||
/*
|
||||
* We have two variants here. The cmpxchg based one is the best one
|
||||
* because it never induce a false contention state. It is included
|
||||
* here because architectures using the inc/dec algorithms over the
|
||||
* xchg ones are much more likely to support cmpxchg natively.
|
||||
*
|
||||
* If not we fall back to the spinlock based variant - that is
|
||||
* just as efficient (and simpler) as a 'destructive' probing of
|
||||
* the mutex state would be.
|
||||
*/
|
||||
#ifdef __HAVE_ARCH_CMPXCHG
|
||||
if (likely(atomic_cmpxchg(count, 1, 0) == 1)) {
|
||||
smp_mb();
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
#else
|
||||
return fail_fn(count);
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
@ -4,4 +4,15 @@
|
||||
/* nothing to see, move along */
|
||||
#include <asm-generic/sections.h>
|
||||
|
||||
/* only used when MTD_UCLINUX */
|
||||
extern unsigned long memory_mtd_start, memory_mtd_end, mtd_size;
|
||||
|
||||
extern unsigned long _ramstart, _ramend, _rambase;
|
||||
extern unsigned long memory_start, memory_end, physical_mem_end;
|
||||
|
||||
extern char _stext_l1[], _etext_l1[], _sdata_l1[], _edata_l1[], _sbss_l1[],
|
||||
_ebss_l1[], _l1_lma_start[], _sdata_b_l1[], _sbss_b_l1[], _ebss_b_l1[],
|
||||
_stext_l2[], _etext_l2[], _sdata_l2[], _edata_l2[], _sbss_l2[],
|
||||
_ebss_l2[], _l2_lma_start[];
|
||||
|
||||
#endif
|
||||
|
@ -35,10 +35,10 @@
|
||||
#define _BLACKFIN_SYSTEM_H
|
||||
|
||||
#include <linux/linkage.h>
|
||||
#include <linux/compiler.h>
|
||||
#include <linux/irqflags.h>
|
||||
#include <mach/anomaly.h>
|
||||
#include <asm/cache.h>
|
||||
#include <asm/pda.h>
|
||||
#include <asm/processor.h>
|
||||
#include <asm/irq.h>
|
||||
|
||||
/*
|
||||
|
@ -380,8 +380,9 @@
|
||||
#define __NR_inotify_init1 365
|
||||
#define __NR_preadv 366
|
||||
#define __NR_pwritev 367
|
||||
#define __NR_rt_tgsigqueueinfo 368
|
||||
|
||||
#define __NR_syscall 368
|
||||
#define __NR_syscall 369
|
||||
#define NR_syscalls __NR_syscall
|
||||
|
||||
/* Old optional stuff no one actually uses */
|
||||
|
@ -15,6 +15,10 @@ else
|
||||
obj-y += time.o
|
||||
endif
|
||||
|
||||
obj-$(CONFIG_FUNCTION_TRACER) += ftrace-entry.o
|
||||
obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o
|
||||
CFLAGS_REMOVE_ftrace.o = -pg
|
||||
|
||||
obj-$(CONFIG_IPIPE) += ipipe.o
|
||||
obj-$(CONFIG_IPIPE_TRACE_MCOUNT) += mcount.o
|
||||
obj-$(CONFIG_BFIN_GPTIMERS) += gptimers.o
|
||||
@ -23,6 +27,7 @@ obj-$(CONFIG_MODULES) += module.o
|
||||
obj-$(CONFIG_KGDB) += kgdb.o
|
||||
obj-$(CONFIG_KGDB_TESTS) += kgdb_test.o
|
||||
obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
|
||||
obj-$(CONFIG_STACKTRACE) += stacktrace.o
|
||||
|
||||
# the kgdb test puts code into L2 and without linker
|
||||
# relaxation, we need to force long calls to/from it
|
||||
|
@ -453,10 +453,10 @@ void *dma_memcpy(void *pdst, const void *psrc, size_t size)
|
||||
unsigned long src = (unsigned long)psrc;
|
||||
size_t bulk, rest;
|
||||
|
||||
if (bfin_addr_dcachable(src))
|
||||
if (bfin_addr_dcacheable(src))
|
||||
blackfin_dcache_flush_range(src, src + size);
|
||||
|
||||
if (bfin_addr_dcachable(dst))
|
||||
if (bfin_addr_dcacheable(dst))
|
||||
blackfin_dcache_invalidate_range(dst, dst + size);
|
||||
|
||||
bulk = size & ~0xffff;
|
||||
|
@ -103,3 +103,8 @@ EXPORT_SYMBOL(__raw_smp_mark_barrier_asm);
|
||||
EXPORT_SYMBOL(__raw_smp_check_barrier_asm);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_FUNCTION_TRACER
|
||||
extern void _mcount(void);
|
||||
EXPORT_SYMBOL(_mcount);
|
||||
#endif
|
||||
|
@ -151,7 +151,7 @@ static noinline int dcplb_miss(unsigned int cpu)
|
||||
|
||||
d_data = CPLB_SUPV_WR | CPLB_VALID | CPLB_DIRTY | PAGE_SIZE_4KB;
|
||||
#ifdef CONFIG_BFIN_DCACHE
|
||||
if (bfin_addr_dcachable(addr)) {
|
||||
if (bfin_addr_dcacheable(addr)) {
|
||||
d_data |= CPLB_L1_CHBL | ANOMALY_05000158_WORKAROUND;
|
||||
#ifdef CONFIG_BFIN_WT
|
||||
d_data |= CPLB_L1_AOW | CPLB_WT;
|
||||
|
@ -28,6 +28,7 @@
|
||||
#include <asm/cplbinit.h>
|
||||
#include <asm/cplb.h>
|
||||
#include <asm/mmu_context.h>
|
||||
#include <asm/traps.h>
|
||||
|
||||
/*
|
||||
* WARNING
|
||||
@ -100,28 +101,6 @@ static inline void write_icplb_data(int cpu, int idx, unsigned long data,
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Given the contents of the status register, return the index of the
|
||||
* CPLB that caused the fault.
|
||||
*/
|
||||
static inline int faulting_cplb_index(int status)
|
||||
{
|
||||
int signbits = __builtin_bfin_norm_fr1x32(status & 0xFFFF);
|
||||
return 30 - signbits;
|
||||
}
|
||||
|
||||
/*
|
||||
* Given the contents of the status register and the DCPLB_DATA contents,
|
||||
* return true if a write access should be permitted.
|
||||
*/
|
||||
static inline int write_permitted(int status, unsigned long data)
|
||||
{
|
||||
if (status & FAULT_USERSUPV)
|
||||
return !!(data & CPLB_SUPV_WR);
|
||||
else
|
||||
return !!(data & CPLB_USER_WR);
|
||||
}
|
||||
|
||||
/* Counters to implement round-robin replacement. */
|
||||
static int icplb_rr_index[NR_CPUS] PDT_ATTR;
|
||||
static int dcplb_rr_index[NR_CPUS] PDT_ATTR;
|
||||
@ -245,43 +224,16 @@ MGR_ATTR static int dcplb_miss(int cpu)
|
||||
return CPLB_RELOADED;
|
||||
}
|
||||
|
||||
MGR_ATTR static noinline int dcplb_protection_fault(int cpu)
|
||||
{
|
||||
int status = bfin_read_DCPLB_STATUS();
|
||||
|
||||
nr_dcplb_prot[cpu]++;
|
||||
|
||||
if (likely(status & FAULT_RW)) {
|
||||
int idx = faulting_cplb_index(status);
|
||||
unsigned long regaddr = DCPLB_DATA0 + idx * 4;
|
||||
unsigned long data = bfin_read32(regaddr);
|
||||
|
||||
/* Check if fault is to dirty a clean page */
|
||||
if (!(data & CPLB_WT) && !(data & CPLB_DIRTY) &&
|
||||
write_permitted(status, data)) {
|
||||
|
||||
dcplb_tbl[cpu][idx].data = data;
|
||||
bfin_write32(regaddr, data);
|
||||
return CPLB_RELOADED;
|
||||
}
|
||||
}
|
||||
|
||||
return CPLB_PROT_VIOL;
|
||||
}
|
||||
|
||||
MGR_ATTR int cplb_hdr(int seqstat, struct pt_regs *regs)
|
||||
{
|
||||
int cause = seqstat & 0x3f;
|
||||
unsigned int cpu = smp_processor_id();
|
||||
switch (cause) {
|
||||
case 0x2C:
|
||||
case VEC_CPLB_I_M:
|
||||
return icplb_miss(cpu);
|
||||
case 0x26:
|
||||
case VEC_CPLB_M:
|
||||
return dcplb_miss(cpu);
|
||||
default:
|
||||
if (unlikely(cause == 0x23))
|
||||
return dcplb_protection_fault(cpu);
|
||||
|
||||
return CPLB_UNKNOWN_ERR;
|
||||
}
|
||||
}
|
||||
|
@ -202,11 +202,15 @@ asmlinkage void __init init_early_exception_vectors(void)
|
||||
asmlinkage void __init early_trap_c(struct pt_regs *fp, void *retaddr)
|
||||
{
|
||||
/* This can happen before the uart is initialized, so initialize
|
||||
* the UART now
|
||||
* the UART now (but only if we are running on the processor we think
|
||||
* we are compiled for - otherwise we write to MMRs that don't exist,
|
||||
* and cause other problems. Nothing comes out the UART, but it does
|
||||
* end up in the __buf_log.
|
||||
*/
|
||||
if (likely(early_console == NULL))
|
||||
if (likely(early_console == NULL) && CPUID == bfin_cpuid())
|
||||
setup_early_printk(DEFAULT_EARLY_PORT);
|
||||
|
||||
printk(KERN_EMERG "Early panic\n");
|
||||
dump_bfin_mem(fp);
|
||||
show_regs(fp);
|
||||
dump_bfin_trace_buffer();
|
||||
|
140
arch/blackfin/kernel/ftrace-entry.S
Normal file
140
arch/blackfin/kernel/ftrace-entry.S
Normal file
@ -0,0 +1,140 @@
|
||||
/*
|
||||
* mcount and friends -- ftrace stuff
|
||||
*
|
||||
* Copyright (C) 2009 Analog Devices Inc.
|
||||
* Licensed under the GPL-2 or later.
|
||||
*/
|
||||
|
||||
#include <linux/linkage.h>
|
||||
#include <asm/ftrace.h>
|
||||
|
||||
.text
|
||||
|
||||
/* GCC will have called us before setting up the function prologue, so we
|
||||
* can clobber the normal scratch registers, but we need to make sure to
|
||||
* save/restore the registers used for argument passing (R0-R2) in case
|
||||
* the profiled function is using them. With data registers, R3 is the
|
||||
* only one we can blow away. With pointer registers, we have P0-P2.
|
||||
*
|
||||
* Upon entry, the RETS will point to the top of the current profiled
|
||||
* function. And since GCC setup the frame for us, the previous function
|
||||
* will be waiting there. mmmm pie.
|
||||
*/
|
||||
ENTRY(__mcount)
|
||||
/* save third function arg early so we can do testing below */
|
||||
[--sp] = r2;
|
||||
|
||||
/* load the function pointer to the tracer */
|
||||
p0.l = _ftrace_trace_function;
|
||||
p0.h = _ftrace_trace_function;
|
||||
r3 = [p0];
|
||||
|
||||
/* optional micro optimization: don't call the stub tracer */
|
||||
r2.l = _ftrace_stub;
|
||||
r2.h = _ftrace_stub;
|
||||
cc = r2 == r3;
|
||||
if ! cc jump .Ldo_trace;
|
||||
|
||||
#ifdef CONFIG_FUNCTION_GRAPH_TRACER
|
||||
/* if the ftrace_graph_return function pointer is not set to
|
||||
* the ftrace_stub entry, call prepare_ftrace_return().
|
||||
*/
|
||||
p0.l = _ftrace_graph_return;
|
||||
p0.h = _ftrace_graph_return;
|
||||
r3 = [p0];
|
||||
cc = r2 == r3;
|
||||
if ! cc jump _ftrace_graph_caller;
|
||||
|
||||
/* similarly, if the ftrace_graph_entry function pointer is not
|
||||
* set to the ftrace_graph_entry_stub entry, ...
|
||||
*/
|
||||
p0.l = _ftrace_graph_entry;
|
||||
p0.h = _ftrace_graph_entry;
|
||||
r2.l = _ftrace_graph_entry_stub;
|
||||
r2.h = _ftrace_graph_entry_stub;
|
||||
r3 = [p0];
|
||||
cc = r2 == r3;
|
||||
if ! cc jump _ftrace_graph_caller;
|
||||
#endif
|
||||
|
||||
r2 = [sp++];
|
||||
rts;
|
||||
|
||||
.Ldo_trace:
|
||||
|
||||
/* save first/second function arg and the return register */
|
||||
[--sp] = r0;
|
||||
[--sp] = r1;
|
||||
[--sp] = rets;
|
||||
|
||||
/* setup the tracer function */
|
||||
p0 = r3;
|
||||
|
||||
/* tracer(ulong frompc, ulong selfpc):
|
||||
* frompc: the pc that did the call to ...
|
||||
* selfpc: ... this location
|
||||
* the selfpc itself will need adjusting for the mcount call
|
||||
*/
|
||||
r1 = rets;
|
||||
r0 = [fp + 4];
|
||||
r1 += -MCOUNT_INSN_SIZE;
|
||||
|
||||
/* call the tracer */
|
||||
call (p0);
|
||||
|
||||
/* restore state and get out of dodge */
|
||||
.Lfinish_trace:
|
||||
rets = [sp++];
|
||||
r1 = [sp++];
|
||||
r0 = [sp++];
|
||||
r2 = [sp++];
|
||||
|
||||
.globl _ftrace_stub
|
||||
_ftrace_stub:
|
||||
rts;
|
||||
ENDPROC(__mcount)
|
||||
|
||||
#ifdef CONFIG_FUNCTION_GRAPH_TRACER
|
||||
/* The prepare_ftrace_return() function is similar to the trace function
|
||||
* except it takes a pointer to the location of the frompc. This is so
|
||||
* the prepare_ftrace_return() can hijack it temporarily for probing
|
||||
* purposes.
|
||||
*/
|
||||
ENTRY(_ftrace_graph_caller)
|
||||
/* save first/second function arg and the return register */
|
||||
[--sp] = r0;
|
||||
[--sp] = r1;
|
||||
[--sp] = rets;
|
||||
|
||||
r0 = fp;
|
||||
r1 = rets;
|
||||
r0 += 4;
|
||||
r1 += -MCOUNT_INSN_SIZE;
|
||||
call _prepare_ftrace_return;
|
||||
|
||||
jump .Lfinish_trace;
|
||||
ENDPROC(_ftrace_graph_caller)
|
||||
|
||||
/* Undo the rewrite caused by ftrace_graph_caller(). The common function
|
||||
* ftrace_return_to_handler() will return the original rets so we can
|
||||
* restore it and be on our way.
|
||||
*/
|
||||
ENTRY(_return_to_handler)
|
||||
/* make sure original return values are saved */
|
||||
[--sp] = p0;
|
||||
[--sp] = r0;
|
||||
[--sp] = r1;
|
||||
|
||||
/* get original return address */
|
||||
call _ftrace_return_to_handler;
|
||||
rets = r0;
|
||||
|
||||
/* anomaly 05000371 - make sure we have at least three instructions
|
||||
* between rets setting and the return
|
||||
*/
|
||||
r1 = [sp++];
|
||||
r0 = [sp++];
|
||||
p0 = [sp++];
|
||||
rts;
|
||||
ENDPROC(_return_to_handler)
|
||||
#endif
|
42
arch/blackfin/kernel/ftrace.c
Normal file
42
arch/blackfin/kernel/ftrace.c
Normal file
@ -0,0 +1,42 @@
|
||||
/*
|
||||
* ftrace graph code
|
||||
*
|
||||
* Copyright (C) 2009 Analog Devices Inc.
|
||||
* Licensed under the GPL-2 or later.
|
||||
*/
|
||||
|
||||
#include <linux/ftrace.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/sched.h>
|
||||
#include <asm/atomic.h>
|
||||
|
||||
#ifdef CONFIG_FUNCTION_GRAPH_TRACER
|
||||
|
||||
/*
|
||||
* Hook the return address and push it in the stack of return addrs
|
||||
* in current thread info.
|
||||
*/
|
||||
void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr)
|
||||
{
|
||||
struct ftrace_graph_ent trace;
|
||||
unsigned long return_hooker = (unsigned long)&return_to_handler;
|
||||
|
||||
if (unlikely(atomic_read(¤t->tracing_graph_pause)))
|
||||
return;
|
||||
|
||||
if (ftrace_push_return_trace(*parent, self_addr, &trace.depth) == -EBUSY)
|
||||
return;
|
||||
|
||||
trace.func = self_addr;
|
||||
|
||||
/* Only trace if the calling function expects to */
|
||||
if (!ftrace_graph_entry(&trace)) {
|
||||
current->curr_ret_stack--;
|
||||
return;
|
||||
}
|
||||
|
||||
/* all is well in the world ! hijack RETS ... */
|
||||
*parent = return_hooker;
|
||||
}
|
||||
|
||||
#endif
|
@ -99,7 +99,7 @@ void __ipipe_handle_irq(unsigned irq, struct pt_regs *regs)
|
||||
* interrupt.
|
||||
*/
|
||||
m_ack = (regs == NULL || irq == IRQ_SYSTMR || irq == IRQ_CORETMR);
|
||||
this_domain = ipipe_current_domain;
|
||||
this_domain = __ipipe_current_domain;
|
||||
|
||||
if (unlikely(test_bit(IPIPE_STICKY_FLAG, &this_domain->irqs[irq].control)))
|
||||
head = &this_domain->p_link;
|
||||
@ -212,7 +212,9 @@ void __ipipe_unstall_root_raw(void)
|
||||
|
||||
int __ipipe_syscall_root(struct pt_regs *regs)
|
||||
{
|
||||
struct ipipe_percpu_domain_data *p;
|
||||
unsigned long flags;
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* We need to run the IRQ tail hook whenever we don't
|
||||
@ -231,29 +233,31 @@ int __ipipe_syscall_root(struct pt_regs *regs)
|
||||
/*
|
||||
* This routine either returns:
|
||||
* 0 -- if the syscall is to be passed to Linux;
|
||||
* 1 -- if the syscall should not be passed to Linux, and no
|
||||
* >0 -- if the syscall should not be passed to Linux, and no
|
||||
* tail work should be performed;
|
||||
* -1 -- if the syscall should not be passed to Linux but the
|
||||
* <0 -- if the syscall should not be passed to Linux but the
|
||||
* tail work has to be performed (for handling signals etc).
|
||||
*/
|
||||
|
||||
if (__ipipe_event_monitored_p(IPIPE_EVENT_SYSCALL) &&
|
||||
__ipipe_dispatch_event(IPIPE_EVENT_SYSCALL, regs) > 0) {
|
||||
if (ipipe_root_domain_p && !in_atomic()) {
|
||||
/*
|
||||
* Sync pending VIRQs before _TIF_NEED_RESCHED
|
||||
* is tested.
|
||||
*/
|
||||
local_irq_save_hw(flags);
|
||||
if ((ipipe_root_cpudom_var(irqpend_himask) & IPIPE_IRQMASK_VIRT) != 0)
|
||||
__ipipe_sync_pipeline(IPIPE_IRQMASK_VIRT);
|
||||
local_irq_restore_hw(flags);
|
||||
return -1;
|
||||
}
|
||||
if (!__ipipe_event_monitored_p(IPIPE_EVENT_SYSCALL))
|
||||
return 0;
|
||||
|
||||
ret = __ipipe_dispatch_event(IPIPE_EVENT_SYSCALL, regs);
|
||||
|
||||
local_irq_save_hw(flags);
|
||||
|
||||
if (!__ipipe_root_domain_p) {
|
||||
local_irq_restore_hw(flags);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
p = ipipe_root_cpudom_ptr();
|
||||
if ((p->irqpend_himask & IPIPE_IRQMASK_VIRT) != 0)
|
||||
__ipipe_sync_pipeline(IPIPE_IRQMASK_VIRT);
|
||||
|
||||
local_irq_restore_hw(flags);
|
||||
|
||||
return -ret;
|
||||
}
|
||||
|
||||
unsigned long ipipe_critical_enter(void (*syncfn) (void))
|
||||
@ -329,9 +333,7 @@ asmlinkage void __ipipe_sync_root(void)
|
||||
|
||||
void ___ipipe_sync_pipeline(unsigned long syncmask)
|
||||
{
|
||||
struct ipipe_domain *ipd = ipipe_current_domain;
|
||||
|
||||
if (ipd == ipipe_root_domain) {
|
||||
if (__ipipe_root_domain_p) {
|
||||
if (test_bit(IPIPE_SYNCDEFER_FLAG, &ipipe_root_cpudom_var(status)))
|
||||
return;
|
||||
}
|
||||
|
@ -1098,7 +1098,7 @@ static int show_cpuinfo(struct seq_file *m, void *v)
|
||||
CPUID, bfin_cpuid());
|
||||
|
||||
seq_printf(m, "model name\t: ADSP-%s %lu(MHz CCLK) %lu(MHz SCLK) (%s)\n"
|
||||
"stepping\t: %d\n",
|
||||
"stepping\t: %d ",
|
||||
cpu, cclk/1000000, sclk/1000000,
|
||||
#ifdef CONFIG_MPU
|
||||
"mpu on",
|
||||
@ -1107,7 +1107,16 @@ static int show_cpuinfo(struct seq_file *m, void *v)
|
||||
#endif
|
||||
revid);
|
||||
|
||||
seq_printf(m, "cpu MHz\t\t: %lu.%03lu/%lu.%03lu\n",
|
||||
if (bfin_revid() != bfin_compiled_revid()) {
|
||||
if (bfin_compiled_revid() == -1)
|
||||
seq_printf(m, "(Compiled for Rev none)");
|
||||
else if (bfin_compiled_revid() == 0xffff)
|
||||
seq_printf(m, "(Compiled for Rev any)");
|
||||
else
|
||||
seq_printf(m, "(Compiled for Rev %d)", bfin_compiled_revid());
|
||||
}
|
||||
|
||||
seq_printf(m, "\ncpu MHz\t\t: %lu.%03lu/%lu.%03lu\n",
|
||||
cclk/1000000, cclk%1000000,
|
||||
sclk/1000000, sclk%1000000);
|
||||
seq_printf(m, "bogomips\t: %lu.%02lu\n"
|
||||
@ -1172,6 +1181,9 @@ static int show_cpuinfo(struct seq_file *m, void *v)
|
||||
#ifdef __ARCH_SYNC_CORE_DCACHE
|
||||
seq_printf(m, "SMP Dcache Flushes\t: %lu\n\n", cpudata->dcache_invld_count);
|
||||
#endif
|
||||
#ifdef __ARCH_SYNC_CORE_ICACHE
|
||||
seq_printf(m, "SMP Icache Flushes\t: %lu\n\n", cpudata->icache_invld_count);
|
||||
#endif
|
||||
#ifdef CONFIG_BFIN_ICACHE_LOCK
|
||||
switch ((cpudata->imemctl >> 3) & WAYALL_L) {
|
||||
case WAY0_L:
|
||||
|
53
arch/blackfin/kernel/stacktrace.c
Normal file
53
arch/blackfin/kernel/stacktrace.c
Normal file
@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Blackfin stacktrace code (mostly copied from avr32)
|
||||
*
|
||||
* Copyright 2009 Analog Devices Inc.
|
||||
* Licensed under the GPL-2 or later.
|
||||
*/
|
||||
|
||||
#include <linux/sched.h>
|
||||
#include <linux/stacktrace.h>
|
||||
#include <linux/thread_info.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
register unsigned long current_frame_pointer asm("FP");
|
||||
|
||||
struct stackframe {
|
||||
unsigned long fp;
|
||||
unsigned long rets;
|
||||
};
|
||||
|
||||
/*
|
||||
* Save stack-backtrace addresses into a stack_trace buffer.
|
||||
*/
|
||||
void save_stack_trace(struct stack_trace *trace)
|
||||
{
|
||||
unsigned long low, high;
|
||||
unsigned long fp;
|
||||
struct stackframe *frame;
|
||||
int skip = trace->skip;
|
||||
|
||||
low = (unsigned long)task_stack_page(current);
|
||||
high = low + THREAD_SIZE;
|
||||
fp = current_frame_pointer;
|
||||
|
||||
while (fp >= low && fp <= (high - sizeof(*frame))) {
|
||||
frame = (struct stackframe *)fp;
|
||||
|
||||
if (skip) {
|
||||
skip--;
|
||||
} else {
|
||||
trace->entries[trace->nr_entries++] = frame->rets;
|
||||
if (trace->nr_entries >= trace->max_entries)
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* The next frame must be at a higher address than the
|
||||
* current frame.
|
||||
*/
|
||||
low = fp + sizeof(*frame);
|
||||
fp = frame->fp;
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(save_stack_trace);
|
@ -27,6 +27,7 @@
|
||||
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include <linux/bug.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/module.h>
|
||||
@ -238,6 +239,11 @@ asmlinkage void double_fault_c(struct pt_regs *fp)
|
||||
|
||||
}
|
||||
|
||||
static int kernel_mode_regs(struct pt_regs *regs)
|
||||
{
|
||||
return regs->ipend & 0xffc0;
|
||||
}
|
||||
|
||||
asmlinkage void trap_c(struct pt_regs *fp)
|
||||
{
|
||||
#ifdef CONFIG_DEBUG_BFIN_HWTRACE_ON
|
||||
@ -246,6 +252,7 @@ asmlinkage void trap_c(struct pt_regs *fp)
|
||||
#ifdef CONFIG_DEBUG_HUNT_FOR_ZERO
|
||||
unsigned int cpu = smp_processor_id();
|
||||
#endif
|
||||
const char *strerror = NULL;
|
||||
int sig = 0;
|
||||
siginfo_t info;
|
||||
unsigned long trapnr = fp->seqstat & SEQSTAT_EXCAUSE;
|
||||
@ -259,27 +266,10 @@ asmlinkage void trap_c(struct pt_regs *fp)
|
||||
* double faults if the stack has become corrupt
|
||||
*/
|
||||
|
||||
/* If the fault was caused by a kernel thread, or interrupt handler
|
||||
* we will kernel panic, so the system reboots.
|
||||
* If KGDB is enabled, don't set this for kernel breakpoints
|
||||
*/
|
||||
|
||||
/* TODO: check to see if we are in some sort of deferred HWERR
|
||||
* that we should be able to recover from, not kernel panic
|
||||
*/
|
||||
if ((bfin_read_IPEND() & 0xFFC0) && (trapnr != VEC_STEP)
|
||||
#ifdef CONFIG_KGDB
|
||||
&& (trapnr != VEC_EXCPT02)
|
||||
#ifndef CONFIG_KGDB
|
||||
/* IPEND is skipped if KGDB isn't enabled (see entry code) */
|
||||
fp->ipend = bfin_read_IPEND();
|
||||
#endif
|
||||
){
|
||||
console_verbose();
|
||||
oops_in_progress = 1;
|
||||
} else if (current) {
|
||||
if (current->mm == NULL) {
|
||||
console_verbose();
|
||||
oops_in_progress = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* trap_c() will be called for exceptions. During exceptions
|
||||
* processing, the pc value should be set with retx value.
|
||||
@ -307,15 +297,15 @@ asmlinkage void trap_c(struct pt_regs *fp)
|
||||
sig = SIGTRAP;
|
||||
CHK_DEBUGGER_TRAP_MAYBE();
|
||||
/* Check if this is a breakpoint in kernel space */
|
||||
if (fp->ipend & 0xffc0)
|
||||
return;
|
||||
if (kernel_mode_regs(fp))
|
||||
goto traps_done;
|
||||
else
|
||||
break;
|
||||
/* 0x03 - User Defined, userspace stack overflow */
|
||||
case VEC_EXCPT03:
|
||||
info.si_code = SEGV_STACKFLOW;
|
||||
sig = SIGSEGV;
|
||||
verbose_printk(KERN_NOTICE EXC_0x03(KERN_NOTICE));
|
||||
strerror = KERN_NOTICE EXC_0x03(KERN_NOTICE);
|
||||
CHK_DEBUGGER_TRAP_MAYBE();
|
||||
break;
|
||||
/* 0x02 - KGDB initial connection and break signal trap */
|
||||
@ -324,7 +314,7 @@ asmlinkage void trap_c(struct pt_regs *fp)
|
||||
info.si_code = TRAP_ILLTRAP;
|
||||
sig = SIGTRAP;
|
||||
CHK_DEBUGGER_TRAP();
|
||||
return;
|
||||
goto traps_done;
|
||||
#endif
|
||||
/* 0x04 - User Defined */
|
||||
/* 0x05 - User Defined */
|
||||
@ -344,7 +334,7 @@ asmlinkage void trap_c(struct pt_regs *fp)
|
||||
case VEC_EXCPT04 ... VEC_EXCPT15:
|
||||
info.si_code = ILL_ILLPARAOP;
|
||||
sig = SIGILL;
|
||||
verbose_printk(KERN_NOTICE EXC_0x04(KERN_NOTICE));
|
||||
strerror = KERN_NOTICE EXC_0x04(KERN_NOTICE);
|
||||
CHK_DEBUGGER_TRAP_MAYBE();
|
||||
break;
|
||||
/* 0x10 HW Single step, handled here */
|
||||
@ -353,15 +343,15 @@ asmlinkage void trap_c(struct pt_regs *fp)
|
||||
sig = SIGTRAP;
|
||||
CHK_DEBUGGER_TRAP_MAYBE();
|
||||
/* Check if this is a single step in kernel space */
|
||||
if (fp->ipend & 0xffc0)
|
||||
return;
|
||||
if (kernel_mode_regs(fp))
|
||||
goto traps_done;
|
||||
else
|
||||
break;
|
||||
/* 0x11 - Trace Buffer Full, handled here */
|
||||
case VEC_OVFLOW:
|
||||
info.si_code = TRAP_TRACEFLOW;
|
||||
sig = SIGTRAP;
|
||||
verbose_printk(KERN_NOTICE EXC_0x11(KERN_NOTICE));
|
||||
strerror = KERN_NOTICE EXC_0x11(KERN_NOTICE);
|
||||
CHK_DEBUGGER_TRAP_MAYBE();
|
||||
break;
|
||||
/* 0x12 - Reserved, Caught by default */
|
||||
@ -381,37 +371,54 @@ asmlinkage void trap_c(struct pt_regs *fp)
|
||||
/* 0x20 - Reserved, Caught by default */
|
||||
/* 0x21 - Undefined Instruction, handled here */
|
||||
case VEC_UNDEF_I:
|
||||
#ifdef CONFIG_BUG
|
||||
if (kernel_mode_regs(fp)) {
|
||||
switch (report_bug(fp->pc, fp)) {
|
||||
case BUG_TRAP_TYPE_NONE:
|
||||
break;
|
||||
case BUG_TRAP_TYPE_WARN:
|
||||
dump_bfin_trace_buffer();
|
||||
fp->pc += 2;
|
||||
goto traps_done;
|
||||
case BUG_TRAP_TYPE_BUG:
|
||||
/* call to panic() will dump trace, and it is
|
||||
* off at this point, so it won't be clobbered
|
||||
*/
|
||||
panic("BUG()");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
info.si_code = ILL_ILLOPC;
|
||||
sig = SIGILL;
|
||||
verbose_printk(KERN_NOTICE EXC_0x21(KERN_NOTICE));
|
||||
strerror = KERN_NOTICE EXC_0x21(KERN_NOTICE);
|
||||
CHK_DEBUGGER_TRAP_MAYBE();
|
||||
break;
|
||||
/* 0x22 - Illegal Instruction Combination, handled here */
|
||||
case VEC_ILGAL_I:
|
||||
info.si_code = ILL_ILLPARAOP;
|
||||
sig = SIGILL;
|
||||
verbose_printk(KERN_NOTICE EXC_0x22(KERN_NOTICE));
|
||||
strerror = KERN_NOTICE EXC_0x22(KERN_NOTICE);
|
||||
CHK_DEBUGGER_TRAP_MAYBE();
|
||||
break;
|
||||
/* 0x23 - Data CPLB protection violation, handled here */
|
||||
case VEC_CPLB_VL:
|
||||
info.si_code = ILL_CPLB_VI;
|
||||
sig = SIGBUS;
|
||||
verbose_printk(KERN_NOTICE EXC_0x23(KERN_NOTICE));
|
||||
strerror = KERN_NOTICE EXC_0x23(KERN_NOTICE);
|
||||
CHK_DEBUGGER_TRAP_MAYBE();
|
||||
break;
|
||||
/* 0x24 - Data access misaligned, handled here */
|
||||
case VEC_MISALI_D:
|
||||
info.si_code = BUS_ADRALN;
|
||||
sig = SIGBUS;
|
||||
verbose_printk(KERN_NOTICE EXC_0x24(KERN_NOTICE));
|
||||
strerror = KERN_NOTICE EXC_0x24(KERN_NOTICE);
|
||||
CHK_DEBUGGER_TRAP_MAYBE();
|
||||
break;
|
||||
/* 0x25 - Unrecoverable Event, handled here */
|
||||
case VEC_UNCOV:
|
||||
info.si_code = ILL_ILLEXCPT;
|
||||
sig = SIGILL;
|
||||
verbose_printk(KERN_NOTICE EXC_0x25(KERN_NOTICE));
|
||||
strerror = KERN_NOTICE EXC_0x25(KERN_NOTICE);
|
||||
CHK_DEBUGGER_TRAP_MAYBE();
|
||||
break;
|
||||
/* 0x26 - Data CPLB Miss, normal case is handled in _cplb_hdr,
|
||||
@ -419,7 +426,7 @@ asmlinkage void trap_c(struct pt_regs *fp)
|
||||
case VEC_CPLB_M:
|
||||
info.si_code = BUS_ADRALN;
|
||||
sig = SIGBUS;
|
||||
verbose_printk(KERN_NOTICE EXC_0x26(KERN_NOTICE));
|
||||
strerror = KERN_NOTICE EXC_0x26(KERN_NOTICE);
|
||||
break;
|
||||
/* 0x27 - Data CPLB Multiple Hits - Linux Trap Zero, handled here */
|
||||
case VEC_CPLB_MHIT:
|
||||
@ -427,10 +434,10 @@ asmlinkage void trap_c(struct pt_regs *fp)
|
||||
sig = SIGSEGV;
|
||||
#ifdef CONFIG_DEBUG_HUNT_FOR_ZERO
|
||||
if (cpu_pda[cpu].dcplb_fault_addr < FIXED_CODE_START)
|
||||
verbose_printk(KERN_NOTICE "NULL pointer access\n");
|
||||
strerror = KERN_NOTICE "NULL pointer access\n";
|
||||
else
|
||||
#endif
|
||||
verbose_printk(KERN_NOTICE EXC_0x27(KERN_NOTICE));
|
||||
strerror = KERN_NOTICE EXC_0x27(KERN_NOTICE);
|
||||
CHK_DEBUGGER_TRAP_MAYBE();
|
||||
break;
|
||||
/* 0x28 - Emulation Watchpoint, handled here */
|
||||
@ -440,8 +447,8 @@ asmlinkage void trap_c(struct pt_regs *fp)
|
||||
pr_debug(EXC_0x28(KERN_DEBUG));
|
||||
CHK_DEBUGGER_TRAP_MAYBE();
|
||||
/* Check if this is a watchpoint in kernel space */
|
||||
if (fp->ipend & 0xffc0)
|
||||
return;
|
||||
if (kernel_mode_regs(fp))
|
||||
goto traps_done;
|
||||
else
|
||||
break;
|
||||
#ifdef CONFIG_BF535
|
||||
@ -449,7 +456,7 @@ asmlinkage void trap_c(struct pt_regs *fp)
|
||||
case VEC_ISTRU_VL: /* ADSP-BF535 only (MH) */
|
||||
info.si_code = BUS_OPFETCH;
|
||||
sig = SIGBUS;
|
||||
verbose_printk(KERN_NOTICE "BF535: VEC_ISTRU_VL\n");
|
||||
strerror = KERN_NOTICE "BF535: VEC_ISTRU_VL\n";
|
||||
CHK_DEBUGGER_TRAP_MAYBE();
|
||||
break;
|
||||
#else
|
||||
@ -459,21 +466,21 @@ asmlinkage void trap_c(struct pt_regs *fp)
|
||||
case VEC_MISALI_I:
|
||||
info.si_code = BUS_ADRALN;
|
||||
sig = SIGBUS;
|
||||
verbose_printk(KERN_NOTICE EXC_0x2A(KERN_NOTICE));
|
||||
strerror = KERN_NOTICE EXC_0x2A(KERN_NOTICE);
|
||||
CHK_DEBUGGER_TRAP_MAYBE();
|
||||
break;
|
||||
/* 0x2B - Instruction CPLB protection violation, handled here */
|
||||
case VEC_CPLB_I_VL:
|
||||
info.si_code = ILL_CPLB_VI;
|
||||
sig = SIGBUS;
|
||||
verbose_printk(KERN_NOTICE EXC_0x2B(KERN_NOTICE));
|
||||
strerror = KERN_NOTICE EXC_0x2B(KERN_NOTICE);
|
||||
CHK_DEBUGGER_TRAP_MAYBE();
|
||||
break;
|
||||
/* 0x2C - Instruction CPLB miss, handled in _cplb_hdr */
|
||||
case VEC_CPLB_I_M:
|
||||
info.si_code = ILL_CPLB_MISS;
|
||||
sig = SIGBUS;
|
||||
verbose_printk(KERN_NOTICE EXC_0x2C(KERN_NOTICE));
|
||||
strerror = KERN_NOTICE EXC_0x2C(KERN_NOTICE);
|
||||
break;
|
||||
/* 0x2D - Instruction CPLB Multiple Hits, handled here */
|
||||
case VEC_CPLB_I_MHIT:
|
||||
@ -481,17 +488,17 @@ asmlinkage void trap_c(struct pt_regs *fp)
|
||||
sig = SIGSEGV;
|
||||
#ifdef CONFIG_DEBUG_HUNT_FOR_ZERO
|
||||
if (cpu_pda[cpu].icplb_fault_addr < FIXED_CODE_START)
|
||||
verbose_printk(KERN_NOTICE "Jump to NULL address\n");
|
||||
strerror = KERN_NOTICE "Jump to NULL address\n";
|
||||
else
|
||||
#endif
|
||||
verbose_printk(KERN_NOTICE EXC_0x2D(KERN_NOTICE));
|
||||
strerror = KERN_NOTICE EXC_0x2D(KERN_NOTICE);
|
||||
CHK_DEBUGGER_TRAP_MAYBE();
|
||||
break;
|
||||
/* 0x2E - Illegal use of Supervisor Resource, handled here */
|
||||
case VEC_ILL_RES:
|
||||
info.si_code = ILL_PRVOPC;
|
||||
sig = SIGILL;
|
||||
verbose_printk(KERN_NOTICE EXC_0x2E(KERN_NOTICE));
|
||||
strerror = KERN_NOTICE EXC_0x2E(KERN_NOTICE);
|
||||
CHK_DEBUGGER_TRAP_MAYBE();
|
||||
break;
|
||||
/* 0x2F - Reserved, Caught by default */
|
||||
@ -519,17 +526,17 @@ asmlinkage void trap_c(struct pt_regs *fp)
|
||||
case (SEQSTAT_HWERRCAUSE_SYSTEM_MMR):
|
||||
info.si_code = BUS_ADRALN;
|
||||
sig = SIGBUS;
|
||||
verbose_printk(KERN_NOTICE HWC_x2(KERN_NOTICE));
|
||||
strerror = KERN_NOTICE HWC_x2(KERN_NOTICE);
|
||||
break;
|
||||
/* External Memory Addressing Error */
|
||||
case (SEQSTAT_HWERRCAUSE_EXTERN_ADDR):
|
||||
info.si_code = BUS_ADRERR;
|
||||
sig = SIGBUS;
|
||||
verbose_printk(KERN_NOTICE HWC_x3(KERN_NOTICE));
|
||||
strerror = KERN_NOTICE HWC_x3(KERN_NOTICE);
|
||||
break;
|
||||
/* Performance Monitor Overflow */
|
||||
case (SEQSTAT_HWERRCAUSE_PERF_FLOW):
|
||||
verbose_printk(KERN_NOTICE HWC_x12(KERN_NOTICE));
|
||||
strerror = KERN_NOTICE HWC_x12(KERN_NOTICE);
|
||||
break;
|
||||
/* RAISE 5 instruction */
|
||||
case (SEQSTAT_HWERRCAUSE_RAISE_5):
|
||||
@ -546,7 +553,6 @@ asmlinkage void trap_c(struct pt_regs *fp)
|
||||
* if we get here we hit a reserved one, so panic
|
||||
*/
|
||||
default:
|
||||
oops_in_progress = 1;
|
||||
info.si_code = ILL_ILLPARAOP;
|
||||
sig = SIGILL;
|
||||
verbose_printk(KERN_EMERG "Caught Unhandled Exception, code = %08lx\n",
|
||||
@ -557,6 +563,16 @@ asmlinkage void trap_c(struct pt_regs *fp)
|
||||
|
||||
BUG_ON(sig == 0);
|
||||
|
||||
/* If the fault was caused by a kernel thread, or interrupt handler
|
||||
* we will kernel panic, so the system reboots.
|
||||
*/
|
||||
if (kernel_mode_regs(fp) || (current && !current->mm)) {
|
||||
console_verbose();
|
||||
oops_in_progress = 1;
|
||||
if (strerror)
|
||||
verbose_printk(strerror);
|
||||
}
|
||||
|
||||
if (sig != SIGTRAP) {
|
||||
dump_bfin_process(fp);
|
||||
dump_bfin_mem(fp);
|
||||
@ -606,8 +622,8 @@ asmlinkage void trap_c(struct pt_regs *fp)
|
||||
if (ANOMALY_05000461 && trapnr == VEC_HWERR && !access_ok(VERIFY_READ, fp->pc, 8))
|
||||
fp->pc = SAFE_USER_INSTRUCTION;
|
||||
|
||||
traps_done:
|
||||
trace_buffer_restore(j);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Typical exception handling routines */
|
||||
@ -792,6 +808,18 @@ void dump_bfin_trace_buffer(void)
|
||||
}
|
||||
EXPORT_SYMBOL(dump_bfin_trace_buffer);
|
||||
|
||||
#ifdef CONFIG_BUG
|
||||
int is_valid_bugaddr(unsigned long addr)
|
||||
{
|
||||
unsigned short opcode;
|
||||
|
||||
if (!get_instruction(&opcode, (unsigned short *)addr))
|
||||
return 0;
|
||||
|
||||
return opcode == BFIN_BUG_OPCODE;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Checks to see if the address pointed to is either a
|
||||
* 16-bit CALL instruction, or a 32-bit CALL instruction
|
||||
|
@ -54,6 +54,7 @@ SECTIONS
|
||||
SCHED_TEXT
|
||||
#endif
|
||||
LOCK_TEXT
|
||||
IRQENTRY_TEXT
|
||||
KPROBES_TEXT
|
||||
*(.text.*)
|
||||
*(.fixup)
|
||||
@ -166,6 +167,20 @@ SECTIONS
|
||||
}
|
||||
PERCPU(4)
|
||||
SECURITY_INIT
|
||||
|
||||
/* we have to discard exit text and such at runtime, not link time, to
|
||||
* handle embedded cross-section references (alt instructions, bug
|
||||
* table, eh_frame, etc...)
|
||||
*/
|
||||
.exit.text :
|
||||
{
|
||||
EXIT_TEXT
|
||||
}
|
||||
.exit.data :
|
||||
{
|
||||
EXIT_DATA
|
||||
}
|
||||
|
||||
.init.ramfs :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
@ -264,8 +279,6 @@ SECTIONS
|
||||
|
||||
/DISCARD/ :
|
||||
{
|
||||
EXIT_TEXT
|
||||
EXIT_DATA
|
||||
*(.exitcall.exit)
|
||||
}
|
||||
}
|
||||
|
@ -116,6 +116,7 @@ __sum16 ip_compute_csum(const void *buff, int len)
|
||||
{
|
||||
return (__force __sum16)~do_csum(buff, len);
|
||||
}
|
||||
EXPORT_SYMBOL(ip_compute_csum);
|
||||
|
||||
/*
|
||||
* copy from fs while checksumming, otherwise like csum_partial
|
||||
@ -130,6 +131,7 @@ csum_partial_copy_from_user(const void __user *src, void *dst,
|
||||
memcpy(dst, (__force void *)src, len);
|
||||
return csum_partial(dst, len, sum);
|
||||
}
|
||||
EXPORT_SYMBOL(csum_partial_copy_from_user);
|
||||
|
||||
/*
|
||||
* copy from ds while checksumming, otherwise like csum_partial
|
||||
|
@ -246,7 +246,7 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
|
||||
.modalias = "m25p80", /* Name of spi_driver for this device */
|
||||
.max_speed_hz = 25000000, /* max spi clock (SCK) speed in HZ */
|
||||
.bus_num = 0, /* Framework bus number */
|
||||
.chip_select = 1, /* Framework chip select. On STAMP537 it is SPISSEL1*/
|
||||
.chip_select = 2, /* On BF518F-EZBRD it's SPI0_SSEL2 */
|
||||
.platform_data = &bfin_spi_flash_data,
|
||||
.controller_data = &spi_flash_chip_info,
|
||||
.mode = SPI_MODE_3,
|
||||
@ -369,6 +369,11 @@ static struct resource bfin_spi0_resource[] = {
|
||||
[1] = {
|
||||
.start = CH_SPI0,
|
||||
.end = CH_SPI0,
|
||||
.flags = IORESOURCE_DMA,
|
||||
},
|
||||
[2] = {
|
||||
.start = IRQ_SPI0,
|
||||
.end = IRQ_SPI0,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
};
|
||||
@ -399,6 +404,11 @@ static struct resource bfin_spi1_resource[] = {
|
||||
[1] = {
|
||||
.start = CH_SPI1,
|
||||
.end = CH_SPI1,
|
||||
.flags = IORESOURCE_DMA,
|
||||
},
|
||||
[2] = {
|
||||
.start = IRQ_SPI1,
|
||||
.end = IRQ_SPI1,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
};
|
||||
|
@ -664,6 +664,11 @@ static struct resource bfin_spi0_resource[] = {
|
||||
[1] = {
|
||||
.start = CH_SPI,
|
||||
.end = CH_SPI,
|
||||
.flags = IORESOURCE_DMA,
|
||||
},
|
||||
[2] = {
|
||||
.start = IRQ_SPI,
|
||||
.end = IRQ_SPI,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
};
|
||||
|
@ -467,6 +467,11 @@ static struct resource bfin_spi0_resource[] = {
|
||||
[1] = {
|
||||
.start = CH_SPI,
|
||||
.end = CH_SPI,
|
||||
.flags = IORESOURCE_DMA,
|
||||
},
|
||||
[2] = {
|
||||
.start = IRQ_SPI,
|
||||
.end = IRQ_SPI,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
};
|
||||
|
@ -723,6 +723,11 @@ static struct resource bfin_spi0_resource[] = {
|
||||
[1] = {
|
||||
.start = CH_SPI,
|
||||
.end = CH_SPI,
|
||||
.flags = IORESOURCE_DMA,
|
||||
},
|
||||
[2] = {
|
||||
.start = IRQ_SPI,
|
||||
.end = IRQ_SPI,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
};
|
||||
|
@ -266,6 +266,11 @@ static struct resource bfin_spi0_resource[] = {
|
||||
[1] = {
|
||||
.start = CH_SPI,
|
||||
.end = CH_SPI,
|
||||
.flags = IORESOURCE_DMA,
|
||||
},
|
||||
[2] = {
|
||||
.start = IRQ_SPI,
|
||||
.end = IRQ_SPI,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
}
|
||||
};
|
||||
|
@ -162,6 +162,11 @@ static struct resource bfin_spi0_resource[] = {
|
||||
[1] = {
|
||||
.start = CH_SPI,
|
||||
.end = CH_SPI,
|
||||
.flags = IORESOURCE_DMA,
|
||||
},
|
||||
[2] = {
|
||||
.start = IRQ_SPI,
|
||||
.end = IRQ_SPI,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
}
|
||||
};
|
||||
|
@ -160,6 +160,11 @@ static struct resource bfin_spi0_resource[] = {
|
||||
[1] = {
|
||||
.start = CH_SPI,
|
||||
.end = CH_SPI,
|
||||
.flags = IORESOURCE_DMA,
|
||||
},
|
||||
[2] = {
|
||||
.start = IRQ_SPI,
|
||||
.end = IRQ_SPI,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
}
|
||||
};
|
||||
|
@ -196,6 +196,11 @@ static struct resource bfin_spi0_resource[] = {
|
||||
[1] = {
|
||||
.start = CH_SPI,
|
||||
.end = CH_SPI,
|
||||
.flags = IORESOURCE_DMA,
|
||||
},
|
||||
[2] = {
|
||||
.start = IRQ_SPI,
|
||||
.end = IRQ_SPI,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
}
|
||||
};
|
||||
|
@ -299,6 +299,11 @@ static struct resource bfin_spi0_resource[] = {
|
||||
[1] = {
|
||||
.start = CH_SPI,
|
||||
.end = CH_SPI,
|
||||
.flags = IORESOURCE_DMA,
|
||||
},
|
||||
[2] = {
|
||||
.start = IRQ_SPI,
|
||||
.end = IRQ_SPI,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
}
|
||||
};
|
||||
|
@ -182,8 +182,13 @@ static struct resource bfin_spi0_resource[] = {
|
||||
[1] = {
|
||||
.start = CH_SPI,
|
||||
.end = CH_SPI,
|
||||
.flags = IORESOURCE_DMA,
|
||||
},
|
||||
[2] = {
|
||||
.start = IRQ_SPI,
|
||||
.end = IRQ_SPI,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
/* SPI controller data */
|
||||
|
@ -184,6 +184,11 @@ static struct resource bfin_spi0_resource[] = {
|
||||
[1] = {
|
||||
.start = CH_SPI,
|
||||
.end = CH_SPI,
|
||||
.flags = IORESOURCE_DMA,
|
||||
},
|
||||
[2] = {
|
||||
.start = IRQ_SPI,
|
||||
.end = IRQ_SPI,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
};
|
||||
|
@ -398,8 +398,13 @@ static struct resource bfin_spi0_resource[] = {
|
||||
[1] = {
|
||||
.start = CH_SPI,
|
||||
.end = CH_SPI,
|
||||
.flags = IORESOURCE_DMA,
|
||||
},
|
||||
[2] = {
|
||||
.start = IRQ_SPI,
|
||||
.end = IRQ_SPI,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
/* SPI controller data */
|
||||
|
@ -1345,7 +1345,7 @@ static struct i2c_board_info __initdata bfin_i2c_board_info[] = {
|
||||
#if defined(CONFIG_PMIC_ADP5520) || defined(CONFIG_PMIC_ADP5520_MODULE)
|
||||
{
|
||||
I2C_BOARD_INFO("pmic-adp5520", 0x32),
|
||||
.irq = IRQ_PF7,
|
||||
.irq = IRQ_PG0,
|
||||
.platform_data = (void *)&adp5520_pdev_data,
|
||||
},
|
||||
#endif
|
||||
|
@ -182,6 +182,11 @@ static struct resource bfin_spi0_resource[] = {
|
||||
[1] = {
|
||||
.start = CH_SPI,
|
||||
.end = CH_SPI,
|
||||
.flags = IORESOURCE_DMA,
|
||||
},
|
||||
[2] = {
|
||||
.start = IRQ_SPI,
|
||||
.end = IRQ_SPI,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
}
|
||||
};
|
||||
|
@ -352,6 +352,11 @@ static struct resource bfin_spi0_resource[] = {
|
||||
[1] = {
|
||||
.start = CH_SPI0,
|
||||
.end = CH_SPI0,
|
||||
.flags = IORESOURCE_DMA,
|
||||
},
|
||||
[2] = {
|
||||
.start = IRQ_SPI0,
|
||||
.end = IRQ_SPI0,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
}
|
||||
};
|
||||
@ -366,6 +371,11 @@ static struct resource bfin_spi1_resource[] = {
|
||||
[1] = {
|
||||
.start = CH_SPI1,
|
||||
.end = CH_SPI1,
|
||||
.flags = IORESOURCE_DMA,
|
||||
},
|
||||
[2] = {
|
||||
.start = IRQ_SPI1,
|
||||
.end = IRQ_SPI1,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
}
|
||||
};
|
||||
|
@ -612,6 +612,11 @@ static struct resource bfin_spi0_resource[] = {
|
||||
[1] = {
|
||||
.start = CH_SPI0,
|
||||
.end = CH_SPI0,
|
||||
.flags = IORESOURCE_DMA,
|
||||
},
|
||||
[2] = {
|
||||
.start = IRQ_SPI0,
|
||||
.end = IRQ_SPI0,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
}
|
||||
};
|
||||
@ -626,6 +631,11 @@ static struct resource bfin_spi1_resource[] = {
|
||||
[1] = {
|
||||
.start = CH_SPI1,
|
||||
.end = CH_SPI1,
|
||||
.flags = IORESOURCE_DMA,
|
||||
},
|
||||
[2] = {
|
||||
.start = IRQ_SPI1,
|
||||
.end = IRQ_SPI1,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
}
|
||||
};
|
||||
|
@ -396,6 +396,8 @@ static struct platform_device bfin_sir3_device = {
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_SMSC911X) || defined(CONFIG_SMSC911X_MODULE)
|
||||
#include <linux/smsc911x.h>
|
||||
|
||||
static struct resource smsc911x_resources[] = {
|
||||
{
|
||||
.name = "smsc911x-memory",
|
||||
@ -409,11 +411,22 @@ static struct resource smsc911x_resources[] = {
|
||||
.flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL,
|
||||
},
|
||||
};
|
||||
|
||||
static struct smsc911x_platform_config smsc911x_config = {
|
||||
.flags = SMSC911X_USE_32BIT,
|
||||
.irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
|
||||
.irq_type = SMSC911X_IRQ_TYPE_OPEN_DRAIN,
|
||||
.phy_interface = PHY_INTERFACE_MODE_MII,
|
||||
};
|
||||
|
||||
static struct platform_device smsc911x_device = {
|
||||
.name = "smsc911x",
|
||||
.id = 0,
|
||||
.num_resources = ARRAY_SIZE(smsc911x_resources),
|
||||
.resource = smsc911x_resources,
|
||||
.dev = {
|
||||
.platform_data = &smsc911x_config,
|
||||
},
|
||||
};
|
||||
#endif
|
||||
|
||||
@ -741,6 +754,11 @@ static struct resource bfin_spi0_resource[] = {
|
||||
[1] = {
|
||||
.start = CH_SPI0,
|
||||
.end = CH_SPI0,
|
||||
.flags = IORESOURCE_DMA,
|
||||
},
|
||||
[2] = {
|
||||
.start = IRQ_SPI0,
|
||||
.end = IRQ_SPI0,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
}
|
||||
};
|
||||
@ -755,6 +773,11 @@ static struct resource bfin_spi1_resource[] = {
|
||||
[1] = {
|
||||
.start = CH_SPI1,
|
||||
.end = CH_SPI1,
|
||||
.flags = IORESOURCE_DMA,
|
||||
},
|
||||
[2] = {
|
||||
.start = IRQ_SPI1,
|
||||
.end = IRQ_SPI1,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
}
|
||||
};
|
||||
|
@ -177,8 +177,13 @@ static struct resource bfin_spi0_resource[] = {
|
||||
[1] = {
|
||||
.start = CH_SPI,
|
||||
.end = CH_SPI,
|
||||
.flags = IORESOURCE_DMA,
|
||||
},
|
||||
[2] = {
|
||||
.start = IRQ_SPI,
|
||||
.end = IRQ_SPI,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
/* SPI controller data */
|
||||
|
@ -304,6 +304,11 @@ static struct resource bfin_spi0_resource[] = {
|
||||
[1] = {
|
||||
.start = CH_SPI,
|
||||
.end = CH_SPI,
|
||||
.flags = IORESOURCE_DMA,
|
||||
},
|
||||
[2] = {
|
||||
.start = IRQ_SPI,
|
||||
.end = IRQ_SPI,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
}
|
||||
};
|
||||
|
@ -16,9 +16,21 @@
|
||||
void blackfin_invalidate_entire_dcache(void)
|
||||
{
|
||||
u32 dmem = bfin_read_DMEM_CONTROL();
|
||||
SSYNC();
|
||||
bfin_write_DMEM_CONTROL(dmem & ~0xc);
|
||||
SSYNC();
|
||||
bfin_write_DMEM_CONTROL(dmem);
|
||||
SSYNC();
|
||||
}
|
||||
|
||||
/* Invalidate the Entire Instruction cache by
|
||||
* clearing IMC bit
|
||||
*/
|
||||
void blackfin_invalidate_entire_icache(void)
|
||||
{
|
||||
u32 imem = bfin_read_IMEM_CONTROL();
|
||||
bfin_write_IMEM_CONTROL(imem & ~0x4);
|
||||
SSYNC();
|
||||
bfin_write_IMEM_CONTROL(imem);
|
||||
SSYNC();
|
||||
}
|
||||
|
||||
|
@ -42,6 +42,7 @@
|
||||
#include <asm/thread_info.h> /* TIF_NEED_RESCHED */
|
||||
#include <asm/asm-offsets.h>
|
||||
#include <asm/trace.h>
|
||||
#include <asm/traps.h>
|
||||
|
||||
#include <asm/context.S>
|
||||
|
||||
@ -84,13 +85,15 @@ ENTRY(_ex_workaround_261)
|
||||
if !cc jump _bfin_return_from_exception;
|
||||
/* fall through */
|
||||
R7 = P4;
|
||||
R6 = 0x26; /* Data CPLB Miss */
|
||||
R6 = VEC_CPLB_M; /* Data CPLB Miss */
|
||||
cc = R6 == R7;
|
||||
if cc jump _ex_dcplb_miss (BP);
|
||||
R6 = 0x23; /* Data CPLB Miss */
|
||||
#ifdef CONFIG_MPU
|
||||
R6 = VEC_CPLB_VL; /* Data CPLB Violation */
|
||||
cc = R6 == R7;
|
||||
if cc jump _ex_dcplb_viol (BP);
|
||||
/* Handle 0x23 Data CPLB Protection Violation
|
||||
#endif
|
||||
/* Handle Data CPLB Protection Violation
|
||||
* and Data CPLB Multiple Hits - Linux Trap Zero
|
||||
*/
|
||||
jump _ex_trap_c;
|
||||
@ -270,7 +273,7 @@ ENTRY(_bfin_return_from_exception)
|
||||
r6.l = lo(SEQSTAT_EXCAUSE);
|
||||
r6.h = hi(SEQSTAT_EXCAUSE);
|
||||
r7 = r7 & r6;
|
||||
r6 = 0x25;
|
||||
r6 = VEC_UNCOV;
|
||||
CC = R7 == R6;
|
||||
if CC JUMP _double_fault;
|
||||
#endif
|
||||
@ -1605,6 +1608,7 @@ ENTRY(_sys_call_table)
|
||||
.long _sys_inotify_init1 /* 365 */
|
||||
.long _sys_preadv
|
||||
.long _sys_pwritev
|
||||
.long _sys_rt_tgsigqueueinfo
|
||||
|
||||
.rept NR_syscalls-(.-_sys_call_table)/4
|
||||
.long _sys_ni_syscall
|
||||
|
@ -144,7 +144,7 @@ static void ipi_call_function(unsigned int cpu, struct ipi_message *msg)
|
||||
|
||||
static irqreturn_t ipi_handler(int irq, void *dev_instance)
|
||||
{
|
||||
struct ipi_message *msg, *mg;
|
||||
struct ipi_message *msg;
|
||||
struct ipi_message_queue *msg_queue;
|
||||
unsigned int cpu = smp_processor_id();
|
||||
|
||||
@ -154,7 +154,8 @@ static irqreturn_t ipi_handler(int irq, void *dev_instance)
|
||||
msg_queue->count++;
|
||||
|
||||
spin_lock(&msg_queue->lock);
|
||||
list_for_each_entry_safe(msg, mg, &msg_queue->head, list) {
|
||||
while (!list_empty(&msg_queue->head)) {
|
||||
msg = list_entry(msg_queue->head.next, typeof(*msg), list);
|
||||
list_del(&msg->list);
|
||||
switch (msg->type) {
|
||||
case BFIN_IPI_RESCHEDULE:
|
||||
@ -221,7 +222,7 @@ int smp_call_function(void (*func)(void *info), void *info, int wait)
|
||||
for_each_cpu_mask(cpu, callmap) {
|
||||
msg_queue = &per_cpu(ipi_msg_queue, cpu);
|
||||
spin_lock_irqsave(&msg_queue->lock, flags);
|
||||
list_add(&msg->list, &msg_queue->head);
|
||||
list_add_tail(&msg->list, &msg_queue->head);
|
||||
spin_unlock_irqrestore(&msg_queue->lock, flags);
|
||||
platform_send_ipi_cpu(cpu);
|
||||
}
|
||||
@ -261,7 +262,7 @@ int smp_call_function_single(int cpuid, void (*func) (void *info), void *info,
|
||||
|
||||
msg_queue = &per_cpu(ipi_msg_queue, cpu);
|
||||
spin_lock_irqsave(&msg_queue->lock, flags);
|
||||
list_add(&msg->list, &msg_queue->head);
|
||||
list_add_tail(&msg->list, &msg_queue->head);
|
||||
spin_unlock_irqrestore(&msg_queue->lock, flags);
|
||||
platform_send_ipi_cpu(cpu);
|
||||
|
||||
@ -292,7 +293,7 @@ void smp_send_reschedule(int cpu)
|
||||
|
||||
msg_queue = &per_cpu(ipi_msg_queue, cpu);
|
||||
spin_lock_irqsave(&msg_queue->lock, flags);
|
||||
list_add(&msg->list, &msg_queue->head);
|
||||
list_add_tail(&msg->list, &msg_queue->head);
|
||||
spin_unlock_irqrestore(&msg_queue->lock, flags);
|
||||
platform_send_ipi_cpu(cpu);
|
||||
|
||||
@ -320,7 +321,7 @@ void smp_send_stop(void)
|
||||
for_each_cpu_mask(cpu, callmap) {
|
||||
msg_queue = &per_cpu(ipi_msg_queue, cpu);
|
||||
spin_lock_irqsave(&msg_queue->lock, flags);
|
||||
list_add(&msg->list, &msg_queue->head);
|
||||
list_add_tail(&msg->list, &msg_queue->head);
|
||||
spin_unlock_irqrestore(&msg_queue->lock, flags);
|
||||
platform_send_ipi_cpu(cpu);
|
||||
}
|
||||
@ -468,6 +469,17 @@ void smp_icache_flush_range_others(unsigned long start, unsigned long end)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(smp_icache_flush_range_others);
|
||||
|
||||
#ifdef __ARCH_SYNC_CORE_ICACHE
|
||||
void resync_core_icache(void)
|
||||
{
|
||||
unsigned int cpu = get_cpu();
|
||||
blackfin_invalidate_entire_icache();
|
||||
++per_cpu(cpu_data, cpu).icache_invld_count;
|
||||
put_cpu();
|
||||
}
|
||||
EXPORT_SYMBOL(resync_core_icache);
|
||||
#endif
|
||||
|
||||
#ifdef __ARCH_SYNC_CORE_DCACHE
|
||||
unsigned long barrier_mask __attribute__ ((__section__(".l2.bss")));
|
||||
|
||||
|
@ -803,7 +803,7 @@ static void bfin_spi_pump_transfers(unsigned long data)
|
||||
drv_data->rx, drv_data->len_in_bytes);
|
||||
|
||||
/* invalidate caches, if needed */
|
||||
if (bfin_addr_dcachable((unsigned long) drv_data->rx))
|
||||
if (bfin_addr_dcacheable((unsigned long) drv_data->rx))
|
||||
invalidate_dcache_range((unsigned long) drv_data->rx,
|
||||
(unsigned long) (drv_data->rx +
|
||||
drv_data->len_in_bytes));
|
||||
@ -816,7 +816,7 @@ static void bfin_spi_pump_transfers(unsigned long data)
|
||||
dev_dbg(&drv_data->pdev->dev, "doing DMA out.\n");
|
||||
|
||||
/* flush caches, if needed */
|
||||
if (bfin_addr_dcachable((unsigned long) drv_data->tx))
|
||||
if (bfin_addr_dcacheable((unsigned long) drv_data->tx))
|
||||
flush_dcache_range((unsigned long) drv_data->tx,
|
||||
(unsigned long) (drv_data->tx +
|
||||
drv_data->len_in_bytes));
|
||||
|
Loading…
Reference in New Issue
Block a user