aboutsummaryrefslogtreecommitdiffstats
path: root/arch/microblaze/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'arch/microblaze/kernel')
-rw-r--r--arch/microblaze/kernel/cpu/cpuinfo.c1
-rw-r--r--arch/microblaze/kernel/dma.c82
-rw-r--r--arch/microblaze/kernel/exceptions.c2
-rw-r--r--arch/microblaze/kernel/process.c1
-rw-r--r--arch/microblaze/kernel/ptrace.c2
-rw-r--r--arch/microblaze/kernel/timer.c3
6 files changed, 69 insertions, 22 deletions
diff --git a/arch/microblaze/kernel/cpu/cpuinfo.c b/arch/microblaze/kernel/cpu/cpuinfo.c
index 44394d80a683..54194b28574a 100644
--- a/arch/microblaze/kernel/cpu/cpuinfo.c
+++ b/arch/microblaze/kernel/cpu/cpuinfo.c
@@ -34,6 +34,7 @@ const struct cpu_ver_key cpu_ver_lookup[] = {
{"8.00.a", 0x12},
{"8.00.b", 0x13},
{"8.10.a", 0x14},
+ {"8.20.a", 0x15},
{NULL, 0},
};
diff --git a/arch/microblaze/kernel/dma.c b/arch/microblaze/kernel/dma.c
index b159b8a847d6..65a4af4cbbbe 100644
--- a/arch/microblaze/kernel/dma.c
+++ b/arch/microblaze/kernel/dma.c
@@ -12,7 +12,6 @@
#include <linux/dma-debug.h>
#include <linux/export.h>
#include <asm/bug.h>
-#include <asm/cacheflush.h>
/*
* Generic direct DMA implementation
@@ -22,21 +21,6 @@
* can set archdata.dma_data to an unsigned long holding the offset. By
* default the offset is PCI_DRAM_OFFSET.
*/
-static inline void __dma_sync_page(unsigned long paddr, unsigned long offset,
- size_t size, enum dma_data_direction direction)
-{
- switch (direction) {
- case DMA_TO_DEVICE:
- case DMA_BIDIRECTIONAL:
- flush_dcache_range(paddr + offset, paddr + offset + size);
- break;
- case DMA_FROM_DEVICE:
- invalidate_dcache_range(paddr + offset, paddr + offset + size);
- break;
- default:
- BUG();
- }
-}
static unsigned long get_dma_direct_offset(struct device *dev)
{
@@ -92,7 +76,7 @@ static int dma_direct_map_sg(struct device *dev, struct scatterlist *sgl,
/* FIXME this part of code is untested */
for_each_sg(sgl, sg, nents, i) {
sg->dma_address = sg_phys(sg) + get_dma_direct_offset(dev);
- __dma_sync_page(page_to_phys(sg_page(sg)), sg->offset,
+ __dma_sync(page_to_phys(sg_page(sg)) + sg->offset,
sg->length, direction);
}
@@ -117,7 +101,7 @@ static inline dma_addr_t dma_direct_map_page(struct device *dev,
enum dma_data_direction direction,
struct dma_attrs *attrs)
{
- __dma_sync_page(page_to_phys(page), offset, size, direction);
+ __dma_sync(page_to_phys(page) + offset, size, direction);
return page_to_phys(page) + offset + get_dma_direct_offset(dev);
}
@@ -132,7 +116,63 @@ static inline void dma_direct_unmap_page(struct device *dev,
* phys_to_virt is here because in __dma_sync_page is __virt_to_phys and
* dma_address is physical address
*/
- __dma_sync_page(dma_address, 0 , size, direction);
+ __dma_sync(dma_address, size, direction);
+}
+
+static inline void
+dma_direct_sync_single_for_cpu(struct device *dev,
+ dma_addr_t dma_handle, size_t size,
+ enum dma_data_direction direction)
+{
+ /*
+ * It's pointless to flush the cache as the memory segment
+ * is given to the CPU
+ */
+
+ if (direction == DMA_FROM_DEVICE)
+ __dma_sync(dma_handle, size, direction);
+}
+
+static inline void
+dma_direct_sync_single_for_device(struct device *dev,
+ dma_addr_t dma_handle, size_t size,
+ enum dma_data_direction direction)
+{
+ /*
+ * It's pointless to invalidate the cache if the device isn't
+ * supposed to write to the relevant region
+ */
+
+ if (direction == DMA_TO_DEVICE)
+ __dma_sync(dma_handle, size, direction);
+}
+
+static inline void
+dma_direct_sync_sg_for_cpu(struct device *dev,
+ struct scatterlist *sgl, int nents,
+ enum dma_data_direction direction)
+{
+ struct scatterlist *sg;
+ int i;
+
+ /* FIXME this part of code is untested */
+ if (direction == DMA_FROM_DEVICE)
+ for_each_sg(sgl, sg, nents, i)
+ __dma_sync(sg->dma_address, sg->length, direction);
+}
+
+static inline void
+dma_direct_sync_sg_for_device(struct device *dev,
+ struct scatterlist *sgl, int nents,
+ enum dma_data_direction direction)
+{
+ struct scatterlist *sg;
+ int i;
+
+ /* FIXME this part of code is untested */
+ if (direction == DMA_TO_DEVICE)
+ for_each_sg(sgl, sg, nents, i)
+ __dma_sync(sg->dma_address, sg->length, direction);
}
struct dma_map_ops dma_direct_ops = {
@@ -143,6 +183,10 @@ struct dma_map_ops dma_direct_ops = {
.dma_supported = dma_direct_dma_supported,
.map_page = dma_direct_map_page,
.unmap_page = dma_direct_unmap_page,
+ .sync_single_for_cpu = dma_direct_sync_single_for_cpu,
+ .sync_single_for_device = dma_direct_sync_single_for_device,
+ .sync_sg_for_cpu = dma_direct_sync_sg_for_cpu,
+ .sync_sg_for_device = dma_direct_sync_sg_for_device,
};
EXPORT_SYMBOL(dma_direct_ops);
diff --git a/arch/microblaze/kernel/exceptions.c b/arch/microblaze/kernel/exceptions.c
index 66fad2301221..6348dc82f428 100644
--- a/arch/microblaze/kernel/exceptions.c
+++ b/arch/microblaze/kernel/exceptions.c
@@ -119,7 +119,7 @@ asmlinkage void full_exception(struct pt_regs *regs, unsigned int type,
case MICROBLAZE_DIV_ZERO_EXCEPTION:
if (user_mode(regs)) {
pr_debug("Divide by zero exception in user mode\n");
- _exception(SIGILL, regs, FPE_INTDIV, addr);
+ _exception(SIGFPE, regs, FPE_INTDIV, addr);
return;
}
printk(KERN_WARNING "Divide by zero exception " \
diff --git a/arch/microblaze/kernel/process.c b/arch/microblaze/kernel/process.c
index dbb812421d8a..95cc295976a7 100644
--- a/arch/microblaze/kernel/process.c
+++ b/arch/microblaze/kernel/process.c
@@ -179,6 +179,7 @@ int copy_thread(unsigned long clone_flags, unsigned long usp,
ti->cpu_context.msr = (childregs->msr|MSR_VM);
ti->cpu_context.msr &= ~MSR_UMS; /* switch_to to kernel mode */
+ ti->cpu_context.msr &= ~MSR_IE;
#endif
ti->cpu_context.r15 = (unsigned long)ret_from_fork - 8;
diff --git a/arch/microblaze/kernel/ptrace.c b/arch/microblaze/kernel/ptrace.c
index 6a8e0cc5c57d..043cb58f9c44 100644
--- a/arch/microblaze/kernel/ptrace.c
+++ b/arch/microblaze/kernel/ptrace.c
@@ -148,7 +148,7 @@ asmlinkage long do_syscall_trace_enter(struct pt_regs *regs)
ret = -1L;
if (unlikely(current->audit_context))
- audit_syscall_entry(EM_XILINX_MICROBLAZE, regs->r12,
+ audit_syscall_entry(EM_MICROBLAZE, regs->r12,
regs->r5, regs->r6,
regs->r7, regs->r8);
diff --git a/arch/microblaze/kernel/timer.c b/arch/microblaze/kernel/timer.c
index e5550ce4e0eb..af74b1113aab 100644
--- a/arch/microblaze/kernel/timer.c
+++ b/arch/microblaze/kernel/timer.c
@@ -308,7 +308,8 @@ unsigned long long notrace sched_clock(void)
{
if (timer_initialized) {
struct clocksource *cs = &clocksource_microblaze;
- cycle_t cyc = cnt32_to_63(cs->read(NULL));
+
+ cycle_t cyc = cnt32_to_63(cs->read(NULL)) & LLONG_MAX;
return clocksource_cyc2ns(cyc, cs->mult, cs->shift);
}
return 0;