aboutsummaryrefslogtreecommitdiff
path: root/arch/microblaze/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'arch/microblaze/kernel')
-rw-r--r--arch/microblaze/kernel/.gitignore1
-rw-r--r--arch/microblaze/kernel/Makefile4
-rw-r--r--arch/microblaze/kernel/cpu/cache.c150
-rw-r--r--arch/microblaze/kernel/cpu/cpuinfo-pvr-full.c24
-rw-r--r--arch/microblaze/kernel/cpu/cpuinfo-static.c2
-rw-r--r--arch/microblaze/kernel/cpu/cpuinfo.c44
-rw-r--r--arch/microblaze/kernel/cpu/pvr.c2
-rw-r--r--arch/microblaze/kernel/dma.c36
-rw-r--r--arch/microblaze/kernel/early_printk.c43
-rw-r--r--arch/microblaze/kernel/entry-nommu.S21
-rw-r--r--arch/microblaze/kernel/entry.S62
-rw-r--r--arch/microblaze/kernel/exceptions.c27
-rw-r--r--arch/microblaze/kernel/ftrace.c49
-rw-r--r--arch/microblaze/kernel/head.S28
-rw-r--r--arch/microblaze/kernel/heartbeat.c6
-rw-r--r--arch/microblaze/kernel/hw_exception_handler.S53
-rw-r--r--arch/microblaze/kernel/intc.c126
-rw-r--r--arch/microblaze/kernel/irq.c10
-rw-r--r--arch/microblaze/kernel/microblaze_ksyms.c2
-rw-r--r--arch/microblaze/kernel/module.c5
-rw-r--r--arch/microblaze/kernel/platform.c30
-rw-r--r--arch/microblaze/kernel/process.c103
-rw-r--r--arch/microblaze/kernel/prom.c79
-rw-r--r--arch/microblaze/kernel/prom_parse.c2
-rw-r--r--arch/microblaze/kernel/ptrace.c25
-rw-r--r--arch/microblaze/kernel/reset.c6
-rw-r--r--arch/microblaze/kernel/selfmod.c81
-rw-r--r--arch/microblaze/kernel/setup.c83
-rw-r--r--arch/microblaze/kernel/signal.c34
-rw-r--r--arch/microblaze/kernel/stacktrace.c2
-rw-r--r--arch/microblaze/kernel/sys_microblaze.c20
-rw-r--r--arch/microblaze/kernel/syscall_table.S10
-rw-r--r--arch/microblaze/kernel/timer.c276
-rw-r--r--arch/microblaze/kernel/traps.c14
-rw-r--r--arch/microblaze/kernel/unwind.c2
-rw-r--r--arch/microblaze/kernel/vmlinux.lds.S1
36 files changed, 632 insertions, 831 deletions
diff --git a/arch/microblaze/kernel/.gitignore b/arch/microblaze/kernel/.gitignore
new file mode 100644
index 00000000000..c5f676c3c22
--- /dev/null
+++ b/arch/microblaze/kernel/.gitignore
@@ -0,0 +1 @@
+vmlinux.lds
diff --git a/arch/microblaze/kernel/Makefile b/arch/microblaze/kernel/Makefile
index 928c950fc14..08d50cc55e7 100644
--- a/arch/microblaze/kernel/Makefile
+++ b/arch/microblaze/kernel/Makefile
@@ -7,7 +7,6 @@ ifdef CONFIG_FUNCTION_TRACER
CFLAGS_REMOVE_timer.o = -pg
CFLAGS_REMOVE_intc.o = -pg
CFLAGS_REMOVE_early_printk.o = -pg
-CFLAGS_REMOVE_selfmod.o = -pg
CFLAGS_REMOVE_heartbeat.o = -pg
CFLAGS_REMOVE_ftrace.o = -pg
CFLAGS_REMOVE_process.o = -pg
@@ -17,13 +16,12 @@ extra-y := head.o vmlinux.lds
obj-y += dma.o exceptions.o \
hw_exception_handler.o intc.o irq.o \
- process.o prom.o prom_parse.o ptrace.o \
+ platform.o process.o prom.o prom_parse.o ptrace.o \
reset.o setup.o signal.o sys_microblaze.o timer.o traps.o unwind.o
obj-y += cpu/
obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
-obj-$(CONFIG_SELFMOD) += selfmod.o
obj-$(CONFIG_HEART_BEAT) += heartbeat.o
obj-$(CONFIG_MODULES) += microblaze_ksyms.o module.o
obj-$(CONFIG_MMU) += misc.o
diff --git a/arch/microblaze/kernel/cpu/cache.c b/arch/microblaze/kernel/cpu/cache.c
index 4b7d8a3f4ae..a6e44410672 100644
--- a/arch/microblaze/kernel/cpu/cache.c
+++ b/arch/microblaze/kernel/cpu/cache.c
@@ -17,82 +17,70 @@
static inline void __enable_icache_msr(void)
{
- __asm__ __volatile__ (" msrset r0, %0; \
- nop; " \
+ __asm__ __volatile__ (" msrset r0, %0;" \
+ "nop;" \
: : "i" (MSR_ICE) : "memory");
}
static inline void __disable_icache_msr(void)
{
- __asm__ __volatile__ (" msrclr r0, %0; \
- nop; " \
+ __asm__ __volatile__ (" msrclr r0, %0;" \
+ "nop;" \
: : "i" (MSR_ICE) : "memory");
}
static inline void __enable_dcache_msr(void)
{
- __asm__ __volatile__ (" msrset r0, %0; \
- nop; " \
- : \
- : "i" (MSR_DCE) \
- : "memory");
+ __asm__ __volatile__ (" msrset r0, %0;" \
+ "nop;" \
+ : : "i" (MSR_DCE) : "memory");
}
static inline void __disable_dcache_msr(void)
{
- __asm__ __volatile__ (" msrclr r0, %0; \
- nop; " \
- : \
- : "i" (MSR_DCE) \
- : "memory");
+ __asm__ __volatile__ (" msrclr r0, %0;" \
+ "nop; " \
+ : : "i" (MSR_DCE) : "memory");
}
static inline void __enable_icache_nomsr(void)
{
- __asm__ __volatile__ (" mfs r12, rmsr; \
- nop; \
- ori r12, r12, %0; \
- mts rmsr, r12; \
- nop; " \
- : \
- : "i" (MSR_ICE) \
- : "memory", "r12");
+ __asm__ __volatile__ (" mfs r12, rmsr;" \
+ "nop;" \
+ "ori r12, r12, %0;" \
+ "mts rmsr, r12;" \
+ "nop;" \
+ : : "i" (MSR_ICE) : "memory", "r12");
}
static inline void __disable_icache_nomsr(void)
{
- __asm__ __volatile__ (" mfs r12, rmsr; \
- nop; \
- andi r12, r12, ~%0; \
- mts rmsr, r12; \
- nop; " \
- : \
- : "i" (MSR_ICE) \
- : "memory", "r12");
+ __asm__ __volatile__ (" mfs r12, rmsr;" \
+ "nop;" \
+ "andi r12, r12, ~%0;" \
+ "mts rmsr, r12;" \
+ "nop;" \
+ : : "i" (MSR_ICE) : "memory", "r12");
}
static inline void __enable_dcache_nomsr(void)
{
- __asm__ __volatile__ (" mfs r12, rmsr; \
- nop; \
- ori r12, r12, %0; \
- mts rmsr, r12; \
- nop; " \
- : \
- : "i" (MSR_DCE) \
- : "memory", "r12");
+ __asm__ __volatile__ (" mfs r12, rmsr;" \
+ "nop;" \
+ "ori r12, r12, %0;" \
+ "mts rmsr, r12;" \
+ "nop;" \
+ : : "i" (MSR_DCE) : "memory", "r12");
}
static inline void __disable_dcache_nomsr(void)
{
- __asm__ __volatile__ (" mfs r12, rmsr; \
- nop; \
- andi r12, r12, ~%0; \
- mts rmsr, r12; \
- nop; " \
- : \
- : "i" (MSR_DCE) \
- : "memory", "r12");
+ __asm__ __volatile__ (" mfs r12, rmsr;" \
+ "nop;" \
+ "andi r12, r12, ~%0;" \
+ "mts rmsr, r12;" \
+ "nop;" \
+ : : "i" (MSR_DCE) : "memory", "r12");
}
@@ -106,7 +94,7 @@ do { \
int align = ~(cache_line_length - 1); \
end = min(start + cache_size, end); \
start &= align; \
-} while (0);
+} while (0)
/*
* Helper macro to loop over the specified cache_size/line_length and
@@ -118,12 +106,12 @@ do { \
int step = -line_length; \
WARN_ON(step >= 0); \
\
- __asm__ __volatile__ (" 1: " #op " %0, r0; \
- bgtid %0, 1b; \
- addk %0, %0, %1; \
- " : : "r" (len), "r" (step) \
+ __asm__ __volatile__ (" 1: " #op " %0, r0;" \
+ "bgtid %0, 1b;" \
+ "addk %0, %0, %1;" \
+ : : "r" (len), "r" (step) \
: "memory"); \
-} while (0);
+} while (0)
/* Used for wdc.flush/clear which can use rB for offset which is not possible
* to use for simple wdc or wic.
@@ -142,28 +130,28 @@ do { \
count = end - start; \
WARN_ON(count < 0); \
\
- __asm__ __volatile__ (" 1: " #op " %0, %1; \
- bgtid %1, 1b; \
- addk %1, %1, %2; \
- " : : "r" (start), "r" (count), \
+ __asm__ __volatile__ (" 1: " #op " %0, %1;" \
+ "bgtid %1, 1b;" \
+ "addk %1, %1, %2;" \
+ : : "r" (start), "r" (count), \
"r" (step) : "memory"); \
-} while (0);
+} while (0)
/* It is used only first parameter for OP - for wic, wdc */
#define CACHE_RANGE_LOOP_1(start, end, line_length, op) \
do { \
- int volatile temp; \
+ int volatile temp = 0; \
int align = ~(line_length - 1); \
end = ((end & align) == end) ? end - line_length : end & align; \
WARN_ON(end - start < 0); \
\
- __asm__ __volatile__ (" 1: " #op " %1, r0; \
- cmpu %0, %1, %2; \
- bgtid %0, 1b; \
- addk %1, %1, %3; \
- " : : "r" (temp), "r" (start), "r" (end),\
+ __asm__ __volatile__ (" 1: " #op " %1, r0;" \
+ "cmpu %0, %1, %2;" \
+ "bgtid %0, 1b;" \
+ "addk %1, %1, %3;" \
+ : : "r" (temp), "r" (start), "r" (end), \
"r" (line_length) : "memory"); \
-} while (0);
+} while (0)
#define ASM_LOOP
@@ -352,7 +340,7 @@ static void __invalidate_dcache_all_noirq_wt(void)
#endif
pr_debug("%s\n", __func__);
#ifdef ASM_LOOP
- CACHE_ALL_LOOP(cpuinfo.dcache_size, cpuinfo.dcache_line_length, wdc)
+ CACHE_ALL_LOOP(cpuinfo.dcache_size, cpuinfo.dcache_line_length, wdc);
#else
for (i = 0; i < cpuinfo.dcache_size;
i += cpuinfo.dcache_line_length)
@@ -361,7 +349,8 @@ static void __invalidate_dcache_all_noirq_wt(void)
#endif
}
-/* FIXME It is blindly invalidation as is expected
+/*
+ * FIXME It is blindly invalidation as is expected
* but can't be called on noMMU in microblaze_cache_init below
*
* MS: noMMU kernel won't boot if simple wdc is used
@@ -375,7 +364,7 @@ static void __invalidate_dcache_all_wb(void)
pr_debug("%s\n", __func__);
#ifdef ASM_LOOP
CACHE_ALL_LOOP(cpuinfo.dcache_size, cpuinfo.dcache_line_length,
- wdc)
+ wdc);
#else
for (i = 0; i < cpuinfo.dcache_size;
i += cpuinfo.dcache_line_length)
@@ -616,49 +605,48 @@ static const struct scache wt_nomsr_noirq = {
#define CPUVER_7_20_A 0x0c
#define CPUVER_7_20_D 0x0f
-#define INFO(s) printk(KERN_INFO "cache: " s "\n");
-
void microblaze_cache_init(void)
{
if (cpuinfo.use_instr & PVR2_USE_MSR_INSTR) {
if (cpuinfo.dcache_wb) {
- INFO("wb_msr");
+ pr_info("wb_msr\n");
mbc = (struct scache *)&wb_msr;
if (cpuinfo.ver_code <= CPUVER_7_20_D) {
/* MS: problem with signal handling - hw bug */
- INFO("WB won't work properly");
+ pr_info("WB won't work properly\n");
}
} else {
if (cpuinfo.ver_code >= CPUVER_7_20_A) {
- INFO("wt_msr_noirq");
+ pr_info("wt_msr_noirq\n");
mbc = (struct scache *)&wt_msr_noirq;
} else {
- INFO("wt_msr");
+ pr_info("wt_msr\n");
mbc = (struct scache *)&wt_msr;
}
}
} else {
if (cpuinfo.dcache_wb) {
- INFO("wb_nomsr");
+ pr_info("wb_nomsr\n");
mbc = (struct scache *)&wb_nomsr;
if (cpuinfo.ver_code <= CPUVER_7_20_D) {
/* MS: problem with signal handling - hw bug */
- INFO("WB won't work properly");
+ pr_info("WB won't work properly\n");
}
} else {
if (cpuinfo.ver_code >= CPUVER_7_20_A) {
- INFO("wt_nomsr_noirq");
+ pr_info("wt_nomsr_noirq\n");
mbc = (struct scache *)&wt_nomsr_noirq;
} else {
- INFO("wt_nomsr");
+ pr_info("wt_nomsr\n");
mbc = (struct scache *)&wt_nomsr;
}
}
}
-/* FIXME Invalidation is done in U-BOOT
- * WT cache: Data is already written to main memory
- * WB cache: Discard data on noMMU which caused that kernel doesn't boot
- */
+ /*
+ * FIXME Invalidation is done in U-BOOT
+ * WT cache: Data is already written to main memory
+ * WB cache: Discard data on noMMU which caused that kernel doesn't boot
+ */
/* invalidate_dcache(); */
enable_dcache();
diff --git a/arch/microblaze/kernel/cpu/cpuinfo-pvr-full.c b/arch/microblaze/kernel/cpu/cpuinfo-pvr-full.c
index 916aaedf194..93c26cf50de 100644
--- a/arch/microblaze/kernel/cpu/cpuinfo-pvr-full.c
+++ b/arch/microblaze/kernel/cpu/cpuinfo-pvr-full.c
@@ -27,7 +27,7 @@
early_printk("ERROR: Microblaze " x "-different for PVR and DTS\n");
#else
#define err_printk(x) \
- printk(KERN_INFO "ERROR: Microblaze " x "-different for PVR and DTS\n");
+ pr_info("ERROR: Microblaze " x "-different for PVR and DTS\n");
#endif
void set_cpuinfo_pvr_full(struct cpuinfo *ci, struct device_node *cpu)
@@ -38,12 +38,11 @@ void set_cpuinfo_pvr_full(struct cpuinfo *ci, struct device_node *cpu)
CI(ver_code, VERSION);
if (!ci->ver_code) {
- printk(KERN_ERR "ERROR: MB has broken PVR regs "
- "-> use DTS setting\n");
+ pr_err("ERROR: MB has broken PVR regs -> use DTS setting\n");
return;
}
- temp = PVR_USE_BARREL(pvr) | PVR_USE_MSR_INSTR(pvr) |\
+ temp = PVR_USE_BARREL(pvr) | PVR_USE_MSR_INSTR(pvr) |
PVR_USE_PCMP_INSTR(pvr) | PVR_USE_DIV(pvr);
if (ci->use_instr != temp)
err_printk("BARREL, MSR, PCMP or DIV");
@@ -59,13 +58,13 @@ void set_cpuinfo_pvr_full(struct cpuinfo *ci, struct device_node *cpu)
err_printk("HW_FPU");
ci->use_fpu = temp;
- ci->use_exc = PVR_OPCODE_0x0_ILLEGAL(pvr) |\
- PVR_UNALIGNED_EXCEPTION(pvr) |\
- PVR_ILL_OPCODE_EXCEPTION(pvr) |\
- PVR_IOPB_BUS_EXCEPTION(pvr) |\
- PVR_DOPB_BUS_EXCEPTION(pvr) |\
- PVR_DIV_ZERO_EXCEPTION(pvr) |\
- PVR_FPU_EXCEPTION(pvr) |\
+ ci->use_exc = PVR_OPCODE_0x0_ILLEGAL(pvr) |
+ PVR_UNALIGNED_EXCEPTION(pvr) |
+ PVR_ILL_OPCODE_EXCEPTION(pvr) |
+ PVR_IOPB_BUS_EXCEPTION(pvr) |
+ PVR_DOPB_BUS_EXCEPTION(pvr) |
+ PVR_DIV_ZERO_EXCEPTION(pvr) |
+ PVR_FPU_EXCEPTION(pvr) |
PVR_FSL_EXCEPTION(pvr);
CI(pvr_user1, USER1);
@@ -113,7 +112,4 @@ void set_cpuinfo_pvr_full(struct cpuinfo *ci, struct device_node *cpu)
CI(num_wr_brk, NUMBER_OF_WR_ADDR_BRK);
CI(fpga_family_code, TARGET_FAMILY);
-
- /* take timebase-frequency from DTS */
- ci->cpu_clock_freq = fcpu(cpu, "timebase-frequency");
}
diff --git a/arch/microblaze/kernel/cpu/cpuinfo-static.c b/arch/microblaze/kernel/cpu/cpuinfo-static.c
index 592bb2e838c..4854285b26e 100644
--- a/arch/microblaze/kernel/cpu/cpuinfo-static.c
+++ b/arch/microblaze/kernel/cpu/cpuinfo-static.c
@@ -113,8 +113,6 @@ void __init set_cpuinfo_static(struct cpuinfo *ci, struct device_node *cpu)
ci->num_rd_brk = fcpu(cpu, "xlnx,number-of-rd-addr-brk");
ci->num_wr_brk = fcpu(cpu, "xlnx,number-of-wr-addr-brk");
- ci->cpu_clock_freq = fcpu(cpu, "timebase-frequency");
-
ci->pvr_user1 = fcpu(cpu, "xlnx,pvr-user1");
ci->pvr_user2 = fcpu(cpu, "xlnx,pvr-user2");
diff --git a/arch/microblaze/kernel/cpu/cpuinfo.c b/arch/microblaze/kernel/cpu/cpuinfo.c
index eab6abf5652..234acad79b9 100644
--- a/arch/microblaze/kernel/cpu/cpuinfo.c
+++ b/arch/microblaze/kernel/cpu/cpuinfo.c
@@ -8,6 +8,7 @@
* for more details.
*/
+#include <linux/clk.h>
#include <linux/init.h>
#include <asm/cpuinfo.h>
#include <asm/pvr.h>
@@ -37,6 +38,11 @@ const struct cpu_ver_key cpu_ver_lookup[] = {
{"8.20.a", 0x15},
{"8.20.b", 0x16},
{"8.30.a", 0x17},
+ {"8.40.a", 0x18},
+ {"8.40.b", 0x19},
+ {"8.50.a", 0x1a},
+ {"9.0", 0x1b},
+ {"9.1", 0x1d},
{NULL, 0},
};
@@ -57,42 +63,62 @@ const struct family_string_key family_string_lookup[] = {
{"virtex6", 0xe},
/* FIXME There is no key code defined for spartan2 */
{"spartan2", 0xf0},
+ {"kintex7", 0x10},
+ {"artix7", 0x11},
+ {"zynq7000", 0x12},
{NULL, 0},
};
struct cpuinfo cpuinfo;
+static struct device_node *cpu;
void __init setup_cpuinfo(void)
{
- struct device_node *cpu = NULL;
-
cpu = (struct device_node *) of_find_node_by_type(NULL, "cpu");
if (!cpu)
- printk(KERN_ERR "You don't have cpu!!!\n");
+ pr_err("You don't have cpu!!!\n");
- printk(KERN_INFO "%s: initialising\n", __func__);
+ pr_info("%s: initialising\n", __func__);
switch (cpu_has_pvr()) {
case 0:
- printk(KERN_WARNING
- "%s: No PVR support. Using static CPU info from FDT\n",
+ pr_warn("%s: No PVR support. Using static CPU info from FDT\n",
__func__);
set_cpuinfo_static(&cpuinfo, cpu);
break;
/* FIXME I found weird behavior with MB 7.00.a/b 7.10.a
* please do not use FULL PVR with MMU */
case 1:
- printk(KERN_INFO "%s: Using full CPU PVR support\n",
+ pr_info("%s: Using full CPU PVR support\n",
__func__);
set_cpuinfo_static(&cpuinfo, cpu);
set_cpuinfo_pvr_full(&cpuinfo, cpu);
break;
default:
- printk(KERN_WARNING "%s: Unsupported PVR setting\n", __func__);
+ pr_warn("%s: Unsupported PVR setting\n", __func__);
set_cpuinfo_static(&cpuinfo, cpu);
}
if (cpuinfo.mmu_privins)
- printk(KERN_WARNING "%s: Stream instructions enabled"
+ pr_warn("%s: Stream instructions enabled"
" - USERSPACE CAN LOCK THIS KERNEL!\n", __func__);
}
+
+void __init setup_cpuinfo_clk(void)
+{
+ struct clk *clk;
+
+ clk = of_clk_get(cpu, 0);
+ if (IS_ERR(clk)) {
+ pr_err("ERROR: CPU CCF input clock not found\n");
+ /* take timebase-frequency from DTS */
+ cpuinfo.cpu_clock_freq = fcpu(cpu, "timebase-frequency");
+ } else {
+ cpuinfo.cpu_clock_freq = clk_get_rate(clk);
+ }
+
+ if (!cpuinfo.cpu_clock_freq) {
+ pr_err("ERROR: CPU clock frequency not setup\n");
+ BUG();
+ }
+}
diff --git a/arch/microblaze/kernel/cpu/pvr.c b/arch/microblaze/kernel/cpu/pvr.c
index 3a749d5e71f..8d0dc6db48c 100644
--- a/arch/microblaze/kernel/cpu/pvr.c
+++ b/arch/microblaze/kernel/cpu/pvr.c
@@ -27,7 +27,7 @@
tmp = 0x0; /* Prevent warning about unused */ \
__asm__ __volatile__ ( \
"mfs %0, rpvr" #pvrid ";" \
- : "=r" (tmp) : : "memory"); \
+ : "=r" (tmp) : : "memory"); \
val = tmp; \
}
diff --git a/arch/microblaze/kernel/dma.c b/arch/microblaze/kernel/dma.c
index a2bfa2ca573..4633c36c1b3 100644
--- a/arch/microblaze/kernel/dma.c
+++ b/arch/microblaze/kernel/dma.c
@@ -11,24 +11,7 @@
#include <linux/gfp.h>
#include <linux/dma-debug.h>
#include <linux/export.h>
-#include <asm/bug.h>
-
-/*
- * Generic direct DMA implementation
- *
- * This implementation supports a per-device offset that can be applied if
- * the address at which memory is visible to devices is not 0. Platform code
- * can set archdata.dma_data to an unsigned long holding the offset. By
- * default the offset is PCI_DRAM_OFFSET.
- */
-
-static unsigned long get_dma_direct_offset(struct device *dev)
-{
- if (likely(dev))
- return (unsigned long)dev->archdata.dma_data;
-
- return PCI_DRAM_OFFSET; /* FIXME Not sure if is correct */
-}
+#include <linux/bug.h>
#define NOT_COHERENT_CACHE
@@ -51,7 +34,7 @@ static void *dma_direct_alloc_coherent(struct device *dev, size_t size,
return NULL;
ret = page_address(page);
memset(ret, 0, size);
- *dma_handle = virt_to_phys(ret) + get_dma_direct_offset(dev);
+ *dma_handle = virt_to_phys(ret);
return ret;
#endif
@@ -77,7 +60,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);
+ sg->dma_address = sg_phys(sg);
__dma_sync(page_to_phys(sg_page(sg)) + sg->offset,
sg->length, direction);
}
@@ -85,12 +68,6 @@ static int dma_direct_map_sg(struct device *dev, struct scatterlist *sgl,
return nents;
}
-static void dma_direct_unmap_sg(struct device *dev, struct scatterlist *sg,
- int nents, enum dma_data_direction direction,
- struct dma_attrs *attrs)
-{
-}
-
static int dma_direct_dma_supported(struct device *dev, u64 mask)
{
return 1;
@@ -104,7 +81,7 @@ static inline dma_addr_t dma_direct_map_page(struct device *dev,
struct dma_attrs *attrs)
{
__dma_sync(page_to_phys(page) + offset, size, direction);
- return page_to_phys(page) + offset + get_dma_direct_offset(dev);
+ return page_to_phys(page) + offset;
}
static inline void dma_direct_unmap_page(struct device *dev,
@@ -181,7 +158,6 @@ struct dma_map_ops dma_direct_ops = {
.alloc = dma_direct_alloc_coherent,
.free = dma_direct_free_coherent,
.map_sg = dma_direct_map_sg,
- .unmap_sg = dma_direct_unmap_sg,
.dma_supported = dma_direct_dma_supported,
.map_page = dma_direct_map_page,
.unmap_page = dma_direct_unmap_page,
@@ -197,8 +173,8 @@ EXPORT_SYMBOL(dma_direct_ops);
static int __init dma_init(void)
{
- dma_debug_init(PREALLOC_DMA_DEBUG_ENTRIES);
+ dma_debug_init(PREALLOC_DMA_DEBUG_ENTRIES);
- return 0;
+ return 0;
}
fs_initcall(dma_init);
diff --git a/arch/microblaze/kernel/early_printk.c b/arch/microblaze/kernel/early_printk.c
index aba1f9a97d5..365f2d53f1b 100644
--- a/arch/microblaze/kernel/early_printk.c
+++ b/arch/microblaze/kernel/early_printk.c
@@ -21,7 +21,6 @@
#include <asm/setup.h>
#include <asm/prom.h>
-static u32 early_console_initialized;
static u32 base_addr;
#ifdef CONFIG_SERIAL_UARTLITE_CONSOLE
@@ -109,27 +108,11 @@ static struct console early_serial_uart16550_console = {
};
#endif /* CONFIG_SERIAL_8250_CONSOLE */
-static struct console *early_console;
-
-void early_printk(const char *fmt, ...)
-{
- char buf[512];
- int n;
- va_list ap;
-
- if (early_console_initialized) {
- va_start(ap, fmt);
- n = vscnprintf(buf, 512, fmt, ap);
- early_console->write(early_console, buf, n);
- va_end(ap);
- }
-}
-
int __init setup_early_printk(char *opt)
{
int version = 0;
- if (early_console_initialized)
+ if (early_console)
return 1;
base_addr = of_early_console(&version);
@@ -140,26 +123,25 @@ int __init setup_early_printk(char *opt)
switch (version) {
#ifdef CONFIG_SERIAL_UARTLITE_CONSOLE
case UARTLITE:
- printk(KERN_INFO "Early console on uartlite "
- "at 0x%08x\n", base_addr);
+ pr_info("Early console on uartlite at 0x%08x\n",
+ base_addr);
early_console = &early_serial_uartlite_console;
break;
#endif
#ifdef CONFIG_SERIAL_8250_CONSOLE
case UART16550:
- printk(KERN_INFO "Early console on uart16650 "
- "at 0x%08x\n", base_addr);
+ pr_info("Early console on uart16650 at 0x%08x\n",
+ base_addr);
early_console = &early_serial_uart16550_console;
break;
#endif
default:
- printk(KERN_INFO "Unsupported early console %d\n",
+ pr_info("Unsupported early console %d\n",
version);
return 1;
}
register_console(early_console);
- early_console_initialized = 1;
return 0;
}
return 1;
@@ -169,12 +151,11 @@ int __init setup_early_printk(char *opt)
* only for early console because of performance degression */
void __init remap_early_printk(void)
{
- if (!early_console_initialized || !early_console)
+ if (!early_console)
return;
- printk(KERN_INFO "early_printk_console remapping from 0x%x to ",
- base_addr);
+ pr_info("early_printk_console remapping from 0x%x to ", base_addr);
base_addr = (u32) ioremap(base_addr, PAGE_SIZE);
- printk(KERN_CONT "0x%x\n", base_addr);
+ pr_cont("0x%x\n", base_addr);
#ifdef CONFIG_MMU
/*
@@ -195,9 +176,9 @@ void __init remap_early_printk(void)
void __init disable_early_printk(void)
{
- if (!early_console_initialized || !early_console)
+ if (!early_console)
return;
- printk(KERN_WARNING "disabling early console\n");
+ pr_warn("disabling early console\n");
unregister_console(early_console);
- early_console_initialized = 0;
+ early_console = NULL;
}
diff --git a/arch/microblaze/kernel/entry-nommu.S b/arch/microblaze/kernel/entry-nommu.S
index 70da83a4967..7e394fc2c43 100644
--- a/arch/microblaze/kernel/entry-nommu.S
+++ b/arch/microblaze/kernel/entry-nommu.S
@@ -124,6 +124,7 @@ ret_from_intr:
lwi r11, r1, PT_MODE
bneid r11, no_intr_resched
+3:
lwi r6, r31, TS_THREAD_INFO /* get thread info */
lwi r19, r6, TI_FLAGS /* get flags in thread info */
/* do an extra work if any bits are set */
@@ -132,11 +133,13 @@ ret_from_intr:
beqi r11, 1f
bralid r15, schedule
nop
+ bri 3b
1: andi r11, r19, _TIF_SIGPENDING | _TIF_NOTIFY_RESUME
beqid r11, no_intr_resched
addk r5, r1, r0
bralid r15, do_notify_resume
addk r6, r0, r0
+ bri 3b
no_intr_resched:
/* Disable interrupts, we are now committed to the state restore */
@@ -280,6 +283,7 @@ ENTRY(_user_exception)
/* Figure out which function to use for this system call. */
/* Note Microblaze barrel shift is optional, so don't rely on it */
add r12, r12, r12 /* convert num -> ptr */
+ addik r30, r0, 1 /* restarts allowed */
add r12, r12, r12
lwi r12, r12, sys_call_table /* Get function pointer */
addik r15, r0, ret_to_user-8 /* set return address */
@@ -369,6 +373,7 @@ ENTRY(_debug_exception)
bralid r15, send_sig
add r7, r0, r0 /* 3rd param zero */
+ addik r30, r0, 1 /* restarts allowed ??? */
/* Restore r3/r4 to work around how ret_to_user works */
lwi r3, r1, PT_R3
lwi r4, r1, PT_R4
@@ -482,18 +487,26 @@ ENTRY(ret_from_kernel_thread)
addk r3, r0, r0
work_pending:
+ lwi r11, r1, PT_MODE
+ bneid r11, 2f
+3:
enable_irq
-
andi r11, r19, _TIF_NEED_RESCHED
beqi r11, 1f
bralid r15, schedule
nop
+ bri 4f
1: andi r11, r19, _TIF_SIGPENDING | _TIF_NOTIFY_RESUME
beqi r11, no_work_pending
- addk r5, r1, r0
+ addk r5, r30, r0
bralid r15, do_notify_resume
addik r6, r0, 1
- bri no_work_pending
+ addk r30, r0, r0 /* no restarts from now on */
+4:
+ disable_irq
+ lwi r6, r31, TS_THREAD_INFO /* get thread info */
+ lwi r19, r6, TI_FLAGS /* get flags in thread info */
+ bri 3b
ENTRY(ret_to_user)
disable_irq
@@ -507,6 +520,7 @@ ENTRY(ret_to_user)
no_work_pending:
disable_irq
+2:
/* save r31 */
swi r31, r0, PER_CPU(CURRENT_SAVE)
/* save mode indicator */
@@ -559,6 +573,7 @@ no_work_pending:
nop
sys_rt_sigreturn_wrapper:
+ addk r30, r0, r0 /* no restarts for this one */
brid sys_rt_sigreturn
addk r5, r1, r0
diff --git a/arch/microblaze/kernel/entry.S b/arch/microblaze/kernel/entry.S
index c217367dfc7..0536bc021cc 100644
--- a/arch/microblaze/kernel/entry.S
+++ b/arch/microblaze/kernel/entry.S
@@ -354,6 +354,7 @@ C_ENTRY(_user_exception):
/* Note Microblaze barrel shift is optional, so don't rely on it */
add r12, r12, r12; /* convert num -> ptr */
add r12, r12, r12;
+ addi r30, r0, 1 /* restarts allowed */
#ifdef DEBUG
/* Trac syscalls and stored them to syscall_debug_table */
@@ -401,26 +402,27 @@ C_ENTRY(ret_from_trap):
* trigger rescheduling. */
/* get thread info from current task */
lwi r11, CURRENT_TASK, TS_THREAD_INFO;
- lwi r11, r11, TI_FLAGS; /* get flags in thread info */
- andi r11, r11, _TIF_NEED_RESCHED;
+ lwi r19, r11, TI_FLAGS; /* get flags in thread info */
+ andi r11, r19, _TIF_NEED_RESCHED;
beqi r11, 5f;
bralid r15, schedule; /* Call scheduler */
nop; /* delay slot */
+ bri 1b
/* Maybe handle a signal */
-5: /* get thread info from current task*/
- lwi r11, CURRENT_TASK, TS_THREAD_INFO;
- lwi r11, r11, TI_FLAGS; /* get flags in thread info */
- andi r11, r11, _TIF_SIGPENDING | _TIF_NOTIFY_RESUME;
- beqi r11, 1f; /* Signals to handle, handle them */
+5:
+ andi r11, r19, _TIF_SIGPENDING | _TIF_NOTIFY_RESUME;
+ beqi r11, 4f; /* Signals to handle, handle them */
addik r5, r1, 0; /* Arg 1: struct pt_regs *regs */
bralid r15, do_notify_resume; /* Handle any signals */
- addi r6, r0, 1; /* Arg 2: int in_syscall */
+ add r6, r30, r0; /* Arg 2: int in_syscall */
+ add r30, r0, r0 /* no more restarts */
+ bri 1b
/* Finally, return to user state. */
-1: set_bip; /* Ints masked for state restore */
+4: set_bip; /* Ints masked for state restore */
swi CURRENT_TASK, r0, PER_CPU(CURRENT_SAVE); /* save current */
VM_OFF;
tophys(r1,r1);
@@ -464,6 +466,7 @@ C_ENTRY(ret_from_kernel_thread):
add r3, r0, r0
C_ENTRY(sys_rt_sigreturn_wrapper):
+ addik r30, r0, 0 /* no restarts */
brid sys_rt_sigreturn /* Do real work */
addik r5, r1, 0; /* add user context as 1st arg */
@@ -571,20 +574,20 @@ C_ENTRY(ret_from_exc):
/* We're returning to user mode, so check for various conditions that
trigger rescheduling. */
+1:
lwi r11, CURRENT_TASK, TS_THREAD_INFO; /* get thread info */
- lwi r11, r11, TI_FLAGS; /* get flags in thread info */
- andi r11, r11, _TIF_NEED_RESCHED;
+ lwi r19, r11, TI_FLAGS; /* get flags in thread info */
+ andi r11, r19, _TIF_NEED_RESCHED;
beqi r11, 5f;
/* Call the scheduler before returning from a syscall/trap. */
bralid r15, schedule; /* Call scheduler */
nop; /* delay slot */
+ bri 1b
/* Maybe handle a signal */
-5: lwi r11, CURRENT_TASK, TS_THREAD_INFO; /* get thread info */
- lwi r11, r11, TI_FLAGS; /* get flags in thread info */
- andi r11, r11, _TIF_SIGPENDING | _TIF_NOTIFY_RESUME;
- beqi r11, 1f; /* Signals to handle, handle them */
+5: andi r11, r19, _TIF_SIGPENDING | _TIF_NOTIFY_RESUME;
+ beqi r11, 4f; /* Signals to handle, handle them */
/*
* Handle a signal return; Pending signals should be in r18.
@@ -600,9 +603,10 @@ C_ENTRY(ret_from_exc):
addik r5, r1, 0; /* Arg 1: struct pt_regs *regs */
bralid r15, do_notify_resume; /* Handle any signals */
addi r6, r0, 0; /* Arg 2: int in_syscall */
+ bri 1b
/* Finally, return to user state. */
-1: set_bip; /* Ints masked for state restore */
+4: set_bip; /* Ints masked for state restore */
swi CURRENT_TASK, r0, PER_CPU(CURRENT_SAVE); /* save current */
VM_OFF;
tophys(r1,r1);
@@ -682,22 +686,23 @@ ret_from_irq:
lwi r11, r1, PT_MODE;
bnei r11, 2f;
+1:
lwi r11, CURRENT_TASK, TS_THREAD_INFO;
- lwi r11, r11, TI_FLAGS; /* MS: get flags from thread info */
- andi r11, r11, _TIF_NEED_RESCHED;
+ lwi r19, r11, TI_FLAGS; /* MS: get flags from thread info */
+ andi r11, r19, _TIF_NEED_RESCHED;
beqi r11, 5f
bralid r15, schedule;
nop; /* delay slot */
+ bri 1b
/* Maybe handle a signal */
-5: lwi r11, CURRENT_TASK, TS_THREAD_INFO; /* MS: get thread info */
- lwi r11, r11, TI_FLAGS; /* get flags in thread info */
- andi r11, r11, _TIF_SIGPENDING | _TIF_NOTIFY_RESUME;
+5: andi r11, r19, _TIF_SIGPENDING | _TIF_NOTIFY_RESUME;
beqid r11, no_intr_resched
/* Handle a signal return; Pending signals should be in r18. */
addik r5, r1, 0; /* Arg 1: struct pt_regs *regs */
bralid r15, do_notify_resume; /* Handle any signals */
addi r6, r0, 0; /* Arg 2: int in_syscall */
+ bri 1b
/* Finally, return to user state. */
no_intr_resched:
@@ -815,28 +820,29 @@ dbtrap_call: /* Return point for kernel/user entry + 8 because of rtsd r15, 8 */
lwi r11, r1, PT_MODE;
bnei r11, 2f;
/* MS: Return to user space - gdb */
+1:
/* Get current task ptr into r11 */
lwi r11, CURRENT_TASK, TS_THREAD_INFO; /* get thread info */
- lwi r11, r11, TI_FLAGS; /* get flags in thread info */
- andi r11, r11, _TIF_NEED_RESCHED;
+ lwi r19, r11, TI_FLAGS; /* get flags in thread info */
+ andi r11, r19, _TIF_NEED_RESCHED;
beqi r11, 5f;
/* Call the scheduler before returning from a syscall/trap. */
bralid r15, schedule; /* Call scheduler */
nop; /* delay slot */
+ bri 1b
/* Maybe handle a signal */
-5: lwi r11, CURRENT_TASK, TS_THREAD_INFO; /* get thread info */
- lwi r11, r11, TI_FLAGS; /* get flags in thread info */
- andi r11, r11, _TIF_SIGPENDING | _TIF_NOTIFY_RESUME;
- beqi r11, 1f; /* Signals to handle, handle them */
+5: andi r11, r19, _TIF_SIGPENDING | _TIF_NOTIFY_RESUME;
+ beqi r11, 4f; /* Signals to handle, handle them */
addik r5, r1, 0; /* Arg 1: struct pt_regs *regs */
bralid r15, do_notify_resume; /* Handle any signals */
addi r6, r0, 0; /* Arg 2: int in_syscall */
+ bri 1b
/* Finally, return to user state. */
-1: swi CURRENT_TASK, r0, PER_CPU(CURRENT_SAVE); /* save current */
+4: swi CURRENT_TASK, r0, PER_CPU(CURRENT_SAVE); /* save current */
VM_OFF;
tophys(r1,r1);
/* MS: Restore all regs */
diff --git a/arch/microblaze/kernel/exceptions.c b/arch/microblaze/kernel/exceptions.c
index 6348dc82f42..42dd12a62ff 100644
--- a/arch/microblaze/kernel/exceptions.c
+++ b/arch/microblaze/kernel/exceptions.c
@@ -13,11 +13,11 @@
* This file handles the architecture-dependent parts of hardware exceptions
*/
+#include <linux/export.h>
#include <linux/kernel.h>
#include <linux/signal.h>
#include <linux/sched.h>
#include <linux/kallsyms.h>
-#include <linux/module.h>
#include <asm/exceptions.h>
#include <asm/entry.h> /* For KM CPU var */
@@ -40,7 +40,7 @@ void die(const char *str, struct pt_regs *fp, long err)
{
console_verbose();
spin_lock_irq(&die_lock);
- printk(KERN_WARNING "Oops: %s, sig: %ld\n", str, err);
+ pr_warn("Oops: %s, sig: %ld\n", str, err);
show_regs(fp);
spin_unlock_irq(&die_lock);
/* do_exit() should take care of panic'ing from an interrupt
@@ -61,9 +61,9 @@ void _exception(int signr, struct pt_regs *regs, int code, unsigned long addr)
{
siginfo_t info;
- if (kernel_mode(regs)) {
+ if (kernel_mode(regs))
die("Exception in kernel mode", regs, signr);
- }
+
info.si_signo = signr;
info.si_errno = 0;
info.si_code = code;
@@ -79,8 +79,7 @@ asmlinkage void full_exception(struct pt_regs *regs, unsigned int type,
#endif
#if 0
- printk(KERN_WARNING "Exception %02x in %s mode, FSR=%08x PC=%08x " \
- "ESR=%08x\n",
+ pr_warn("Exception %02x in %s mode, FSR=%08x PC=%08x ESR=%08x\n",
type, user_mode(regs) ? "user" : "kernel", fsr,
(unsigned int) regs->pc, (unsigned int) regs->esr);
#endif
@@ -92,8 +91,7 @@ asmlinkage void full_exception(struct pt_regs *regs, unsigned int type,
_exception(SIGILL, regs, ILL_ILLOPC, addr);
return;
}
- printk(KERN_WARNING "Illegal opcode exception " \
- "in kernel mode.\n");
+ pr_warn("Illegal opcode exception in kernel mode.\n");
die("opcode exception", regs, SIGBUS);
break;
case MICROBLAZE_IBUS_EXCEPTION:
@@ -102,8 +100,7 @@ asmlinkage void full_exception(struct pt_regs *regs, unsigned int type,
_exception(SIGBUS, regs, BUS_ADRERR, addr);
return;
}
- printk(KERN_WARNING "Instruction bus error exception " \
- "in kernel mode.\n");
+ pr_warn("Instruction bus error exception in kernel mode.\n");
die("bus exception", regs, SIGBUS);
break;
case MICROBLAZE_DBUS_EXCEPTION:
@@ -112,8 +109,7 @@ asmlinkage void full_exception(struct pt_regs *regs, unsigned int type,
_exception(SIGBUS, regs, BUS_ADRERR, addr);
return;
}
- printk(KERN_WARNING "Data bus error exception " \
- "in kernel mode.\n");
+ pr_warn("Data bus error exception in kernel mode.\n");
die("bus exception", regs, SIGBUS);
break;
case MICROBLAZE_DIV_ZERO_EXCEPTION:
@@ -122,8 +118,7 @@ asmlinkage void full_exception(struct pt_regs *regs, unsigned int type,
_exception(SIGFPE, regs, FPE_INTDIV, addr);
return;
}
- printk(KERN_WARNING "Divide by zero exception " \
- "in kernel mode.\n");
+ pr_warn("Divide by zero exception in kernel mode.\n");
die("Divide by zero exception", regs, SIGBUS);
break;
case MICROBLAZE_FPU_EXCEPTION:
@@ -151,8 +146,8 @@ asmlinkage void full_exception(struct pt_regs *regs, unsigned int type,
#endif
default:
/* FIXME what to do in unexpected exception */
- printk(KERN_WARNING "Unexpected exception %02x "
- "PC=%08x in %s mode\n", type, (unsigned int) addr,
+ pr_warn("Unexpected exception %02x PC=%08x in %s mode\n",
+ type, (unsigned int) addr,
kernel_mode(regs) ? "kernel" : "user");
}
return;
diff --git a/arch/microblaze/kernel/ftrace.c b/arch/microblaze/kernel/ftrace.c
index 357d56abe24..bbcd2533766 100644
--- a/arch/microblaze/kernel/ftrace.c
+++ b/arch/microblaze/kernel/ftrace.c
@@ -35,18 +35,18 @@ void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr)
* happen. This tool is too much intrusive to
* ignore such a protection.
*/
- asm volatile(" 1: lwi %0, %2, 0; \
- 2: swi %3, %2, 0; \
- addik %1, r0, 0; \
- 3: \
- .section .fixup, \"ax\"; \
- 4: brid 3b; \
- addik %1, r0, 1; \
- .previous; \
- .section __ex_table,\"a\"; \
- .word 1b,4b; \
- .word 2b,4b; \
- .previous;" \
+ asm volatile(" 1: lwi %0, %2, 0;" \
+ "2: swi %3, %2, 0;" \
+ " addik %1, r0, 0;" \
+ "3:" \
+ " .section .fixup, \"ax\";" \
+ "4: brid 3b;" \
+ " addik %1, r0, 1;" \
+ " .previous;" \
+ " .section __ex_table,\"a\";" \
+ " .word 1b,4b;" \
+ " .word 2b,4b;" \
+ " .previous;" \
: "=&r" (old), "=r" (faulted)
: "r" (parent), "r" (return_hooker)
);
@@ -81,16 +81,16 @@ static int ftrace_modify_code(unsigned long addr, unsigned int value)
{
int faulted = 0;
- __asm__ __volatile__(" 1: swi %2, %1, 0; \
- addik %0, r0, 0; \
- 2: \
- .section .fixup, \"ax\"; \
- 3: brid 2b; \
- addik %0, r0, 1; \
- .previous; \
- .section __ex_table,\"a\"; \
- .word 1b,3b; \
- .previous;" \
+ __asm__ __volatile__(" 1: swi %2, %1, 0;" \
+ " addik %0, r0, 0;" \
+ "2:" \
+ " .section .fixup, \"ax\";" \
+ "3: brid 2b;" \
+ " addik %0, r0, 1;" \
+ " .previous;" \
+ " .section __ex_table,\"a\";" \
+ " .word 1b,3b;" \
+ " .previous;" \
: "=r" (faulted)
: "r" (addr), "r" (value)
);
@@ -171,11 +171,8 @@ int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
return ret;
}
-int __init ftrace_dyn_arch_init(void *data)
+int __init ftrace_dyn_arch_init(void)
{
- /* The return code is retured via data */
- *(unsigned long *)data = 0;
-
return 0;
}
diff --git a/arch/microblaze/kernel/head.S b/arch/microblaze/kernel/head.S
index eef84de5e8c..4655ff342c6 100644
--- a/arch/microblaze/kernel/head.S
+++ b/arch/microblaze/kernel/head.S
@@ -64,6 +64,10 @@ real_start:
#endif
mts rmsr, r0
+/* Disable stack protection from bootloader */
+ mts rslr, r0
+ addi r8, r0, 0xFFFFFFFF
+ mts rshr, r8
/*
* According to Xilinx, msrclr instruction behaves like 'mfs rX,rpc'
* if the msrclr instruction is not enabled. We use this to detect
@@ -112,16 +116,16 @@ no_fdt_arg:
* copy command line directly to cmd_line placed in data section.
*/
beqid r5, skip /* Skip if NULL pointer */
- or r6, r0, r0 /* incremment */
+ or r11, r0, r0 /* incremment */
ori r4, r0, cmd_line /* load address of command line */
tophys(r4,r4) /* convert to phys address */
ori r3, r0, COMMAND_LINE_SIZE - 1 /* number of loops */
_copy_command_line:
/* r2=r5+r6 - r5 contain pointer to command line */
- lbu r2, r5, r6
+ lbu r2, r5, r11
beqid r2, skip /* Skip if no data */
- sb r2, r4, r6 /* addr[r4+r6]= r2*/
- addik r6, r6, 1 /* increment counting */
+ sb r2, r4, r11 /* addr[r4+r6]= r2 */
+ addik r11, r11, 1 /* increment counting */
bgtid r3, _copy_command_line /* loop for all entries */
addik r3, r3, -1 /* decrement loop */
addik r5, r4, 0 /* add new space for command line */
@@ -131,13 +135,13 @@ skip:
#ifdef NOT_COMPILE
/* save bram context */
- or r6, r0, r0 /* incremment */
+ or r11, r0, r0 /* incremment */
ori r4, r0, TOPHYS(_bram_load_start) /* save bram context */
ori r3, r0, (LMB_SIZE - 4)
_copy_bram:
- lw r7, r0, r6 /* r7 = r0 + r6 */
- sw r7, r4, r6 /* addr[r4 + r6] = r7*/
- addik r6, r6, 4 /* increment counting */
+ lw r7, r0, r11 /* r7 = r0 + r6 */
+ sw r7, r4, r11 /* addr[r4 + r6] = r7 */
+ addik r11, r11, 4 /* increment counting */
bgtid r3, _copy_bram /* loop for all entries */
addik r3, r3, -4 /* descrement loop */
#endif
@@ -176,7 +180,7 @@ _invalidate:
/* start to do TLB calculation */
addik r12, r0, _end
rsub r12, r3, r12
- addik r12, r12, CONFIG_KERNEL_PAD /* that's the pad */
+ addik r12, r12, CONFIG_LOWMEM_SIZE >> PTE_SHIFT /* that's the pad */
or r9, r0, r0 /* TLB0 = 0 */
or r10, r0, r0 /* TLB1 = 0 */
@@ -201,7 +205,7 @@ GT4: /* r11 contains the rest - will be either 1 or 4 */
GT16: /* TLB0 is 16MB */
addik r9, r0, 0x1000000 /* means TLB0 is 16MB */
TLB1:
- /* must be used r2 because of substract if failed */
+ /* must be used r2 because of subtract if failed */
addik r2, r11, -0x0400000
bgei r2, GT20 /* size is greater than 16MB */
/* size is >16MB and <20MB */
@@ -303,8 +307,8 @@ jump_over2:
* the exception vectors, using a 4k real==virtual mapping.
*/
/* Use temporary TLB_ID for LMB - clear this temporary mapping later */
- ori r6, r0, MICROBLAZE_LMB_TLB_ID
- mts rtlbx,r6
+ ori r11, r0, MICROBLAZE_LMB_TLB_ID
+ mts rtlbx,r11
ori r4,r0,(TLB_WR | TLB_EX)
ori r3,r0,(TLB_VALID | TLB_PAGESZ(PAGESZ_4K))
diff --git a/arch/microblaze/kernel/heartbeat.c b/arch/microblaze/kernel/heartbeat.c
index 154756f3c69..4643e3ab941 100644
--- a/arch/microblaze/kernel/heartbeat.c
+++ b/arch/microblaze/kernel/heartbeat.c
@@ -17,7 +17,7 @@
static unsigned int base_addr;
-void heartbeat(void)
+void microblaze_heartbeat(void)
{
static unsigned int cnt, period, dist;
@@ -42,7 +42,7 @@ void heartbeat(void)
}
}
-void setup_heartbeat(void)
+void microblaze_setup_heartbeat(void)
{
struct device_node *gpio = NULL;
int *prop;
@@ -61,7 +61,7 @@ void setup_heartbeat(void)
if (gpio) {
base_addr = be32_to_cpup(of_get_property(gpio, "reg", NULL));
base_addr = (unsigned long) ioremap(base_addr, PAGE_SIZE);
- printk(KERN_NOTICE "Heartbeat GPIO at 0x%x\n", base_addr);
+ pr_notice("Heartbeat GPIO at 0x%x\n", base_addr);
/* GPIO is configured as output */
prop = (int *) of_get_property(gpio, "xlnx,is-bidir", NULL);
diff --git a/arch/microblaze/kernel/hw_exception_handler.S b/arch/microblaze/kernel/hw_exception_handler.S
index 61b3a1fed46..0b11a4469de 100644
--- a/arch/microblaze/kernel/hw_exception_handler.S
+++ b/arch/microblaze/kernel/hw_exception_handler.S
@@ -147,15 +147,14 @@
or r3, r0, NUM_TO_REG (regnum);
/* Shift right instruction depending on available configuration */
- #if CONFIG_XILINX_MICROBLAZE0_USE_BARREL > 0
- #define BSRLI(rD, rA, imm) \
- bsrli rD, rA, imm
- #else
- #define BSRLI(rD, rA, imm) BSRLI ## imm (rD, rA)
+ #if CONFIG_XILINX_MICROBLAZE0_USE_BARREL == 0
/* Only the used shift constants defined here - add more if needed */
#define BSRLI2(rD, rA) \
srl rD, rA; /* << 1 */ \
srl rD, rD; /* << 2 */
+ #define BSRLI4(rD, rA) \
+ BSRLI2(rD, rA); \
+ BSRLI2(rD, rD)
#define BSRLI10(rD, rA) \
srl rD, rA; /* << 1 */ \
srl rD, rD; /* << 2 */ \
@@ -170,7 +169,33 @@
#define BSRLI20(rD, rA) \
BSRLI10(rD, rA); \
BSRLI10(rD, rD)
+
+ .macro bsrli, rD, rA, IMM
+ .if (\IMM) == 2
+ BSRLI2(\rD, \rA)
+ .elseif (\IMM) == 10
+ BSRLI10(\rD, \rA)
+ .elseif (\IMM) == 12
+ BSRLI2(\rD, \rA)
+ BSRLI10(\rD, \rD)
+ .elseif (\IMM) == 14
+ BSRLI4(\rD, \rA)
+ BSRLI10(\rD, \rD)
+ .elseif (\IMM) == 20
+ BSRLI20(\rD, \rA)
+ .elseif (\IMM) == 24
+ BSRLI4(\rD, \rA)
+ BSRLI20(\rD, \rD)
+ .elseif (\IMM) == 28
+ BSRLI4(\rD, \rA)
+ BSRLI4(\rD, \rD)
+ BSRLI20(\rD, \rD)
+ .else
+ .error "BSRLI shift macros \IMM"
+ .endif
+ .endm
#endif
+
#endif /* CONFIG_MMU */
.extern other_exception_handler /* Defined in exception.c */
@@ -193,8 +218,8 @@
* - W S REG EXC
*
*
- * STACK FRAME STRUCTURE (for NO_MMU)
- * ---------------------------------
+ * STACK FRAME STRUCTURE (for CONFIG_MMU=n)
+ * ----------------------------------------
*
* +-------------+ + 0
* | MSR |
@@ -604,7 +629,7 @@ ex_handler_done:
ex4:
tophys(r4,r4)
/* Create L1 (pgdir/pmd) address */
- BSRLI(r5,r3, PGDIR_SHIFT - 2)
+ bsrli r5, r3, PGDIR_SHIFT - 2
andi r5, r5, PAGE_SIZE - 4
/* Assume pgdir aligned on 4K boundary, no need for "andi r4,r4,0xfffff003" */
or r4, r4, r5
@@ -613,7 +638,7 @@ ex_handler_done:
beqi r5, ex2 /* Bail if no table */
tophys(r5,r5)
- BSRLI(r6,r3,PTE_SHIFT) /* Compute PTE address */
+ bsrli r6, r3, PTE_SHIFT /* Compute PTE address */
andi r6, r6, PAGE_SIZE - 4
or r5, r5, r6
lwi r4, r5, 0 /* Get Linux PTE */
@@ -705,7 +730,7 @@ ex_handler_done:
ex6:
tophys(r4,r4)
/* Create L1 (pgdir/pmd) address */
- BSRLI(r5,r3, PGDIR_SHIFT - 2)
+ bsrli r5, r3, PGDIR_SHIFT - 2
andi r5, r5, PAGE_SIZE - 4
/* Assume pgdir aligned on 4K boundary, no need for "andi r4,r4,0xfffff003" */
or r4, r4, r5
@@ -714,7 +739,7 @@ ex_handler_done:
beqi r5, ex7 /* Bail if no table */
tophys(r5,r5)
- BSRLI(r6,r3,PTE_SHIFT) /* Compute PTE address */
+ bsrli r6, r3, PTE_SHIFT /* Compute PTE address */
andi r6, r6, PAGE_SIZE - 4
or r5, r5, r6
lwi r4, r5, 0 /* Get Linux PTE */
@@ -776,7 +801,7 @@ ex_handler_done:
ex9:
tophys(r4,r4)
/* Create L1 (pgdir/pmd) address */
- BSRLI(r5,r3, PGDIR_SHIFT - 2)
+ bsrli r5, r3, PGDIR_SHIFT - 2
andi r5, r5, PAGE_SIZE - 4
/* Assume pgdir aligned on 4K boundary, no need for "andi r4,r4,0xfffff003" */
or r4, r4, r5
@@ -785,7 +810,7 @@ ex_handler_done:
beqi r5, ex10 /* Bail if no table */
tophys(r5,r5)
- BSRLI(r6,r3,PTE_SHIFT) /* Compute PTE address */
+ bsrli r6, r3, PTE_SHIFT /* Compute PTE address */
andi r6, r6, PAGE_SIZE - 4
or r5, r5, r6
lwi r4, r5, 0 /* Get Linux PTE */
@@ -922,7 +947,7 @@ ex_handler_done:
.ent _unaligned_data_exception
_unaligned_data_exception:
andi r8, r3, 0x3E0; /* Mask and extract the register operand */
- BSRLI(r8,r8,2); /* r8 >> 2 = register operand * 8 */
+ bsrli r8, r8, 2; /* r8 >> 2 = register operand * 8 */
andi r6, r3, 0x400; /* Extract ESR[S] */
bneid r6, ex_sw_vm;
andi r6, r3, 0x800; /* Extract ESR[W] - delay slot */
diff --git a/arch/microblaze/kernel/intc.c b/arch/microblaze/kernel/intc.c
index 7a1a8d4354f..15c7c12ea0e 100644
--- a/arch/microblaze/kernel/intc.c
+++ b/arch/microblaze/kernel/intc.c
@@ -1,5 +1,6 @@
/*
- * Copyright (C) 2007-2009 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2007-2013 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2012-2013 Xilinx, Inc.
* Copyright (C) 2007-2009 PetaLogix
* Copyright (C) 2006 Atmark Techno, Inc.
*
@@ -8,23 +9,15 @@
* for more details.
*/
-#include <linux/init.h>
#include <linux/irqdomain.h>
#include <linux/irq.h>
-#include <asm/page.h>
+#include <linux/of_address.h>
#include <linux/io.h>
#include <linux/bug.h>
-#include <asm/prom.h>
-#include <asm/irq.h>
+#include "../../drivers/irqchip/irqchip.h"
-#ifdef CONFIG_SELFMOD_INTC
-#include <asm/selfmod.h>
-#define INTC_BASE BARRIER_BASE_ADDR
-#else
-static unsigned int intc_baseaddr;
-#define INTC_BASE intc_baseaddr
-#endif
+static void __iomem *intc_baseaddr;
/* No one else should require these constants, so define them locally here. */
#define ISR 0x00 /* Interrupt Status Register */
@@ -39,6 +32,29 @@ static unsigned int intc_baseaddr;
#define MER_ME (1<<0)
#define MER_HIE (1<<1)
+static unsigned int (*read_fn)(void __iomem *);
+static void (*write_fn)(u32, void __iomem *);
+
+static void intc_write32(u32 val, void __iomem *addr)
+{
+ iowrite32(val, addr);
+}
+
+static unsigned int intc_read32(void __iomem *addr)
+{
+ return ioread32(addr);
+}
+
+static void intc_write32_be(u32 val, void __iomem *addr)
+{
+ iowrite32be(val, addr);
+}
+
+static unsigned int intc_read32_be(void __iomem *addr)
+{
+ return ioread32be(addr);
+}
+
static void intc_enable_or_unmask(struct irq_data *d)
{
unsigned long mask = 1 << d->hwirq;
@@ -50,21 +66,21 @@ static void intc_enable_or_unmask(struct irq_data *d)
* acks the irq before calling the interrupt handler
*/
if (irqd_is_level_type(d))
- out_be32(INTC_BASE + IAR, mask);
+ write_fn(mask, intc_baseaddr + IAR);
- out_be32(INTC_BASE + SIE, mask);
+ write_fn(mask, intc_baseaddr + SIE);
}
static void intc_disable_or_mask(struct irq_data *d)
{
pr_debug("disable: %ld\n", d->hwirq);
- out_be32(INTC_BASE + CIE, 1 << d->hwirq);
+ write_fn(1 << d->hwirq, intc_baseaddr + CIE);
}
static void intc_ack(struct irq_data *d)
{
pr_debug("ack: %ld\n", d->hwirq);
- out_be32(INTC_BASE + IAR, 1 << d->hwirq);
+ write_fn(1 << d->hwirq, intc_baseaddr + IAR);
}
static void intc_mask_ack(struct irq_data *d)
@@ -72,8 +88,8 @@ static void intc_mask_ack(struct irq_data *d)
unsigned long mask = 1 << d->hwirq;
pr_debug("disable_and_ack: %ld\n", d->hwirq);
- out_be32(INTC_BASE + CIE, mask);
- out_be32(INTC_BASE + IAR, mask);
+ write_fn(mask, intc_baseaddr + CIE);
+ write_fn(mask, intc_baseaddr + IAR);
}
static struct irq_chip intc_dev = {
@@ -90,7 +106,7 @@ unsigned int get_irq(void)
{
unsigned int hwirq, irq = -1;
- hwirq = in_be32(INTC_BASE + IVR);
+ hwirq = read_fn(intc_baseaddr + IVR);
if (hwirq != -1U)
irq = irq_find_mapping(root_domain, hwirq);
@@ -120,56 +136,62 @@ static const struct irq_domain_ops xintc_irq_domain_ops = {
.map = xintc_map,
};
-void __init init_IRQ(void)
+static int __init xilinx_intc_of_init(struct device_node *intc,
+ struct device_node *parent)
{
u32 nr_irq, intr_mask;
- struct device_node *intc = NULL;
-#ifdef CONFIG_SELFMOD_INTC
- unsigned int intc_baseaddr = 0;
- static int arr_func[] = {
- (int)&get_irq,
- (int)&intc_enable_or_unmask,
- (int)&intc_disable_or_mask,
- (int)&intc_mask_ack,
- (int)&intc_ack,
- (int)&intc_end,
- 0
- };
-#endif
- intc = of_find_compatible_node(NULL, NULL, "xlnx,xps-intc-1.00.a");
- BUG_ON(!intc);
-
- intc_baseaddr = be32_to_cpup(of_get_property(intc, "reg", NULL));
- intc_baseaddr = (unsigned long) ioremap(intc_baseaddr, PAGE_SIZE);
- nr_irq = be32_to_cpup(of_get_property(intc,
- "xlnx,num-intr-inputs", NULL));
-
- intr_mask =
- be32_to_cpup(of_get_property(intc, "xlnx,kind-of-intr", NULL));
+ int ret;
+
+ intc_baseaddr = of_iomap(intc, 0);
+ BUG_ON(!intc_baseaddr);
+
+ ret = of_property_read_u32(intc, "xlnx,num-intr-inputs", &nr_irq);
+ if (ret < 0) {
+ pr_err("%s: unable to read xlnx,num-intr-inputs\n", __func__);
+ return -EINVAL;
+ }
+
+ ret = of_property_read_u32(intc, "xlnx,kind-of-intr", &intr_mask);
+ if (ret < 0) {
+ pr_err("%s: unable to read xlnx,kind-of-intr\n", __func__);
+ return -EINVAL;
+ }
+
if (intr_mask > (u32)((1ULL << nr_irq) - 1))
- printk(KERN_INFO " ERROR: Mismatch in kind-of-intr param\n");
+ pr_info(" ERROR: Mismatch in kind-of-intr param\n");
-#ifdef CONFIG_SELFMOD_INTC
- selfmod_function((int *) arr_func, intc_baseaddr);
-#endif
- printk(KERN_INFO "%s #0 at 0x%08x, num_irq=%d, edge=0x%x\n",
- intc->name, intc_baseaddr, nr_irq, intr_mask);
+ pr_info("%s: num_irq=%d, edge=0x%x\n",
+ intc->full_name, nr_irq, intr_mask);
+
+ write_fn = intc_write32;
+ read_fn = intc_read32;
/*
* Disable all external interrupts until they are
* explicity requested.
*/
- out_be32(intc_baseaddr + IER, 0);
+ write_fn(0, intc_baseaddr + IER);
/* Acknowledge any pending interrupts just in case. */
- out_be32(intc_baseaddr + IAR, 0xffffffff);
+ write_fn(0xffffffff, intc_baseaddr + IAR);
/* Turn on the Master Enable. */
- out_be32(intc_baseaddr + MER, MER_HIE | MER_ME);
+ write_fn(MER_HIE | MER_ME, intc_baseaddr + MER);
+ if (!(read_fn(intc_baseaddr + MER) & (MER_HIE | MER_ME))) {
+ write_fn = intc_write32_be;
+ read_fn = intc_read32_be;
+ write_fn(MER_HIE | MER_ME, intc_baseaddr + MER);
+ }
/* Yeah, okay, casting the intr_mask to a void* is butt-ugly, but I'm
* lazy and Michal can clean it up to something nicer when he tests
* and commits this patch. ~~gcl */
root_domain = irq_domain_add_linear(intc, nr_irq, &xintc_irq_domain_ops,
(void *)intr_mask);
+
+ irq_set_default_host(root_domain);
+
+ return 0;
}
+
+IRQCHIP_DECLARE(xilinx_intc, "xlnx,xps-intc-1.00.a", xilinx_intc_of_init);
diff --git a/arch/microblaze/kernel/irq.c b/arch/microblaze/kernel/irq.c
index ace700afbfd..11e24de91aa 100644
--- a/arch/microblaze/kernel/irq.c
+++ b/arch/microblaze/kernel/irq.c
@@ -17,10 +17,8 @@
#include <linux/seq_file.h>
#include <linux/kernel_stat.h>
#include <linux/irq.h>
+#include <linux/irqchip.h>
#include <linux/of_irq.h>
-#include <linux/export.h>
-
-#include <asm/prom.h>
static u32 concurrent_irq;
@@ -47,3 +45,9 @@ next_irq:
set_irq_regs(old_regs);
trace_hardirqs_on();
}
+
+void __init init_IRQ(void)
+{
+ /* process the entire interrupt tree in one go */
+ irqchip_init();
+}
diff --git a/arch/microblaze/kernel/microblaze_ksyms.c b/arch/microblaze/kernel/microblaze_ksyms.c
index 2b25bcf05c0..9f1d02c4c5c 100644
--- a/arch/microblaze/kernel/microblaze_ksyms.c
+++ b/arch/microblaze/kernel/microblaze_ksyms.c
@@ -7,7 +7,7 @@
* published by the Free Software Foundation.
*/
-#include <linux/module.h>
+#include <linux/export.h>
#include <linux/string.h>
#include <linux/cryptohash.h>
#include <linux/delay.h>
diff --git a/arch/microblaze/kernel/module.c b/arch/microblaze/kernel/module.c
index f39257a5abc..182e6be856c 100644
--- a/arch/microblaze/kernel/module.c
+++ b/arch/microblaze/kernel/module.c
@@ -7,7 +7,7 @@
* published by the Free Software Foundation.
*/
-#include <linux/module.h>
+#include <linux/export.h>
#include <linux/moduleloader.h>
#include <linux/kernel.h>
#include <linux/elf.h>
@@ -108,8 +108,7 @@ int apply_relocate_add(Elf32_Shdr *sechdrs, const char *strtab,
break;
default:
- printk(KERN_ERR "module %s: "
- "Unknown relocation: %u\n",
+ pr_err("module %s: Unknown relocation: %u\n",
module->name,
ELF32_R_TYPE(rela[i].r_info));
return -ENOEXEC;
diff --git a/arch/microblaze/kernel/platform.c b/arch/microblaze/kernel/platform.c
new file mode 100644
index 00000000000..b9529caa507
--- /dev/null
+++ b/arch/microblaze/kernel/platform.c
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2008 Michal Simek <monstr@monstr.eu>
+ *
+ * based on virtex.c file
+ *
+ * Copyright 2007 Secret Lab Technologies Ltd.
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2. This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+#include <linux/init.h>
+#include <linux/of_platform.h>
+#include <asm/prom.h>
+#include <asm/setup.h>
+
+static struct of_device_id xilinx_of_bus_ids[] __initdata = {
+ { .compatible = "simple-bus", },
+ { .compatible = "xlnx,compound", },
+ {}
+};
+
+static int __init microblaze_device_probe(void)
+{
+ of_platform_bus_probe(NULL, xilinx_of_bus_ids, NULL);
+ of_platform_reset_gpio_probe();
+ return 0;
+}
+device_initcall(microblaze_device_probe);
diff --git a/arch/microblaze/kernel/process.c b/arch/microblaze/kernel/process.c
index a5b74f729e5..b2dd37196b3 100644
--- a/arch/microblaze/kernel/process.c
+++ b/arch/microblaze/kernel/process.c
@@ -8,113 +8,45 @@
* for more details.
*/
-#include <linux/module.h>
+#include <linux/cpu.h>
+#include <linux/export.h>
#include <linux/sched.h>
#include <linux/pm.h>
#include <linux/tick.h>
#include <linux/bitops.h>
#include <linux/ptrace.h>
#include <asm/pgalloc.h>
-#include <asm/uaccess.h> /* for USER_DS macros */
+#include <linux/uaccess.h> /* for USER_DS macros */
#include <asm/cacheflush.h>
void show_regs(struct pt_regs *regs)
{
- printk(KERN_INFO " Registers dump: mode=%X\r\n", regs->pt_mode);
- printk(KERN_INFO " r1=%08lX, r2=%08lX, r3=%08lX, r4=%08lX\n",
+ show_regs_print_info(KERN_INFO);
+
+ pr_info(" Registers dump: mode=%X\r\n", regs->pt_mode);
+ pr_info(" r1=%08lX, r2=%08lX, r3=%08lX, r4=%08lX\n",
regs->r1, regs->r2, regs->r3, regs->r4);
- printk(KERN_INFO " r5=%08lX, r6=%08lX, r7=%08lX, r8=%08lX\n",
+ pr_info(" r5=%08lX, r6=%08lX, r7=%08lX, r8=%08lX\n",
regs->r5, regs->r6, regs->r7, regs->r8);
- printk(KERN_INFO " r9=%08lX, r10=%08lX, r11=%08lX, r12=%08lX\n",
+ pr_info(" r9=%08lX, r10=%08lX, r11=%08lX, r12=%08lX\n",
regs->r9, regs->r10, regs->r11, regs->r12);
- printk(KERN_INFO " r13=%08lX, r14=%08lX, r15=%08lX, r16=%08lX\n",
+ pr_info(" r13=%08lX, r14=%08lX, r15=%08lX, r16=%08lX\n",
regs->r13, regs->r14, regs->r15, regs->r16);
- printk(KERN_INFO " r17=%08lX, r18=%08lX, r19=%08lX, r20=%08lX\n",
+ pr_info(" r17=%08lX, r18=%08lX, r19=%08lX, r20=%08lX\n",
regs->r17, regs->r18, regs->r19, regs->r20);
- printk(KERN_INFO " r21=%08lX, r22=%08lX, r23=%08lX, r24=%08lX\n",
+ pr_info(" r21=%08lX, r22=%08lX, r23=%08lX, r24=%08lX\n",
regs->r21, regs->r22, regs->r23, regs->r24);
- printk(KERN_INFO " r25=%08lX, r26=%08lX, r27=%08lX, r28=%08lX\n",
+ pr_info(" r25=%08lX, r26=%08lX, r27=%08lX, r28=%08lX\n",
regs->r25, regs->r26, regs->r27, regs->r28);
- printk(KERN_INFO " r29=%08lX, r30=%08lX, r31=%08lX, rPC=%08lX\n",
+ pr_info(" r29=%08lX, r30=%08lX, r31=%08lX, rPC=%08lX\n",
regs->r29, regs->r30, regs->r31, regs->pc);
- printk(KERN_INFO " msr=%08lX, ear=%08lX, esr=%08lX, fsr=%08lX\n",
+ pr_info(" msr=%08lX, ear=%08lX, esr=%08lX, fsr=%08lX\n",
regs->msr, regs->ear, regs->esr, regs->fsr);
}
-void (*pm_idle)(void);
void (*pm_power_off)(void) = NULL;
EXPORT_SYMBOL(pm_power_off);
-static int hlt_counter = 1;
-
-void disable_hlt(void)
-{
- hlt_counter++;
-}
-EXPORT_SYMBOL(disable_hlt);
-
-void enable_hlt(void)
-{
- hlt_counter--;
-}
-EXPORT_SYMBOL(enable_hlt);
-
-static int __init nohlt_setup(char *__unused)
-{
- hlt_counter = 1;
- return 1;
-}
-__setup("nohlt", nohlt_setup);
-
-static int __init hlt_setup(char *__unused)
-{
- hlt_counter = 0;
- return 1;
-}
-__setup("hlt", hlt_setup);
-
-void default_idle(void)
-{
- if (likely(hlt_counter)) {
- local_irq_disable();
- stop_critical_timings();
- cpu_relax();
- start_critical_timings();
- local_irq_enable();
- } else {
- clear_thread_flag(TIF_POLLING_NRFLAG);
- smp_mb__after_clear_bit();
- local_irq_disable();
- while (!need_resched())
- cpu_sleep();
- local_irq_enable();
- set_thread_flag(TIF_POLLING_NRFLAG);
- }
-}
-
-void cpu_idle(void)
-{
- set_thread_flag(TIF_POLLING_NRFLAG);
-
- /* endless idle loop with no priority at all */
- while (1) {
- void (*idle)(void) = pm_idle;
-
- if (!idle)
- idle = default_idle;
-
- tick_nohz_idle_enter();
- rcu_idle_enter();
- while (!need_resched())
- idle();
- rcu_idle_exit();
- tick_nohz_idle_exit();
-
- schedule_preempt_disabled();
- check_pgt_cache();
- }
-}
-
void flush_thread(void)
{
}
@@ -229,3 +161,8 @@ int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpregs)
return 0; /* MicroBlaze has no separate FPU registers */
}
#endif /* CONFIG_MMU */
+
+void arch_cpu_idle(void)
+{
+ local_irq_enable();
+}
diff --git a/arch/microblaze/kernel/prom.c b/arch/microblaze/kernel/prom.c
index a744e3f1888..68f099960eb 100644
--- a/arch/microblaze/kernel/prom.c
+++ b/arch/microblaze/kernel/prom.c
@@ -14,6 +14,7 @@
*/
#include <stdarg.h>
+#include <linux/export.h>
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/init.h>
@@ -25,11 +26,11 @@
#include <linux/delay.h>
#include <linux/initrd.h>
#include <linux/bitops.h>
-#include <linux/module.h>
#include <linux/kexec.h>
#include <linux/debugfs.h>
#include <linux/irq.h>
#include <linux/memblock.h>
+#include <linux/of_fdt.h>
#include <asm/prom.h>
#include <asm/page.h>
@@ -41,24 +42,14 @@
#include <asm/sections.h>
#include <asm/pci-bridge.h>
-void __init early_init_dt_add_memory_arch(u64 base, u64 size)
-{
- memblock_add(base, size);
-}
-
-void * __init early_init_dt_alloc_memory_arch(u64 size, u64 align)
-{
- return __va(memblock_alloc(size, align));
-}
-
#ifdef CONFIG_EARLY_PRINTK
-static char *stdout;
+static const char *stdout;
static int __init early_init_dt_scan_chosen_serial(unsigned long node,
const char *uname, int depth, void *data)
{
- unsigned long l;
- char *p;
+ int l;
+ const char *p;
pr_debug("%s: depth: %d, uname: %s\n", __func__, depth, uname);
@@ -89,7 +80,7 @@ static int __init early_init_dt_scan_chosen_serial(unsigned long node,
(strncmp(p, "xlnx,opb-uartlite", 17) == 0) ||
(strncmp(p, "xlnx,axi-uartlite", 17) == 0) ||
(strncmp(p, "xlnx,mdm", 8) == 0)) {
- unsigned int *addrp;
+ const unsigned int *addrp;
*(u32 *)data = UARTLITE;
@@ -111,21 +102,10 @@ void __init early_init_devtree(void *params)
{
pr_debug(" -> early_init_devtree(%p)\n", params);
- /* Setup flat device-tree pointer */
- initial_boot_params = params;
-
- /* Retrieve various informations from the /chosen node of the
- * device-tree, including the platform type, initrd location and
- * size, TCE reserve, and more ...
- */
- of_scan_flat_dt(early_init_dt_scan_chosen, cmd_line);
+ early_init_dt_scan(params);
+ if (!strlen(boot_command_line))
+ strlcpy(boot_command_line, cmd_line, COMMAND_LINE_SIZE);
- /* Scan memory nodes and rebuild MEMBLOCKs */
- of_scan_flat_dt(early_init_dt_scan_root, NULL);
- of_scan_flat_dt(early_init_dt_scan_memory, NULL);
-
- /* Save command line for /proc/cmdline and then parse parameters */
- strlcpy(boot_command_line, cmd_line, COMMAND_LINE_SIZE);
parse_early_param();
memblock_allow_resize();
@@ -134,44 +114,3 @@ void __init early_init_devtree(void *params)
pr_debug(" <- early_init_devtree()\n");
}
-
-#ifdef CONFIG_BLK_DEV_INITRD
-void __init early_init_dt_setup_initrd_arch(unsigned long start,
- unsigned long end)
-{
- initrd_start = (unsigned long)__va(start);
- initrd_end = (unsigned long)__va(end);
- initrd_below_start_ok = 1;
-}
-#endif
-
-/*******
- *
- * New implementation of the OF "find" APIs, return a refcounted
- * object, call of_node_put() when done. The device tree and list
- * are protected by a rw_lock.
- *
- * Note that property management will need some locking as well,
- * this isn't dealt with yet.
- *
- *******/
-
-#if defined(CONFIG_DEBUG_FS) && defined(DEBUG)
-static struct debugfs_blob_wrapper flat_dt_blob;
-
-static int __init export_flat_device_tree(void)
-{
- struct dentry *d;
-
- flat_dt_blob.data = initial_boot_params;
- flat_dt_blob.size = initial_boot_params->totalsize;
-
- d = debugfs_create_blob("flat-device-tree", S_IFREG | S_IRUSR,
- of_debugfs_root, &flat_dt_blob);
- if (!d)
- return 1;
-
- return 0;
-}
-device_initcall(export_flat_device_tree);
-#endif
diff --git a/arch/microblaze/kernel/prom_parse.c b/arch/microblaze/kernel/prom_parse.c
index 47187cc2cf0..068762f55fd 100644
--- a/arch/microblaze/kernel/prom_parse.c
+++ b/arch/microblaze/kernel/prom_parse.c
@@ -1,8 +1,8 @@
#undef DEBUG
+#include <linux/export.h>
#include <linux/kernel.h>
#include <linux/string.h>
-#include <linux/module.h>
#include <linux/ioport.h>
#include <linux/etherdevice.h>
#include <linux/of_address.h>
diff --git a/arch/microblaze/kernel/ptrace.c b/arch/microblaze/kernel/ptrace.c
index ab1b9db661f..39cf50841f6 100644
--- a/arch/microblaze/kernel/ptrace.c
+++ b/arch/microblaze/kernel/ptrace.c
@@ -40,7 +40,7 @@
#include <asm/asm-offsets.h>
#include <asm/cacheflush.h>
#include <asm/syscall.h>
-#include <asm/io.h>
+#include <linux/io.h>
/* Returns the address where the register at REG_OFFS in P is stashed away. */
static microblaze_reg_t *reg_save_addr(unsigned reg_offs,
@@ -164,29 +164,6 @@ asmlinkage void do_syscall_trace_leave(struct pt_regs *regs)
tracehook_report_syscall_exit(regs, step);
}
-#if 0
-static asmlinkage void syscall_trace(void)
-{
- if (!test_thread_flag(TIF_SYSCALL_TRACE))
- return;
- if (!(current->ptrace & PT_PTRACED))
- return;
- /* The 0x80 provides a way for the tracing parent to distinguish
- between a syscall stop and SIGTRAP delivery */
- ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
- ? 0x80 : 0));
- /*
- * this isn't the same as continuing with a signal, but it will do
- * for normal use. strace only continues with a signal if the
- * stopping signal is not SIGTRAP. -brl
- */
- if (current->exit_code) {
- send_sig(current->exit_code, current, 1);
- current->exit_code = 0;
- }
-}
-#endif
-
void ptrace_disable(struct task_struct *child)
{
/* nothing to do */
diff --git a/arch/microblaze/kernel/reset.c b/arch/microblaze/kernel/reset.c
index 2e5079ab53d..fbe58c6554a 100644
--- a/arch/microblaze/kernel/reset.c
+++ b/arch/microblaze/kernel/reset.c
@@ -67,7 +67,11 @@ static void gpio_system_reset(void)
pr_notice("Reset GPIO unavailable - halting!\n");
}
#else
-#define gpio_system_reset() do {} while (0)
+static void gpio_system_reset(void)
+{
+ pr_notice("No reset GPIO present - halting!\n");
+}
+
void of_platform_reset_gpio_probe(void)
{
return;
diff --git a/arch/microblaze/kernel/selfmod.c b/arch/microblaze/kernel/selfmod.c
deleted file mode 100644
index 89508bdc9f3..00000000000
--- a/arch/microblaze/kernel/selfmod.c
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright (C) 2007-2009 Michal Simek <monstr@monstr.eu>
- * Copyright (C) 2009 PetaLogix
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file "COPYING" in the main directory of this archive
- * for more details.
- */
-
-#include <linux/interrupt.h>
-#include <asm/selfmod.h>
-
-#undef DEBUG
-
-#if __GNUC__ > 3
-#error GCC 4 unsupported SELFMOD. Please disable SELFMOD from menuconfig.
-#endif
-
-#define OPCODE_IMM 0xB0000000
-#define OPCODE_LWI 0xE8000000
-#define OPCODE_LWI_MASK 0xEC000000
-#define OPCODE_RTSD 0xB60F0008 /* return from func: rtsd r15, 8 */
-#define OPCODE_ADDIK 0x30000000
-#define OPCODE_ADDIK_MASK 0xFC000000
-
-#define IMM_BASE (OPCODE_IMM | (BARRIER_BASE_ADDR >> 16))
-#define LWI_BASE (OPCODE_LWI | (BARRIER_BASE_ADDR & 0x0000ff00))
-#define LWI_BASE_MASK (OPCODE_LWI_MASK | (BARRIER_BASE_ADDR & 0x0000ff00))
-#define ADDIK_BASE (OPCODE_ADDIK | (BARRIER_BASE_ADDR & 0x0000ff00))
-#define ADDIK_BASE_MASK (OPCODE_ADDIK_MASK | (BARRIER_BASE_ADDR & 0x0000ff00))
-
-#define MODIFY_INSTR { \
- pr_debug("%s: curr instr, (%d):0x%x, next(%d):0x%x\n", \
- __func__, i, addr[i], i + 1, addr[i + 1]); \
- addr[i] = OPCODE_IMM + (base >> 16); \
- /* keep instruction opcode and add only last 16bits */ \
- addr[i + 1] = (addr[i + 1] & 0xffff00ff) + (base & 0xffff); \
- __invalidate_icache(addr[i]); \
- __invalidate_icache(addr[i + 1]); \
- pr_debug("%s: hack instr, (%d):0x%x, next(%d):0x%x\n", \
- __func__, i, addr[i], i + 1, addr[i + 1]); }
-
-/* NOTE
- * self-modified part of code for improvement of interrupt controller
- * save instruction in interrupt rutine
- */
-void selfmod_function(const int *arr_fce, const unsigned int base)
-{
- unsigned int flags, i, j, *addr = NULL;
-
- local_irq_save(flags);
- __disable_icache();
-
- /* zero terminated array */
- for (j = 0; arr_fce[j] != 0; j++) {
- /* get start address of function */
- addr = (unsigned int *) arr_fce[j];
- pr_debug("%s: func(%d) at 0x%x\n",
- __func__, j, (unsigned int) addr);
- for (i = 0; ; i++) {
- pr_debug("%s: instruction code at %d: 0x%x\n",
- __func__, i, addr[i]);
- if (addr[i] == IMM_BASE) {
- /* detecting of lwi (0xE8) or swi (0xF8) instr
- * I can detect both opcode with one mask */
- if ((addr[i + 1] & LWI_BASE_MASK) == LWI_BASE) {
- MODIFY_INSTR;
- } else /* detection addik for ack */
- if ((addr[i + 1] & ADDIK_BASE_MASK) ==
- ADDIK_BASE) {
- MODIFY_INSTR;
- }
- } else if (addr[i] == OPCODE_RTSD) {
- /* return from function means end of function */
- pr_debug("%s: end of array %d\n", __func__, i);
- break;
- }
- }
- }
- local_irq_restore(flags);
-} /* end of self-modified code */
diff --git a/arch/microblaze/kernel/setup.c b/arch/microblaze/kernel/setup.c
index 954348f8350..ab5b488e1fd 100644
--- a/arch/microblaze/kernel/setup.c
+++ b/arch/microblaze/kernel/setup.c
@@ -9,12 +9,15 @@
*/
#include <linux/init.h>
+#include <linux/clk-provider.h>
+#include <linux/clocksource.h>
#include <linux/string.h>
#include <linux/seq_file.h>
#include <linux/cpu.h>
#include <linux/initrd.h>
#include <linux/console.h>
#include <linux/debugfs.h>
+#include <linux/of_fdt.h>
#include <asm/setup.h>
#include <asm/sections.h>
@@ -49,7 +52,7 @@ char cmd_line[COMMAND_LINE_SIZE] __attribute__ ((section(".data")));
void __init setup_arch(char **cmdline_p)
{
- *cmdline_p = cmd_line;
+ *cmdline_p = boot_command_line;
console_verbose();
@@ -68,17 +71,9 @@ void __init setup_arch(char **cmdline_p)
xilinx_pci_init();
-#if defined(CONFIG_SELFMOD_INTC) || defined(CONFIG_SELFMOD_TIMER)
- pr_notice("Self modified code enable\n");
-#endif
-
-#ifdef CONFIG_VT
-#if defined(CONFIG_XILINX_CONSOLE)
- conswitchp = &xil_con;
-#elif defined(CONFIG_DUMMY_CONSOLE)
+#if defined(CONFIG_DUMMY_CONSOLE)
conswitchp = &dummy_con;
#endif
-#endif
}
#ifdef CONFIG_MTD_UCLINUX
@@ -138,7 +133,7 @@ void __init machine_early_init(const char *cmdline, unsigned int ram,
lockdep_init();
/* initialize device tree for usage in early_printk */
- early_init_devtree((void *)_fdt_start);
+ early_init_devtree(_fdt_start);
#ifdef CONFIG_EARLY_PRINTK
setup_early_printk(NULL);
@@ -150,33 +145,34 @@ void __init machine_early_init(const char *cmdline, unsigned int ram,
/* printk("TLB1 0x%08x, TLB0 0x%08x, tlb 0x%x\n", tlb0,
tlb1, kernel_tlb); */
- printk("Ramdisk addr 0x%08x, ", ram);
+ pr_info("Ramdisk addr 0x%08x, ", ram);
if (fdt)
- printk("FDT at 0x%08x\n", fdt);
+ pr_info("FDT at 0x%08x\n", fdt);
else
- printk("Compiled-in FDT at 0x%08x\n",
- (unsigned int)_fdt_start);
+ pr_info("Compiled-in FDT at %p\n", _fdt_start);
#ifdef CONFIG_MTD_UCLINUX
- printk("Found romfs @ 0x%08x (0x%08x)\n",
+ pr_info("Found romfs @ 0x%08x (0x%08x)\n",
romfs_base, romfs_size);
- printk("#### klimit %p ####\n", old_klimit);
+ pr_info("#### klimit %p ####\n", old_klimit);
BUG_ON(romfs_size < 0); /* What else can we do? */
- printk("Moved 0x%08x bytes from 0x%08x to 0x%08x\n",
+ pr_info("Moved 0x%08x bytes from 0x%08x to 0x%08x\n",
romfs_size, romfs_base, (unsigned)&__bss_stop);
- printk("New klimit: 0x%08x\n", (unsigned)klimit);
+ pr_info("New klimit: 0x%08x\n", (unsigned)klimit);
#endif
#if CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR
- if (msr)
- printk("!!!Your kernel has setup MSR instruction but "
- "CPU don't have it %x\n", msr);
+ if (msr) {
+ pr_info("!!!Your kernel has setup MSR instruction but ");
+ pr_cont("CPU don't have it %x\n", msr);
+ }
#else
- if (!msr)
- printk("!!!Your kernel not setup MSR instruction but "
- "CPU have it %x\n", msr);
+ if (!msr) {
+ pr_info("!!!Your kernel not setup MSR instruction but ");
+ pr_cont("CPU have it %x\n", msr);
+ }
#endif
/* Do not copy reset vectors. offset = 0x2 means skip the first
@@ -194,6 +190,13 @@ void __init machine_early_init(const char *cmdline, unsigned int ram,
per_cpu(CURRENT_SAVE, 0) = (unsigned long)current;
}
+void __init time_init(void)
+{
+ of_clk_init(NULL);
+ setup_cpuinfo_clk();
+ clocksource_of_init();
+}
+
#ifdef CONFIG_DEBUG_FS
struct dentry *of_debugfs_root;
@@ -216,35 +219,9 @@ static int __init debugfs_tlb(void)
d = debugfs_create_u32("tlb_skip", S_IRUGO, of_debugfs_root, &tlb_skip);
if (!d)
return -ENOMEM;
+
+ return 0;
}
device_initcall(debugfs_tlb);
# endif
#endif
-
-static int dflt_bus_notify(struct notifier_block *nb,
- unsigned long action, void *data)
-{
- struct device *dev = data;
-
- /* We are only intereted in device addition */
- if (action != BUS_NOTIFY_ADD_DEVICE)
- return 0;
-
- set_dma_ops(dev, &dma_direct_ops);
-
- return NOTIFY_DONE;
-}
-
-static struct notifier_block dflt_plat_bus_notifier = {
- .notifier_call = dflt_bus_notify,
- .priority = INT_MAX,
-};
-
-static int __init setup_bus_notifier(void)
-{
- bus_register_notifier(&platform_bus_type, &dflt_plat_bus_notifier);
-
- return 0;
-}
-
-arch_initcall(setup_bus_notifier);
diff --git a/arch/microblaze/kernel/signal.c b/arch/microblaze/kernel/signal.c
index ac3d0a0f481..49a07a4d76d 100644
--- a/arch/microblaze/kernel/signal.c
+++ b/arch/microblaze/kernel/signal.c
@@ -41,13 +41,6 @@
#include <asm/cacheflush.h>
#include <asm/syscalls.h>
-asmlinkage long
-sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss,
- struct pt_regs *regs)
-{
- return do_sigaltstack(uss, uoss, regs->r1);
-}
-
/*
* Do a signal return; undo the signal stack.
*/
@@ -109,9 +102,7 @@ asmlinkage long sys_rt_sigreturn(struct pt_regs *regs)
if (restore_sigcontext(regs, &frame->uc.uc_mcontext, &rval))
goto badframe;
- /* It is more difficult to avoid calling this function than to
- call it and ignore errors. */
- if (do_sigaltstack(&frame->uc.uc_stack, NULL, regs->r1) == -EFAULT)
+ if (restore_altstack(&frame->uc.uc_stack))
goto badframe;
return rval;
@@ -194,11 +185,7 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
/* Create the ucontext. */
err |= __put_user(0, &frame->uc.uc_flags);
err |= __put_user(NULL, &frame->uc.uc_link);
- err |= __put_user((void __user *)current->sas_ss_sp,
- &frame->uc.uc_stack.ss_sp);
- err |= __put_user(sas_ss_flags(regs->r1),
- &frame->uc.uc_stack.ss_flags);
- err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
+ err |= __save_altstack(&frame->uc.uc_stack, regs->r1);
err |= setup_sigcontext(&frame->uc.uc_mcontext,
regs, set->sig[0]);
err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
@@ -229,7 +216,7 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
/* MS: I need add offset in page */
address += ((unsigned long)frame->tramp) & ~PAGE_MASK;
/* MS address is virtual */
- address = virt_to_phys(address);
+ address = __virt_to_phys(address);
invalidate_icache_range(address, address + 8);
flush_dcache_range(address, address + 8);
}
@@ -255,7 +242,7 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
set_fs(USER_DS);
#ifdef DEBUG_SIG
- printk(KERN_INFO "SIG deliver (%s:%d): sp=%p pc=%08lx\n",
+ pr_info("SIG deliver (%s:%d): sp=%p pc=%08lx\n",
current->comm, current->pid, frame, regs->pc);
#endif
@@ -330,8 +317,8 @@ static void do_signal(struct pt_regs *regs, int in_syscall)
int signr;
struct k_sigaction ka;
#ifdef DEBUG_SIG
- printk(KERN_INFO "do signal: %p %d\n", regs, in_syscall);
- printk(KERN_INFO "do signal2: %lx %lx %ld [%lx]\n", regs->pc, regs->r1,
+ pr_info("do signal: %p %d\n", regs, in_syscall);
+ pr_info("do signal2: %lx %lx %ld [%lx]\n", regs->pc, regs->r1,
regs->r12, current_thread_info()->flags);
#endif
@@ -356,15 +343,6 @@ static void do_signal(struct pt_regs *regs, int in_syscall)
asmlinkage void do_notify_resume(struct pt_regs *regs, int in_syscall)
{
- /*
- * We want the common case to go fast, which
- * is why we may in certain cases get here from
- * kernel mode. Just return without doing anything
- * if so.
- */
- if (kernel_mode(regs))
- return;
-
if (test_thread_flag(TIF_SIGPENDING))
do_signal(regs, in_syscall);
diff --git a/arch/microblaze/kernel/stacktrace.c b/arch/microblaze/kernel/stacktrace.c
index 84bc6686102..b4debe283a7 100644
--- a/arch/microblaze/kernel/stacktrace.c
+++ b/arch/microblaze/kernel/stacktrace.c
@@ -9,11 +9,11 @@
* for more details.
*/
+#include <linux/export.h>
#include <linux/sched.h>
#include <linux/stacktrace.h>
#include <linux/thread_info.h>
#include <linux/ptrace.h>
-#include <linux/module.h>
#include <asm/unwind.h>
void save_stack_trace(struct stack_trace *trace)
diff --git a/arch/microblaze/kernel/sys_microblaze.c b/arch/microblaze/kernel/sys_microblaze.c
index 63647c586b4..f1e1f666ddd 100644
--- a/arch/microblaze/kernel/sys_microblaze.c
+++ b/arch/microblaze/kernel/sys_microblaze.c
@@ -13,6 +13,7 @@
*/
#include <linux/errno.h>
+#include <linux/export.h>
#include <linux/mm.h>
#include <linux/smp.h>
#include <linux/syscalls.h>
@@ -24,22 +25,31 @@
#include <linux/sys.h>
#include <linux/ipc.h>
#include <linux/file.h>
-#include <linux/module.h>
#include <linux/err.h>
#include <linux/fs.h>
#include <linux/semaphore.h>
#include <linux/uaccess.h>
#include <linux/unistd.h>
#include <linux/slab.h>
-
#include <asm/syscalls.h>
-asmlinkage long sys_mmap(unsigned long addr, unsigned long len,
- unsigned long prot, unsigned long flags,
- unsigned long fd, off_t pgoff)
+SYSCALL_DEFINE6(mmap, unsigned long, addr, unsigned long, len,
+ unsigned long, prot, unsigned long, flags, unsigned long, fd,
+ off_t, pgoff)
{
if (pgoff & ~PAGE_MASK)
return -EINVAL;
return sys_mmap_pgoff(addr, len, prot, flags, fd, pgoff >> PAGE_SHIFT);
}
+
+SYSCALL_DEFINE6(mmap2, unsigned long, addr, unsigned long, len,
+ unsigned long, prot, unsigned long, flags, unsigned long, fd,
+ unsigned long, pgoff)
+{
+ if (pgoff & (~PAGE_MASK >> 12))
+ return -EINVAL;
+
+ return sys_mmap_pgoff(addr, len, prot, flags, fd,
+ pgoff >> (PAGE_SHIFT - 12));
+}
diff --git a/arch/microblaze/kernel/syscall_table.S b/arch/microblaze/kernel/syscall_table.S
index 4fca56cf02f..329dfbad810 100644
--- a/arch/microblaze/kernel/syscall_table.S
+++ b/arch/microblaze/kernel/syscall_table.S
@@ -192,7 +192,7 @@ ENTRY(sys_call_table)
.long sys_ni_syscall /* reserved for streams2 */
.long sys_vfork /* 190 */
.long sys_getrlimit
- .long sys_mmap_pgoff /* mmap2 */
+ .long sys_mmap2
.long sys_truncate64
.long sys_ftruncate64
.long sys_stat64 /* 195 */
@@ -308,7 +308,7 @@ ENTRY(sys_call_table)
.long sys_readlinkat /* 305 */
.long sys_fchmodat
.long sys_faccessat
- .long sys_ni_syscall /* pselect6 */
+ .long sys_pselect6
.long sys_ppoll
.long sys_unshare /* 310 */
.long sys_set_robust_list
@@ -363,8 +363,8 @@ ENTRY(sys_call_table)
.long sys_sendmsg /* 360 */
.long sys_recvmsg
.long sys_accept4
- .long sys_ni_syscall
- .long sys_ni_syscall
+ .long sys_preadv
+ .long sys_pwritev
.long sys_rt_tgsigqueueinfo /* 365 */
.long sys_perf_event_open
.long sys_recvmmsg
@@ -381,3 +381,5 @@ ENTRY(sys_call_table)
.long sys_process_vm_writev
.long sys_kcmp
.long sys_finit_module
+ .long sys_sched_setattr
+ .long sys_sched_getattr
diff --git a/arch/microblaze/kernel/timer.c b/arch/microblaze/kernel/timer.c
index aec5020a6e3..dd96f0e4bfa 100644
--- a/arch/microblaze/kernel/timer.c
+++ b/arch/microblaze/kernel/timer.c
@@ -1,5 +1,6 @@
/*
- * Copyright (C) 2007-2009 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2007-2013 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2012-2013 Xilinx, Inc.
* Copyright (C) 2007-2009 PetaLogix
* Copyright (C) 2006 Atmark Techno, Inc.
*
@@ -8,34 +9,17 @@
* for more details.
*/
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/param.h>
#include <linux/interrupt.h>
-#include <linux/profile.h>
-#include <linux/irq.h>
#include <linux/delay.h>
#include <linux/sched.h>
-#include <linux/spinlock.h>
-#include <linux/err.h>
+#include <linux/sched_clock.h>
#include <linux/clk.h>
-#include <linux/clocksource.h>
#include <linux/clockchips.h>
-#include <linux/io.h>
-#include <linux/bug.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
#include <asm/cpuinfo.h>
-#include <asm/setup.h>
-#include <asm/prom.h>
-#include <asm/irq.h>
-#include <linux/cnt32_to_63.h>
-
-#ifdef CONFIG_SELFMOD_TIMER
-#include <asm/selfmod.h>
-#define TIMER_BASE BARRIER_BASE_ADDR
-#else
-static unsigned int timer_baseaddr;
-#define TIMER_BASE timer_baseaddr
-#endif
+
+static void __iomem *timer_baseaddr;
static unsigned int freq_div_hz;
static unsigned int timer_clock_freq;
@@ -59,19 +43,44 @@ static unsigned int timer_clock_freq;
#define TCSR_PWMA (1<<9)
#define TCSR_ENALL (1<<10)
-static inline void microblaze_timer0_stop(void)
+static unsigned int (*read_fn)(void __iomem *);
+static void (*write_fn)(u32, void __iomem *);
+
+static void timer_write32(u32 val, void __iomem *addr)
+{
+ iowrite32(val, addr);
+}
+
+static unsigned int timer_read32(void __iomem *addr)
+{
+ return ioread32(addr);
+}
+
+static void timer_write32_be(u32 val, void __iomem *addr)
+{
+ iowrite32be(val, addr);
+}
+
+static unsigned int timer_read32_be(void __iomem *addr)
+{
+ return ioread32be(addr);
+}
+
+static inline void xilinx_timer0_stop(void)
{
- out_be32(TIMER_BASE + TCSR0, in_be32(TIMER_BASE + TCSR0) & ~TCSR_ENT);
+ write_fn(read_fn(timer_baseaddr + TCSR0) & ~TCSR_ENT,
+ timer_baseaddr + TCSR0);
}
-static inline void microblaze_timer0_start_periodic(unsigned long load_val)
+static inline void xilinx_timer0_start_periodic(unsigned long load_val)
{
if (!load_val)
load_val = 1;
- out_be32(TIMER_BASE + TLR0, load_val); /* loading value to timer reg */
+ /* loading value to timer reg */
+ write_fn(load_val, timer_baseaddr + TLR0);
/* load the initial value */
- out_be32(TIMER_BASE + TCSR0, TCSR_LOAD);
+ write_fn(TCSR_LOAD, timer_baseaddr + TCSR0);
/* see timer data sheet for detail
* !ENALL - don't enable 'em all
@@ -86,38 +95,39 @@ static inline void microblaze_timer0_start_periodic(unsigned long load_val)
* UDT - set the timer as down counter
* !MDT0 - generate mode
*/
- out_be32(TIMER_BASE + TCSR0,
- TCSR_TINT|TCSR_ENIT|TCSR_ENT|TCSR_ARHT|TCSR_UDT);
+ write_fn(TCSR_TINT|TCSR_ENIT|TCSR_ENT|TCSR_ARHT|TCSR_UDT,
+ timer_baseaddr + TCSR0);
}
-static inline void microblaze_timer0_start_oneshot(unsigned long load_val)
+static inline void xilinx_timer0_start_oneshot(unsigned long load_val)
{
if (!load_val)
load_val = 1;
- out_be32(TIMER_BASE + TLR0, load_val); /* loading value to timer reg */
+ /* loading value to timer reg */
+ write_fn(load_val, timer_baseaddr + TLR0);
/* load the initial value */
- out_be32(TIMER_BASE + TCSR0, TCSR_LOAD);
+ write_fn(TCSR_LOAD, timer_baseaddr + TCSR0);
- out_be32(TIMER_BASE + TCSR0,
- TCSR_TINT|TCSR_ENIT|TCSR_ENT|TCSR_ARHT|TCSR_UDT);
+ write_fn(TCSR_TINT|TCSR_ENIT|TCSR_ENT|TCSR_ARHT|TCSR_UDT,
+ timer_baseaddr + TCSR0);
}
-static int microblaze_timer_set_next_event(unsigned long delta,
+static int xilinx_timer_set_next_event(unsigned long delta,
struct clock_event_device *dev)
{
pr_debug("%s: next event, delta %x\n", __func__, (u32)delta);
- microblaze_timer0_start_oneshot(delta);
+ xilinx_timer0_start_oneshot(delta);
return 0;
}
-static void microblaze_timer_set_mode(enum clock_event_mode mode,
+static void xilinx_timer_set_mode(enum clock_event_mode mode,
struct clock_event_device *evt)
{
switch (mode) {
case CLOCK_EVT_MODE_PERIODIC:
pr_info("%s: periodic\n", __func__);
- microblaze_timer0_start_periodic(freq_div_hz);
+ xilinx_timer0_start_periodic(freq_div_hz);
break;
case CLOCK_EVT_MODE_ONESHOT:
pr_info("%s: oneshot\n", __func__);
@@ -127,7 +137,7 @@ static void microblaze_timer_set_mode(enum clock_event_mode mode,
break;
case CLOCK_EVT_MODE_SHUTDOWN:
pr_info("%s: shutdown\n", __func__);
- microblaze_timer0_stop();
+ xilinx_timer0_stop();
break;
case CLOCK_EVT_MODE_RESUME:
pr_info("%s: resume\n", __func__);
@@ -135,25 +145,25 @@ static void microblaze_timer_set_mode(enum clock_event_mode mode,
}
}
-static struct clock_event_device clockevent_microblaze_timer = {
- .name = "microblaze_clockevent",
+static struct clock_event_device clockevent_xilinx_timer = {
+ .name = "xilinx_clockevent",
.features = CLOCK_EVT_FEAT_ONESHOT | CLOCK_EVT_FEAT_PERIODIC,
.shift = 8,
.rating = 300,
- .set_next_event = microblaze_timer_set_next_event,
- .set_mode = microblaze_timer_set_mode,
+ .set_next_event = xilinx_timer_set_next_event,
+ .set_mode = xilinx_timer_set_mode,
};
static inline void timer_ack(void)
{
- out_be32(TIMER_BASE + TCSR0, in_be32(TIMER_BASE + TCSR0));
+ write_fn(read_fn(timer_baseaddr + TCSR0), timer_baseaddr + TCSR0);
}
static irqreturn_t timer_interrupt(int irq, void *dev_id)
{
- struct clock_event_device *evt = &clockevent_microblaze_timer;
+ struct clock_event_device *evt = &clockevent_xilinx_timer;
#ifdef CONFIG_HEART_BEAT
- heartbeat();
+ microblaze_heartbeat();
#endif
timer_ack();
evt->event_handler(evt);
@@ -162,153 +172,147 @@ static irqreturn_t timer_interrupt(int irq, void *dev_id)
static struct irqaction timer_irqaction = {
.handler = timer_interrupt,
- .flags = IRQF_DISABLED | IRQF_TIMER,
+ .flags = IRQF_TIMER,
.name = "timer",
- .dev_id = &clockevent_microblaze_timer,
+ .dev_id = &clockevent_xilinx_timer,
};
-static __init void microblaze_clockevent_init(void)
+static __init void xilinx_clockevent_init(void)
{
- clockevent_microblaze_timer.mult =
+ clockevent_xilinx_timer.mult =
div_sc(timer_clock_freq, NSEC_PER_SEC,
- clockevent_microblaze_timer.shift);
- clockevent_microblaze_timer.max_delta_ns =
- clockevent_delta2ns((u32)~0, &clockevent_microblaze_timer);
- clockevent_microblaze_timer.min_delta_ns =
- clockevent_delta2ns(1, &clockevent_microblaze_timer);
- clockevent_microblaze_timer.cpumask = cpumask_of(0);
- clockevents_register_device(&clockevent_microblaze_timer);
+ clockevent_xilinx_timer.shift);
+ clockevent_xilinx_timer.max_delta_ns =
+ clockevent_delta2ns((u32)~0, &clockevent_xilinx_timer);
+ clockevent_xilinx_timer.min_delta_ns =
+ clockevent_delta2ns(1, &clockevent_xilinx_timer);
+ clockevent_xilinx_timer.cpumask = cpumask_of(0);
+ clockevents_register_device(&clockevent_xilinx_timer);
}
-static cycle_t microblaze_read(struct clocksource *cs)
+static u64 xilinx_clock_read(void)
+{
+ return read_fn(timer_baseaddr + TCR1);
+}
+
+static cycle_t xilinx_read(struct clocksource *cs)
{
/* reading actual value of timer 1 */
- return (cycle_t) (in_be32(TIMER_BASE + TCR1));
+ return (cycle_t)xilinx_clock_read();
}
-static struct timecounter microblaze_tc = {
+static struct timecounter xilinx_tc = {
.cc = NULL,
};
-static cycle_t microblaze_cc_read(const struct cyclecounter *cc)
+static cycle_t xilinx_cc_read(const struct cyclecounter *cc)
{
- return microblaze_read(NULL);
+ return xilinx_read(NULL);
}
-static struct cyclecounter microblaze_cc = {
- .read = microblaze_cc_read,
+static struct cyclecounter xilinx_cc = {
+ .read = xilinx_cc_read,
.mask = CLOCKSOURCE_MASK(32),
.shift = 8,
};
-static int __init init_microblaze_timecounter(void)
+static int __init init_xilinx_timecounter(void)
{
- microblaze_cc.mult = div_sc(timer_clock_freq, NSEC_PER_SEC,
- microblaze_cc.shift);
+ xilinx_cc.mult = div_sc(timer_clock_freq, NSEC_PER_SEC,
+ xilinx_cc.shift);
- timecounter_init(&microblaze_tc, &microblaze_cc, sched_clock());
+ timecounter_init(&xilinx_tc, &xilinx_cc, sched_clock());
return 0;
}
static struct clocksource clocksource_microblaze = {
- .name = "microblaze_clocksource",
+ .name = "xilinx_clocksource",
.rating = 300,
- .read = microblaze_read,
+ .read = xilinx_read,
.mask = CLOCKSOURCE_MASK(32),
.flags = CLOCK_SOURCE_IS_CONTINUOUS,
};
-static int __init microblaze_clocksource_init(void)
+static int __init xilinx_clocksource_init(void)
{
if (clocksource_register_hz(&clocksource_microblaze, timer_clock_freq))
panic("failed to register clocksource");
/* stop timer1 */
- out_be32(TIMER_BASE + TCSR1, in_be32(TIMER_BASE + TCSR1) & ~TCSR_ENT);
+ write_fn(read_fn(timer_baseaddr + TCSR1) & ~TCSR_ENT,
+ timer_baseaddr + TCSR1);
/* start timer1 - up counting without interrupt */
- out_be32(TIMER_BASE + TCSR1, TCSR_TINT|TCSR_ENT|TCSR_ARHT);
+ write_fn(TCSR_TINT|TCSR_ENT|TCSR_ARHT, timer_baseaddr + TCSR1);
/* register timecounter - for ftrace support */
- init_microblaze_timecounter();
+ init_xilinx_timecounter();
return 0;
}
-/*
- * We have to protect accesses before timer initialization
- * and return 0 for sched_clock function below.
- */
-static int timer_initialized;
-
-void __init time_init(void)
+static void __init xilinx_timer_init(struct device_node *timer)
{
+ struct clk *clk;
+ static int initialized;
u32 irq;
u32 timer_num = 1;
- struct device_node *timer = NULL;
- const void *prop;
-#ifdef CONFIG_SELFMOD_TIMER
- unsigned int timer_baseaddr = 0;
- int arr_func[] = {
- (int)&microblaze_read,
- (int)&timer_interrupt,
- (int)&microblaze_clocksource_init,
- (int)&microblaze_timer_set_mode,
- (int)&microblaze_timer_set_next_event,
- 0
- };
-#endif
- prop = of_get_property(of_chosen, "system-timer", NULL);
- if (prop)
- timer = of_find_node_by_phandle(be32_to_cpup(prop));
- else
- pr_info("No chosen timer found, using default\n");
-
- if (!timer)
- timer = of_find_compatible_node(NULL, NULL,
- "xlnx,xps-timer-1.00.a");
- BUG_ON(!timer);
-
- timer_baseaddr = be32_to_cpup(of_get_property(timer, "reg", NULL));
- timer_baseaddr = (unsigned long) ioremap(timer_baseaddr, PAGE_SIZE);
+
+ if (initialized)
+ return;
+
+ initialized = 1;
+
+ timer_baseaddr = of_iomap(timer, 0);
+ if (!timer_baseaddr) {
+ pr_err("ERROR: invalid timer base address\n");
+ BUG();
+ }
+
+ write_fn = timer_write32;
+ read_fn = timer_read32;
+
+ write_fn(TCSR_MDT, timer_baseaddr + TCSR0);
+ if (!(read_fn(timer_baseaddr + TCSR0) & TCSR_MDT)) {
+ write_fn = timer_write32_be;
+ read_fn = timer_read32_be;
+ }
+
irq = irq_of_parse_and_map(timer, 0);
- timer_num = be32_to_cpup(of_get_property(timer,
- "xlnx,one-timer-only", NULL));
+
+ of_property_read_u32(timer, "xlnx,one-timer-only", &timer_num);
if (timer_num) {
- pr_emerg("Please enable two timers in HW\n");
+ pr_emerg("Please enable two timers in HW\n");
BUG();
}
-#ifdef CONFIG_SELFMOD_TIMER
- selfmod_function((int *) arr_func, timer_baseaddr);
-#endif
- pr_info("%s #0 at 0x%08x, irq=%d\n",
- timer->name, timer_baseaddr, irq);
-
- /* If there is clock-frequency property than use it */
- prop = of_get_property(timer, "clock-frequency", NULL);
- if (prop)
- timer_clock_freq = be32_to_cpup(prop);
- else
+ pr_info("%s: irq=%d\n", timer->full_name, irq);
+
+ clk = of_clk_get(timer, 0);
+ if (IS_ERR(clk)) {
+ pr_err("ERROR: timer CCF input clock not found\n");
+ /* If there is clock-frequency property than use it */
+ of_property_read_u32(timer, "clock-frequency",
+ &timer_clock_freq);
+ } else {
+ timer_clock_freq = clk_get_rate(clk);
+ }
+
+ if (!timer_clock_freq) {
+ pr_err("ERROR: Using CPU clock frequency\n");
timer_clock_freq = cpuinfo.cpu_clock_freq;
+ }
freq_div_hz = timer_clock_freq / HZ;
setup_irq(irq, &timer_irqaction);
#ifdef CONFIG_HEART_BEAT
- setup_heartbeat();
+ microblaze_setup_heartbeat();
#endif
- microblaze_clocksource_init();
- microblaze_clockevent_init();
- timer_initialized = 1;
-}
+ xilinx_clocksource_init();
+ xilinx_clockevent_init();
-unsigned long long notrace sched_clock(void)
-{
- if (timer_initialized) {
- struct clocksource *cs = &clocksource_microblaze;
-
- cycle_t cyc = cnt32_to_63(cs->read(NULL)) & LLONG_MAX;
- return clocksource_cyc2ns(cyc, cs->mult, cs->shift);
- }
- return 0;
+ sched_clock_register(xilinx_clock_read, 32, timer_clock_freq);
}
+
+CLOCKSOURCE_OF_DECLARE(xilinx_timer, "xlnx,xps-timer-1.00.a",
+ xilinx_timer_init);
diff --git a/arch/microblaze/kernel/traps.c b/arch/microblaze/kernel/traps.c
index 5541ac55959..cb619533a19 100644
--- a/arch/microblaze/kernel/traps.c
+++ b/arch/microblaze/kernel/traps.c
@@ -8,9 +8,9 @@
* for more details.
*/
+#include <linux/export.h>
#include <linux/kernel.h>
#include <linux/kallsyms.h>
-#include <linux/module.h>
#include <linux/sched.h>
#include <linux/debug_locks.h>
@@ -26,7 +26,7 @@ static unsigned long kstack_depth_to_print; /* 0 == entire stack */
static int __init kstack_setup(char *s)
{
- return !strict_strtoul(s, 0, &kstack_depth_to_print);
+ return !kstrtoul(s, 0, &kstack_depth_to_print);
}
__setup("kstack=", kstack_setup);
@@ -66,9 +66,7 @@ void show_stack(struct task_struct *task, unsigned long *sp)
}
print_hex_dump(KERN_INFO, "", DUMP_PREFIX_ADDRESS, 32, 4, (void *)fp,
words_to_show << 2, 0);
- printk(KERN_INFO "\n\n");
-
- pr_info("Call Trace:\n");
+ pr_info("\n\nCall Trace:\n");
microblaze_unwind(task, NULL);
pr_info("\n");
@@ -77,9 +75,3 @@ void show_stack(struct task_struct *task, unsigned long *sp)
debug_show_held_locks(task);
}
-
-void dump_stack(void)
-{
- show_stack(NULL, NULL);
-}
-EXPORT_SYMBOL(dump_stack);
diff --git a/arch/microblaze/kernel/unwind.c b/arch/microblaze/kernel/unwind.c
index 6be4ae3c335..1f7b8d44966 100644
--- a/arch/microblaze/kernel/unwind.c
+++ b/arch/microblaze/kernel/unwind.c
@@ -13,13 +13,13 @@
*/
/* #define DEBUG 1 */
+#include <linux/export.h>
#include <linux/kallsyms.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/stacktrace.h>
#include <linux/types.h>
#include <linux/errno.h>
-#include <linux/module.h>
#include <linux/io.h>
#include <asm/sections.h>
#include <asm/exceptions.h>
diff --git a/arch/microblaze/kernel/vmlinux.lds.S b/arch/microblaze/kernel/vmlinux.lds.S
index 936d01a689d..be9488d6973 100644
--- a/arch/microblaze/kernel/vmlinux.lds.S
+++ b/arch/microblaze/kernel/vmlinux.lds.S
@@ -51,6 +51,7 @@ SECTIONS {
. = ALIGN(16);
RODATA
EXCEPTION_TABLE(16)
+ NOTES
/*
* sdata2 section can go anywhere, but must be word aligned