aboutsummaryrefslogtreecommitdiff
path: root/arch/blackfin/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'arch/blackfin/kernel')
-rw-r--r--arch/blackfin/kernel/.gitignore1
-rw-r--r--arch/blackfin/kernel/bfin_dma_5xx.c86
-rw-r--r--arch/blackfin/kernel/bfin_gpio.c18
-rw-r--r--arch/blackfin/kernel/bfin_ksyms.c1
-rw-r--r--arch/blackfin/kernel/cplb-mpu/cacheinit.c9
-rw-r--r--arch/blackfin/kernel/cplb-mpu/cplbinit.c2
-rw-r--r--arch/blackfin/kernel/cplb-nompu/cacheinit.c9
-rw-r--r--arch/blackfin/kernel/early_printk.c16
-rw-r--r--arch/blackfin/kernel/gptimers.c30
-rw-r--r--arch/blackfin/kernel/ipipe.c9
-rw-r--r--arch/blackfin/kernel/irqchip.c2
-rw-r--r--arch/blackfin/kernel/kgdb.c60
-rw-r--r--arch/blackfin/kernel/module.c22
-rw-r--r--arch/blackfin/kernel/process.c3
-rw-r--r--arch/blackfin/kernel/setup.c79
-rw-r--r--arch/blackfin/kernel/sys_bfin.c5
-rw-r--r--arch/blackfin/kernel/time-ts.c222
-rw-r--r--arch/blackfin/kernel/time.c53
-rw-r--r--arch/blackfin/kernel/traps.c52
-rw-r--r--arch/blackfin/kernel/vmlinux.lds.S5
20 files changed, 483 insertions, 201 deletions
diff --git a/arch/blackfin/kernel/.gitignore b/arch/blackfin/kernel/.gitignore
new file mode 100644
index 00000000000..c5f676c3c22
--- /dev/null
+++ b/arch/blackfin/kernel/.gitignore
@@ -0,0 +1 @@
+vmlinux.lds
diff --git a/arch/blackfin/kernel/bfin_dma_5xx.c b/arch/blackfin/kernel/bfin_dma_5xx.c
index 8531693fb48..763ed84ba45 100644
--- a/arch/blackfin/kernel/bfin_dma_5xx.c
+++ b/arch/blackfin/kernel/bfin_dma_5xx.c
@@ -20,6 +20,11 @@
#include <asm/dma.h>
#include <asm/uaccess.h>
+/*
+ * To make sure we work around 05000119 - we always check DMA_DONE bit,
+ * never the DMA_RUN bit
+ */
+
struct dma_channel dma_ch[MAX_DMA_CHANNELS];
EXPORT_SYMBOL(dma_ch);
@@ -232,6 +237,87 @@ void blackfin_dma_resume(void)
void __init blackfin_dma_early_init(void)
{
bfin_write_MDMA_S0_CONFIG(0);
+ bfin_write_MDMA_S1_CONFIG(0);
+}
+
+void __init early_dma_memcpy(void *pdst, const void *psrc, size_t size)
+{
+ unsigned long dst = (unsigned long)pdst;
+ unsigned long src = (unsigned long)psrc;
+ struct dma_register *dst_ch, *src_ch;
+
+ /* We assume that everything is 4 byte aligned, so include
+ * a basic sanity check
+ */
+ BUG_ON(dst % 4);
+ BUG_ON(src % 4);
+ BUG_ON(size % 4);
+
+ /* Force a sync in case a previous config reset on this channel
+ * occurred. This is needed so subsequent writes to DMA registers
+ * are not spuriously lost/corrupted.
+ */
+ __builtin_bfin_ssync();
+
+ src_ch = 0;
+ /* Find an avalible memDMA channel */
+ while (1) {
+ if (!src_ch || src_ch == (struct dma_register *)MDMA_S1_NEXT_DESC_PTR) {
+ dst_ch = (struct dma_register *)MDMA_D0_NEXT_DESC_PTR;
+ src_ch = (struct dma_register *)MDMA_S0_NEXT_DESC_PTR;
+ } else {
+ dst_ch = (struct dma_register *)MDMA_D1_NEXT_DESC_PTR;
+ src_ch = (struct dma_register *)MDMA_S1_NEXT_DESC_PTR;
+ }
+
+ if (!bfin_read16(&src_ch->cfg)) {
+ break;
+ } else {
+ if (bfin_read16(&src_ch->irq_status) & DMA_DONE)
+ bfin_write16(&src_ch->cfg, 0);
+ }
+
+ }
+
+ /* Destination */
+ bfin_write32(&dst_ch->start_addr, dst);
+ bfin_write16(&dst_ch->x_count, size >> 2);
+ bfin_write16(&dst_ch->x_modify, 1 << 2);
+ bfin_write16(&dst_ch->irq_status, DMA_DONE | DMA_ERR);
+
+ /* Source */
+ bfin_write32(&src_ch->start_addr, src);
+ bfin_write16(&src_ch->x_count, size >> 2);
+ bfin_write16(&src_ch->x_modify, 1 << 2);
+ bfin_write16(&src_ch->irq_status, DMA_DONE | DMA_ERR);
+
+ /* Enable */
+ bfin_write16(&src_ch->cfg, DMAEN | WDSIZE_32);
+ bfin_write16(&dst_ch->cfg, WNR | DI_EN | DMAEN | WDSIZE_32);
+
+ /* Since we are atomic now, don't use the workaround ssync */
+ __builtin_bfin_ssync();
+}
+
+void __init early_dma_memcpy_done(void)
+{
+ while ((bfin_read_MDMA_S0_CONFIG() && !(bfin_read_MDMA_D0_IRQ_STATUS() & DMA_DONE)) ||
+ (bfin_read_MDMA_S1_CONFIG() && !(bfin_read_MDMA_D1_IRQ_STATUS() & DMA_DONE)))
+ continue;
+
+ bfin_write_MDMA_D0_IRQ_STATUS(DMA_DONE | DMA_ERR);
+ bfin_write_MDMA_D1_IRQ_STATUS(DMA_DONE | DMA_ERR);
+ /*
+ * Now that DMA is done, we would normally flush cache, but
+ * i/d cache isn't running this early, so we don't bother,
+ * and just clear out the DMA channel for next time
+ */
+ bfin_write_MDMA_S0_CONFIG(0);
+ bfin_write_MDMA_S1_CONFIG(0);
+ bfin_write_MDMA_D0_CONFIG(0);
+ bfin_write_MDMA_D1_CONFIG(0);
+
+ __builtin_bfin_ssync();
}
/**
diff --git a/arch/blackfin/kernel/bfin_gpio.c b/arch/blackfin/kernel/bfin_gpio.c
index a0678da4053..beffa00a93c 100644
--- a/arch/blackfin/kernel/bfin_gpio.c
+++ b/arch/blackfin/kernel/bfin_gpio.c
@@ -313,15 +313,6 @@ inline void portmux_setup(unsigned short per)
# define portmux_setup(...) do { } while (0)
#endif
-static int __init bfin_gpio_init(void)
-{
- printk(KERN_INFO "Blackfin GPIO Controller\n");
-
- return 0;
-}
-arch_initcall(bfin_gpio_init);
-
-
#ifndef CONFIG_BF54x
/***********************************************************
*
@@ -1021,15 +1012,6 @@ int bfin_gpio_irq_request(unsigned gpio, const char *label)
local_irq_save_hw(flags);
- if (unlikely(reserved_gpio_irq_map[gpio_bank(gpio)] & gpio_bit(gpio))) {
- if (system_state == SYSTEM_BOOTING)
- dump_stack();
- printk(KERN_ERR
- "bfin-gpio: GPIO %d is already reserved as gpio-irq !\n",
- gpio);
- local_irq_restore_hw(flags);
- return -EBUSY;
- }
if (unlikely(reserved_peri_map[gpio_bank(gpio)] & gpio_bit(gpio))) {
if (system_state == SYSTEM_BOOTING)
dump_stack();
diff --git a/arch/blackfin/kernel/bfin_ksyms.c b/arch/blackfin/kernel/bfin_ksyms.c
index 01f917d58b5..53e893ff708 100644
--- a/arch/blackfin/kernel/bfin_ksyms.c
+++ b/arch/blackfin/kernel/bfin_ksyms.c
@@ -16,7 +16,6 @@ EXPORT_SYMBOL(bfin_return_from_exception);
/* All the Blackfin cache functions: mach-common/cache.S */
EXPORT_SYMBOL(blackfin_dcache_invalidate_range);
-EXPORT_SYMBOL(blackfin_icache_dcache_flush_range);
EXPORT_SYMBOL(blackfin_icache_flush_range);
EXPORT_SYMBOL(blackfin_dcache_flush_range);
EXPORT_SYMBOL(blackfin_dflush_page);
diff --git a/arch/blackfin/kernel/cplb-mpu/cacheinit.c b/arch/blackfin/kernel/cplb-mpu/cacheinit.c
index c6ff947f9d3..d5a86c3017f 100644
--- a/arch/blackfin/kernel/cplb-mpu/cacheinit.c
+++ b/arch/blackfin/kernel/cplb-mpu/cacheinit.c
@@ -55,7 +55,14 @@ void __cpuinit bfin_dcache_init(struct cplb_entry *dcplb_tbl)
}
ctrl = bfin_read_DMEM_CONTROL();
- ctrl |= DMEM_CNTR;
+
+ /*
+ * Anomaly notes:
+ * 05000287 - We implement workaround #2 - Change the DMEM_CONTROL
+ * register, so that the port preferences for DAG0 and DAG1 are set
+ * to port B
+ */
+ ctrl |= DMEM_CNTR | PORT_PREF0 | (ANOMALY_05000287 ? PORT_PREF1 : 0);
bfin_write_DMEM_CONTROL(ctrl);
SSYNC();
}
diff --git a/arch/blackfin/kernel/cplb-mpu/cplbinit.c b/arch/blackfin/kernel/cplb-mpu/cplbinit.c
index 3e329a6ce04..c006a44527b 100644
--- a/arch/blackfin/kernel/cplb-mpu/cplbinit.c
+++ b/arch/blackfin/kernel/cplb-mpu/cplbinit.c
@@ -64,7 +64,7 @@ void __init generate_cplb_tables_cpu(unsigned int cpu)
dcplb_tbl[cpu][i_d++].data = SDRAM_OOPS | PAGE_SIZE_1KB;
icplb_tbl[cpu][i_i].addr = 0;
- icplb_tbl[cpu][i_i++].data = i_cache | CPLB_USER_RD | PAGE_SIZE_1KB;
+ icplb_tbl[cpu][i_i++].data = CPLB_VALID | i_cache | CPLB_USER_RD | PAGE_SIZE_1KB;
/* Cover kernel memory with 4M pages. */
addr = 0;
diff --git a/arch/blackfin/kernel/cplb-nompu/cacheinit.c b/arch/blackfin/kernel/cplb-nompu/cacheinit.c
index c6ff947f9d3..d5a86c3017f 100644
--- a/arch/blackfin/kernel/cplb-nompu/cacheinit.c
+++ b/arch/blackfin/kernel/cplb-nompu/cacheinit.c
@@ -55,7 +55,14 @@ void __cpuinit bfin_dcache_init(struct cplb_entry *dcplb_tbl)
}
ctrl = bfin_read_DMEM_CONTROL();
- ctrl |= DMEM_CNTR;
+
+ /*
+ * Anomaly notes:
+ * 05000287 - We implement workaround #2 - Change the DMEM_CONTROL
+ * register, so that the port preferences for DAG0 and DAG1 are set
+ * to port B
+ */
+ ctrl |= DMEM_CNTR | PORT_PREF0 | (ANOMALY_05000287 ? PORT_PREF1 : 0);
bfin_write_DMEM_CONTROL(ctrl);
SSYNC();
}
diff --git a/arch/blackfin/kernel/early_printk.c b/arch/blackfin/kernel/early_printk.c
index c8ad051742e..3302719173c 100644
--- a/arch/blackfin/kernel/early_printk.c
+++ b/arch/blackfin/kernel/early_printk.c
@@ -178,25 +178,15 @@ int __init setup_early_printk(char *buf)
asmlinkage void __init init_early_exception_vectors(void)
{
+ u32 evt;
SSYNC();
/* cannot program in software:
* evt0 - emulation (jtag)
* evt1 - reset
*/
- bfin_write_EVT2(early_trap);
- bfin_write_EVT3(early_trap);
- bfin_write_EVT5(early_trap);
- bfin_write_EVT6(early_trap);
- bfin_write_EVT7(early_trap);
- bfin_write_EVT8(early_trap);
- bfin_write_EVT9(early_trap);
- bfin_write_EVT10(early_trap);
- bfin_write_EVT11(early_trap);
- bfin_write_EVT12(early_trap);
- bfin_write_EVT13(early_trap);
- bfin_write_EVT14(early_trap);
- bfin_write_EVT15(early_trap);
+ for (evt = EVT2; evt <= EVT15; evt += 4)
+ bfin_write32(evt, early_trap);
CSYNC();
/* Set all the return from interrupt, exception, NMI to a known place
diff --git a/arch/blackfin/kernel/gptimers.c b/arch/blackfin/kernel/gptimers.c
index 3a3e9615b00..7281a91d26b 100644
--- a/arch/blackfin/kernel/gptimers.c
+++ b/arch/blackfin/kernel/gptimers.c
@@ -189,10 +189,10 @@ void set_gptimer_status(int group, uint32_t value)
}
EXPORT_SYMBOL(set_gptimer_status);
-uint16_t get_gptimer_intr(int timer_id)
+int get_gptimer_intr(int timer_id)
{
tassert(timer_id < MAX_BLACKFIN_GPTIMERS);
- return (group_regs[BFIN_TIMER_OCTET(timer_id)]->status & timil_mask[timer_id]) ? 1 : 0;
+ return !!(group_regs[BFIN_TIMER_OCTET(timer_id)]->status & timil_mask[timer_id]);
}
EXPORT_SYMBOL(get_gptimer_intr);
@@ -203,10 +203,10 @@ void clear_gptimer_intr(int timer_id)
}
EXPORT_SYMBOL(clear_gptimer_intr);
-uint16_t get_gptimer_over(int timer_id)
+int get_gptimer_over(int timer_id)
{
tassert(timer_id < MAX_BLACKFIN_GPTIMERS);
- return (group_regs[BFIN_TIMER_OCTET(timer_id)]->status & tovf_mask[timer_id]) ? 1 : 0;
+ return !!(group_regs[BFIN_TIMER_OCTET(timer_id)]->status & tovf_mask[timer_id]);
}
EXPORT_SYMBOL(get_gptimer_over);
@@ -217,6 +217,13 @@ void clear_gptimer_over(int timer_id)
}
EXPORT_SYMBOL(clear_gptimer_over);
+int get_gptimer_run(int timer_id)
+{
+ tassert(timer_id < MAX_BLACKFIN_GPTIMERS);
+ return !!(group_regs[BFIN_TIMER_OCTET(timer_id)]->status & trun_mask[timer_id]);
+}
+EXPORT_SYMBOL(get_gptimer_run);
+
void set_gptimer_config(int timer_id, uint16_t config)
{
tassert(timer_id < MAX_BLACKFIN_GPTIMERS);
@@ -244,7 +251,7 @@ void enable_gptimers(uint16_t mask)
}
EXPORT_SYMBOL(enable_gptimers);
-void disable_gptimers(uint16_t mask)
+static void _disable_gptimers(uint16_t mask)
{
int i;
uint16_t m = mask;
@@ -253,6 +260,12 @@ void disable_gptimers(uint16_t mask)
group_regs[i]->disable = m & 0xFF;
m >>= 8;
}
+}
+
+void disable_gptimers(uint16_t mask)
+{
+ int i;
+ _disable_gptimers(mask);
for (i = 0; i < MAX_BLACKFIN_GPTIMERS; ++i)
if (mask & (1 << i))
group_regs[BFIN_TIMER_OCTET(i)]->status |= trun_mask[i];
@@ -260,6 +273,13 @@ void disable_gptimers(uint16_t mask)
}
EXPORT_SYMBOL(disable_gptimers);
+void disable_gptimers_sync(uint16_t mask)
+{
+ _disable_gptimers(mask);
+ SSYNC();
+}
+EXPORT_SYMBOL(disable_gptimers_sync);
+
void set_gptimer_pulse_hi(int timer_id)
{
tassert(timer_id < MAX_BLACKFIN_GPTIMERS);
diff --git a/arch/blackfin/kernel/ipipe.c b/arch/blackfin/kernel/ipipe.c
index a5de8d45424..5fc424803a1 100644
--- a/arch/blackfin/kernel/ipipe.c
+++ b/arch/blackfin/kernel/ipipe.c
@@ -167,7 +167,7 @@ int __ipipe_check_root(void)
void __ipipe_enable_irqdesc(struct ipipe_domain *ipd, unsigned irq)
{
struct irq_desc *desc = irq_to_desc(irq);
- int prio = desc->ic_prio;
+ int prio = __ipipe_get_irq_priority(irq);
desc->depth = 0;
if (ipd != &ipipe_root &&
@@ -178,8 +178,7 @@ EXPORT_SYMBOL(__ipipe_enable_irqdesc);
void __ipipe_disable_irqdesc(struct ipipe_domain *ipd, unsigned irq)
{
- struct irq_desc *desc = irq_to_desc(irq);
- int prio = desc->ic_prio;
+ int prio = __ipipe_get_irq_priority(irq);
if (ipd != &ipipe_root &&
atomic_dec_and_test(&__ipipe_irq_lvdepth[prio]))
@@ -310,12 +309,16 @@ int ipipe_trigger_irq(unsigned irq)
asmlinkage void __ipipe_sync_root(void)
{
+ void (*irq_tail_hook)(void) = (void (*)(void))__ipipe_irq_tail_hook;
unsigned long flags;
BUG_ON(irqs_disabled());
local_irq_save_hw(flags);
+ if (irq_tail_hook)
+ irq_tail_hook();
+
clear_thread_flag(TIF_IRQ_SYNC);
if (ipipe_root_cpudom_var(irqpend_himask) != 0)
diff --git a/arch/blackfin/kernel/irqchip.c b/arch/blackfin/kernel/irqchip.c
index 401bd32aa49..6e31e935bb3 100644
--- a/arch/blackfin/kernel/irqchip.c
+++ b/arch/blackfin/kernel/irqchip.c
@@ -59,12 +59,14 @@ static struct irq_chip bad_chip = {
.unmask = dummy_mask_unmask_irq,
};
+static int bad_stats;
static struct irq_desc bad_irq_desc = {
.status = IRQ_DISABLED,
.chip = &bad_chip,
.handle_irq = handle_bad_irq,
.depth = 1,
.lock = __SPIN_LOCK_UNLOCKED(irq_desc->lock),
+ .kstat_irqs = &bad_stats,
#ifdef CONFIG_SMP
.affinity = CPU_MASK_ALL
#endif
diff --git a/arch/blackfin/kernel/kgdb.c b/arch/blackfin/kernel/kgdb.c
index b163f6d3330..da28f796ad7 100644
--- a/arch/blackfin/kernel/kgdb.c
+++ b/arch/blackfin/kernel/kgdb.c
@@ -466,7 +466,7 @@ static int validate_memory_access_address(unsigned long addr, int size)
int cpu = raw_smp_processor_id();
if (size < 0)
- return EFAULT;
+ return -EFAULT;
if (addr >= 0x1000 && (addr + size) <= physical_mem_end)
return 0;
if (addr >= SYSMMR_BASE)
@@ -498,7 +498,7 @@ static int validate_memory_access_address(unsigned long addr, int size)
if (IN_MEM(addr, size, L2_START, L2_LENGTH))
return 0;
- return EFAULT;
+ return -EFAULT;
}
/*
@@ -508,14 +508,15 @@ static int validate_memory_access_address(unsigned long addr, int size)
int kgdb_mem2hex(char *mem, char *buf, int count)
{
char *tmp;
- int err = 0;
+ int err;
unsigned char *pch;
unsigned short mmr16;
unsigned long mmr32;
int cpu = raw_smp_processor_id();
- if (validate_memory_access_address((unsigned long)mem, count))
- return EFAULT;
+ err = validate_memory_access_address((unsigned long)mem, count);
+ if (err)
+ return err;
/*
* We use the upper half of buf as an intermediate buffer for the
@@ -533,7 +534,7 @@ int kgdb_mem2hex(char *mem, char *buf, int count)
*tmp++ = *pch++;
tmp -= 2;
} else
- err = EFAULT;
+ err = -EFAULT;
break;
case 4:
if ((unsigned int)mem % 4 == 0) {
@@ -545,10 +546,10 @@ int kgdb_mem2hex(char *mem, char *buf, int count)
*tmp++ = *pch++;
tmp -= 4;
} else
- err = EFAULT;
+ err = -EFAULT;
break;
default:
- err = EFAULT;
+ err = -EFAULT;
}
} else if ((cpu == 0 && IN_MEM(mem, count, L1_CODE_START, L1_CODE_LENGTH))
#ifdef CONFIG_SMP
@@ -557,7 +558,7 @@ int kgdb_mem2hex(char *mem, char *buf, int count)
) {
/* access L1 instruction SRAM*/
if (dma_memcpy(tmp, mem, count) == NULL)
- err = EFAULT;
+ err = -EFAULT;
} else
err = probe_kernel_read(tmp, mem, count);
@@ -585,24 +586,24 @@ int kgdb_ebin2mem(char *buf, char *mem, int count)
char *tmp_new;
unsigned short *mmr16;
unsigned long *mmr32;
- int err = 0;
- int size = 0;
+ int err;
+ int size;
int cpu = raw_smp_processor_id();
tmp_old = tmp_new = buf;
- while (count-- > 0) {
+ for (size = 0; size < count; ++size) {
if (*tmp_old == 0x7d)
*tmp_new = *(++tmp_old) ^ 0x20;
else
*tmp_new = *tmp_old;
tmp_new++;
tmp_old++;
- size++;
}
- if (validate_memory_access_address((unsigned long)mem, size))
- return EFAULT;
+ err = validate_memory_access_address((unsigned long)mem, size);
+ if (err)
+ return err;
if ((unsigned int)mem >= SYSMMR_BASE) { /*access MMR registers*/
switch (size) {
@@ -611,17 +612,17 @@ int kgdb_ebin2mem(char *buf, char *mem, int count)
mmr16 = (unsigned short *)buf;
*(unsigned short *)mem = *mmr16;
} else
- return EFAULT;
+ err = -EFAULT;
break;
case 4:
if ((unsigned int)mem % 4 == 0) {
mmr32 = (unsigned long *)buf;
*(unsigned long *)mem = *mmr32;
} else
- return EFAULT;
+ err = -EFAULT;
break;
default:
- return EFAULT;
+ err = -EFAULT;
}
} else if ((cpu == 0 && IN_MEM(mem, count, L1_CODE_START, L1_CODE_LENGTH))
#ifdef CONFIG_SMP
@@ -630,7 +631,7 @@ int kgdb_ebin2mem(char *buf, char *mem, int count)
) {
/* access L1 instruction SRAM */
if (dma_memcpy(mem, buf, size) == NULL)
- err = EFAULT;
+ err = -EFAULT;
} else
err = probe_kernel_write(mem, buf, size);
@@ -648,10 +649,12 @@ int kgdb_hex2mem(char *buf, char *mem, int count)
char *tmp_hex;
unsigned short *mmr16;
unsigned long *mmr32;
+ int err;
int cpu = raw_smp_processor_id();
- if (validate_memory_access_address((unsigned long)mem, count))
- return EFAULT;
+ err = validate_memory_access_address((unsigned long)mem, count);
+ if (err)
+ return err;
/*
* We use the upper half of buf as an intermediate buffer for the
@@ -673,17 +676,17 @@ int kgdb_hex2mem(char *buf, char *mem, int count)
mmr16 = (unsigned short *)tmp_raw;
*(unsigned short *)mem = *mmr16;
} else
- return EFAULT;
+ err = -EFAULT;
break;
case 4:
if ((unsigned int)mem % 4 == 0) {
mmr32 = (unsigned long *)tmp_raw;
*(unsigned long *)mem = *mmr32;
} else
- return EFAULT;
+ err = -EFAULT;
break;
default:
- return EFAULT;
+ err = -EFAULT;
}
} else if ((cpu == 0 && IN_MEM(mem, count, L1_CODE_START, L1_CODE_LENGTH))
#ifdef CONFIG_SMP
@@ -692,10 +695,11 @@ int kgdb_hex2mem(char *buf, char *mem, int count)
) {
/* access L1 instruction SRAM */
if (dma_memcpy(mem, tmp_raw, count) == NULL)
- return EFAULT;
+ err = -EFAULT;
} else
- return probe_kernel_write(mem, tmp_raw, count);
- return 0;
+ err = probe_kernel_write(mem, tmp_raw, count);
+
+ return err;
}
int kgdb_validate_break_address(unsigned long addr)
@@ -715,7 +719,7 @@ int kgdb_validate_break_address(unsigned long addr)
if (IN_MEM(addr, BREAK_INSTR_SIZE, L2_START, L2_LENGTH))
return 0;
- return EFAULT;
+ return -EFAULT;
}
int kgdb_arch_set_breakpoint(unsigned long addr, char *saved_instr)
diff --git a/arch/blackfin/kernel/module.c b/arch/blackfin/kernel/module.c
index 1bd7f2d018a..d5aee362668 100644
--- a/arch/blackfin/kernel/module.c
+++ b/arch/blackfin/kernel/module.c
@@ -201,8 +201,8 @@ apply_relocate(Elf_Shdr * sechdrs, const char *strtab,
/* Arithmetic relocations are handled. */
/* We do not expect LSETUP to be split and hence is not */
/* handled. */
-/* R_byte and R_byte2 are also not handled as the gas */
-/* does not generate it. */
+/* R_BFIN_BYTE and R_BFIN_BYTE2 are also not handled as the */
+/* gas does not generate it. */
/*************************************************************************/
int
apply_relocate_add(Elf_Shdr * sechdrs, const char *strtab,
@@ -243,8 +243,8 @@ apply_relocate_add(Elf_Shdr * sechdrs, const char *strtab,
#endif
switch (ELF32_R_TYPE(rel[i].r_info)) {
- case R_pcrel24:
- case R_pcrel24_jump_l:
+ case R_BFIN_PCREL24:
+ case R_BFIN_PCREL24_JUMP_L:
/* Add the value, subtract its postition */
location16 =
(uint16_t *) (sechdrs[sechdrs[relsec].sh_info].
@@ -266,18 +266,18 @@ apply_relocate_add(Elf_Shdr * sechdrs, const char *strtab,
(*location16 & 0xff00) | (value >> 16 & 0x00ff);
*(location16 + 1) = value & 0xffff;
break;
- case R_pcrel12_jump:
- case R_pcrel12_jump_s:
+ case R_BFIN_PCREL12_JUMP:
+ case R_BFIN_PCREL12_JUMP_S:
value -= (uint32_t) location32;
value >>= 1;
*location16 = (value & 0xfff);
break;
- case R_pcrel10:
+ case R_BFIN_PCREL10:
value -= (uint32_t) location32;
value >>= 1;
*location16 = (value & 0x3ff);
break;
- case R_luimm16:
+ case R_BFIN_LUIMM16:
pr_debug("before %x after %x\n", *location16,
(value & 0xffff));
tmp = (value & 0xffff);
@@ -286,7 +286,7 @@ apply_relocate_add(Elf_Shdr * sechdrs, const char *strtab,
} else
*location16 = tmp;
break;
- case R_huimm16:
+ case R_BFIN_HUIMM16:
pr_debug("before %x after %x\n", *location16,
((value >> 16) & 0xffff));
tmp = ((value >> 16) & 0xffff);
@@ -295,10 +295,10 @@ apply_relocate_add(Elf_Shdr * sechdrs, const char *strtab,
} else
*location16 = tmp;
break;
- case R_rimm16:
+ case R_BFIN_RIMM16:
*location16 = (value & 0xffff);
break;
- case R_byte4_data:
+ case R_BFIN_BYTE4_DATA:
pr_debug("before %x after %x\n", *location32, value);
*location32 = value;
break;
diff --git a/arch/blackfin/kernel/process.c b/arch/blackfin/kernel/process.c
index e040e03335e..30d0843ed70 100644
--- a/arch/blackfin/kernel/process.c
+++ b/arch/blackfin/kernel/process.c
@@ -322,6 +322,9 @@ void finish_atomic_sections (struct pt_regs *regs)
}
#if defined(CONFIG_ACCESS_CHECK)
+#ifdef CONFIG_ACCESS_OK_L1
+__attribute__((l1_text))
+#endif
/* Return 1 if access to memory range is OK, 0 otherwise */
int _access_ok(unsigned long addr, unsigned long size)
{
diff --git a/arch/blackfin/kernel/setup.c b/arch/blackfin/kernel/setup.c
index a58687bdee6..80447f99c2b 100644
--- a/arch/blackfin/kernel/setup.c
+++ b/arch/blackfin/kernel/setup.c
@@ -18,9 +18,12 @@
#include <linux/tty.h>
#include <linux/pfn.h>
+#ifdef CONFIG_MTD_UCLINUX
+#include <linux/mtd/map.h>
#include <linux/ext2_fs.h>
#include <linux/cramfs_fs.h>
#include <linux/romfs_fs.h>
+#endif
#include <asm/cplb.h>
#include <asm/cacheflush.h>
@@ -45,6 +48,7 @@ EXPORT_SYMBOL(_ramend);
EXPORT_SYMBOL(reserved_mem_dcache_on);
#ifdef CONFIG_MTD_UCLINUX
+extern struct map_info uclinux_ram_map;
unsigned long memory_mtd_end, memory_mtd_start, mtd_size;
unsigned long _ebss;
EXPORT_SYMBOL(memory_mtd_end);
@@ -150,40 +154,45 @@ void __init bfin_relocate_l1_mem(void)
unsigned long l1_data_b_length;
unsigned long l2_length;
+ /*
+ * due to the ALIGN(4) in the arch/blackfin/kernel/vmlinux.lds.S
+ * we know that everything about l1 text/data is nice and aligned,
+ * so copy by 4 byte chunks, and don't worry about overlapping
+ * src/dest.
+ *
+ * We can't use the dma_memcpy functions, since they can call
+ * scheduler functions which might be in L1 :( and core writes
+ * into L1 instruction cause bad access errors, so we are stuck,
+ * we are required to use DMA, but can't use the common dma
+ * functions. We can't use memcpy either - since that might be
+ * going to be in the relocated L1
+ */
+
blackfin_dma_early_init();
+ /* if necessary, copy _stext_l1 to _etext_l1 to L1 instruction SRAM */
l1_code_length = _etext_l1 - _stext_l1;
- if (l1_code_length > L1_CODE_LENGTH)
- panic("L1 Instruction SRAM Overflow\n");
- /* cannot complain as printk is not available as yet.
- * But we can continue booting and complain later!
- */
-
- /* Copy _stext_l1 to _etext_l1 to L1 instruction SRAM */
- dma_memcpy(_stext_l1, _l1_lma_start, l1_code_length);
+ if (l1_code_length)
+ early_dma_memcpy(_stext_l1, _l1_lma_start, l1_code_length);
+ /* if necessary, copy _sdata_l1 to _sbss_l1 to L1 data bank A SRAM */
l1_data_a_length = _sbss_l1 - _sdata_l1;
- if (l1_data_a_length > L1_DATA_A_LENGTH)
- panic("L1 Data SRAM Bank A Overflow\n");
-
- /* Copy _sdata_l1 to _sbss_l1 to L1 data bank A SRAM */
- dma_memcpy(_sdata_l1, _l1_lma_start + l1_code_length, l1_data_a_length);
+ if (l1_data_a_length)
+ early_dma_memcpy(_sdata_l1, _l1_lma_start + l1_code_length, l1_data_a_length);
+ /* if necessary, copy _sdata_b_l1 to _sbss_b_l1 to L1 data bank B SRAM */
l1_data_b_length = _sbss_b_l1 - _sdata_b_l1;
- if (l1_data_b_length > L1_DATA_B_LENGTH)
- panic("L1 Data SRAM Bank B Overflow\n");
-
- /* Copy _sdata_b_l1 to _sbss_b_l1 to L1 data bank B SRAM */
- dma_memcpy(_sdata_b_l1, _l1_lma_start + l1_code_length +
+ if (l1_data_b_length)
+ early_dma_memcpy(_sdata_b_l1, _l1_lma_start + l1_code_length +
l1_data_a_length, l1_data_b_length);
+ early_dma_memcpy_done();
+
+ /* if necessary, copy _stext_l2 to _edata_l2 to L2 SRAM */
if (L2_LENGTH != 0) {
l2_length = _sbss_l2 - _stext_l2;
- if (l2_length > L2_LENGTH)
- panic("L2 SRAM Overflow\n");
-
- /* Copy _stext_l2 to _edata_l2 to L2 SRAM */
- dma_memcpy(_stext_l2, _l2_lma_start, l2_length);
+ if (l2_length)
+ memcpy(_stext_l2, _l2_lma_start, l2_length);
}
}
@@ -472,7 +481,7 @@ static __init void memory_setup(void)
if (DMA_UNCACHED_REGION > (_ramend - _ramstart)) {
console_init();
- panic("DMA region exceeds memory limit: %lu.\n",
+ panic("DMA region exceeds memory limit: %lu.",
_ramend - _ramstart);
}
memory_end = _ramend - DMA_UNCACHED_REGION;
@@ -526,14 +535,13 @@ static __init void memory_setup(void)
if (mtd_size == 0) {
console_init();
- panic("Don't boot kernel without rootfs attached.\n");
+ panic("Don't boot kernel without rootfs attached.");
}
/* Relocate MTD image to the top of memory after the uncached memory area */
- dma_memcpy((char *)memory_end, _end, mtd_size);
-
- memory_mtd_start = memory_end;
- _ebss = memory_mtd_start; /* define _ebss for compatible */
+ uclinux_ram_map.phys = memory_mtd_start = memory_end;
+ uclinux_ram_map.size = mtd_size;
+ dma_memcpy((void *)uclinux_ram_map.phys, _end, uclinux_ram_map.size);
#endif /* CONFIG_MTD_UCLINUX */
#if (defined(CONFIG_BFIN_ICACHE) && ANOMALY_05000263)
@@ -796,10 +804,8 @@ void __init setup_arch(char **cmdline_p)
cclk = get_cclk();
sclk = get_sclk();
-#if !defined(CONFIG_BFIN_KERNEL_CLOCK)
- if (ANOMALY_05000273 && cclk == sclk)
- panic("ANOMALY 05000273, SCLK can not be same as CCLK");
-#endif
+ if ((ANOMALY_05000273 || ANOMALY_05000274) && (cclk >> 1) < sclk)
+ panic("ANOMALY 05000273 or 05000274: CCLK must be >= 2*SCLK");
#ifdef BF561_FAMILY
if (ANOMALY_05000266) {
@@ -881,7 +887,7 @@ void __init setup_arch(char **cmdline_p)
printk(KERN_ERR "Warning: Compiled for Rev %d, but running on Rev %d\n",
bfin_compiled_revid(), bfin_revid());
if (bfin_compiled_revid() > bfin_revid())
- panic("Error: you are missing anomaly workarounds for this rev\n");
+ panic("Error: you are missing anomaly workarounds for this rev");
}
}
if (bfin_revid() < CONFIG_BF_REV_MIN || bfin_revid() > CONFIG_BF_REV_MAX)
@@ -891,16 +897,13 @@ void __init setup_arch(char **cmdline_p)
/* We can't run on BF548-0.1 due to ANOMALY 05000448 */
if (bfin_cpuid() == 0x27de && bfin_revid() == 1)
- panic("You can't run on this processor due to 05000448\n");
+ panic("You can't run on this processor due to 05000448");
printk(KERN_INFO "Blackfin Linux support by http://blackfin.uclinux.org/\n");
printk(KERN_INFO "Processor Speed: %lu MHz core clock and %lu MHz System Clock\n",
cclk / 1000000, sclk / 1000000);
- if (ANOMALY_05000273 && (cclk >> 1) <= sclk)
- printk("\n\n\nANOMALY_05000273: CCLK must be >= 2*SCLK !!!\n\n\n");
-
setup_bootmem_allocator();
paging_init();
diff --git a/arch/blackfin/kernel/sys_bfin.c b/arch/blackfin/kernel/sys_bfin.c
index fce49d7cf00..a8f1329c15a 100644
--- a/arch/blackfin/kernel/sys_bfin.c
+++ b/arch/blackfin/kernel/sys_bfin.c
@@ -78,11 +78,6 @@ asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
return do_mmap2(addr, len, prot, flags, fd, pgoff);
}
-asmlinkage int sys_getpagesize(void)
-{
- return PAGE_SIZE;
-}
-
asmlinkage void *sys_sram_alloc(size_t size, unsigned long flags)
{
return sram_alloc_with_lsl(size, flags);
diff --git a/arch/blackfin/kernel/time-ts.c b/arch/blackfin/kernel/time-ts.c
index 27646121280..0791eba40d9 100644
--- a/arch/blackfin/kernel/time-ts.c
+++ b/arch/blackfin/kernel/time-ts.c
@@ -20,8 +20,9 @@
#include <asm/blackfin.h>
#include <asm/time.h>
+#include <asm/gptimers.h>
-#ifdef CONFIG_CYCLES_CLOCKSOURCE
+#if defined(CONFIG_CYCLES_CLOCKSOURCE)
/* Accelerators for sched_clock()
* convert from cycles(64bits) => nanoseconds (64bits)
@@ -58,15 +59,15 @@ static inline unsigned long long cycles_2_ns(cycle_t cyc)
return (cyc * cyc2ns_scale) >> CYC2NS_SCALE_FACTOR;
}
-static cycle_t read_cycles(struct clocksource *cs)
+static cycle_t bfin_read_cycles(struct clocksource *cs)
{
return __bfin_cycles_off + (get_cycles() << __bfin_cycles_mod);
}
-static struct clocksource clocksource_bfin = {
- .name = "bfin_cycles",
+static struct clocksource bfin_cs_cycles = {
+ .name = "bfin_cs_cycles",
.rating = 350,
- .read = read_cycles,
+ .read = bfin_read_cycles,
.mask = CLOCKSOURCE_MASK(64),
.shift = 22,
.flags = CLOCK_SOURCE_IS_CONTINUOUS,
@@ -74,53 +75,198 @@ static struct clocksource clocksource_bfin = {
unsigned long long sched_clock(void)
{
- return cycles_2_ns(read_cycles(&clocksource_bfin));
+ return cycles_2_ns(bfin_read_cycles(&bfin_cs_cycles));
}
-static int __init bfin_clocksource_init(void)
+static int __init bfin_cs_cycles_init(void)
{
set_cyc2ns_scale(get_cclk() / 1000);
- clocksource_bfin.mult = clocksource_hz2mult(get_cclk(), clocksource_bfin.shift);
+ bfin_cs_cycles.mult = \
+ clocksource_hz2mult(get_cclk(), bfin_cs_cycles.shift);
- if (clocksource_register(&clocksource_bfin))
+ if (clocksource_register(&bfin_cs_cycles))
panic("failed to register clocksource");
return 0;
}
+#else
+# define bfin_cs_cycles_init()
+#endif
+
+#ifdef CONFIG_GPTMR0_CLOCKSOURCE