summary refs log tree commit diff
path: root/arch/microblaze
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-09-06 10:58:34 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2013-09-06 10:58:34 -0700
commit5872c84027fdcc982e8109ca26d11e1117995745 (patch)
treef4b59f792a24526c0d2f1ffe3fa8d743b5693f1d /arch/microblaze
parent39eda2aba6be642b71f2e0ad623dcb09fd9d79cf (diff)
parent54ea21f0785fd01fb3279d42fe6670cef64cf648 (diff)
downloadlinux-5872c84027fdcc982e8109ca26d11e1117995745.tar.gz
Merge tag 'microblaze-3.12-rc1' of git://git.monstr.eu/linux-2.6-microblaze
Pull Microblaze patches from Michal Simek:
 - PCI fixes
 - Selfmod code removing
 - Intc and timer fixes
 - Adding new MB versions
 - Minor fixes

* tag 'microblaze-3.12-rc1' of git://git.monstr.eu/linux-2.6-microblaze:
  microblaze: Show message when reset gpio is not present
  microblaze: Add linux.bin.ub target
  microblaze: Add PVR version string for MB v9.0 and v9.1
  microblaze: timer: Replace microblaze_ prefix by xilinx_
  microblaze: timer: Update header
  microblaze: timer: Remove unused header
  microblaze: timer: Clear driver init function
  microblaze: timer: Use CLKSRC_OF initialization
  microblaze: intc: Remove unused header
  microblaze: intc: Clean driver init function
  microblaze: intc: Using irqchip
  microblaze: intc: Update header
  microblaze: intc: Remove unused headers
  microblaze: Remove selfmodified feature
  of/pci: Use of_pci_range_parser
Diffstat (limited to 'arch/microblaze')
-rw-r--r--arch/microblaze/Kconfig1
-rw-r--r--arch/microblaze/Makefile3
-rw-r--r--arch/microblaze/boot/Makefile7
-rw-r--r--arch/microblaze/include/asm/selfmod.h24
-rw-r--r--arch/microblaze/kernel/Makefile2
-rw-r--r--arch/microblaze/kernel/cpu/cpuinfo.c2
-rw-r--r--arch/microblaze/kernel/intc.c85
-rw-r--r--arch/microblaze/kernel/irq.c10
-rw-r--r--arch/microblaze/kernel/reset.c6
-rw-r--r--arch/microblaze/kernel/selfmod.c81
-rw-r--r--arch/microblaze/kernel/setup.c10
-rw-r--r--arch/microblaze/kernel/timer.c186
-rw-r--r--arch/microblaze/pci/pci-common.c106
-rw-r--r--arch/microblaze/platform/Kconfig.platform22
14 files changed, 178 insertions, 367 deletions
diff --git a/arch/microblaze/Kconfig b/arch/microblaze/Kconfig
index 4fab52294d98..3f6659cbc969 100644
--- a/arch/microblaze/Kconfig
+++ b/arch/microblaze/Kconfig
@@ -29,6 +29,7 @@ config MICROBLAZE
 	select GENERIC_IDLE_POLL_SETUP
 	select MODULES_USE_ELF_RELA
 	select CLONE_BACKWARDS3
+	select CLKSRC_OF
 
 config SWAP
 	def_bool n
diff --git a/arch/microblaze/Makefile b/arch/microblaze/Makefile
index 0a603d3ecf24..40350a3c24e9 100644
--- a/arch/microblaze/Makefile
+++ b/arch/microblaze/Makefile
@@ -72,7 +72,7 @@ all: linux.bin
 archclean:
 	$(Q)$(MAKE) $(clean)=$(boot)
 
-linux.bin linux.bin.gz: vmlinux
+linux.bin linux.bin.gz linux.bin.ub: vmlinux
 	$(Q)$(MAKE) $(build)=$(boot) $(boot)/$@
 
 simpleImage.%: vmlinux
@@ -81,6 +81,7 @@ simpleImage.%: vmlinux
 define archhelp
   echo '* linux.bin    - Create raw binary'
   echo '  linux.bin.gz - Create compressed raw binary'
+  echo '  linux.bin.ub - Create U-Boot wrapped raw binary'
   echo '  simpleImage.<dt> - ELF image with $(arch)/boot/dts/<dt>.dts linked in'
   echo '                   - stripped elf with fdt blob'
   echo '  simpleImage.<dt>.unstrip - full ELF image with fdt blob'
diff --git a/arch/microblaze/boot/Makefile b/arch/microblaze/boot/Makefile
index 80fe54fb7ca3..8e211cc28dac 100644
--- a/arch/microblaze/boot/Makefile
+++ b/arch/microblaze/boot/Makefile
@@ -2,12 +2,15 @@
 # arch/microblaze/boot/Makefile
 #
 
-targets := linux.bin linux.bin.gz simpleImage.%
+targets := linux.bin linux.bin.gz linux.bin.ub simpleImage.%
 
 OBJCOPYFLAGS := -R .note -R .comment -R .note.gnu.build-id -O binary
 
 $(obj)/linux.bin: vmlinux FORCE
 	$(call if_changed,objcopy)
+	@echo 'Kernel: $@ is ready' ' (#'`cat .version`')'
+
+$(obj)/linux.bin.ub: $(obj)/linux.bin FORCE
 	$(call if_changed,uimage)
 	@echo 'Kernel: $@ is ready' ' (#'`cat .version`')'
 
@@ -22,8 +25,6 @@ quiet_cmd_strip = STRIP   $@
 	cmd_strip = $(STRIP) -K microblaze_start -K _end -K __log_buf \
 				-K _fdt_start vmlinux -o $@
 
-UIMAGE_IN = $@
-UIMAGE_OUT = $@.ub
 UIMAGE_LOADADDR = $(CONFIG_KERNEL_BASE_ADDR)
 
 $(obj)/simpleImage.%: vmlinux FORCE
diff --git a/arch/microblaze/include/asm/selfmod.h b/arch/microblaze/include/asm/selfmod.h
deleted file mode 100644
index c42aff2e6cd0..000000000000
--- a/arch/microblaze/include/asm/selfmod.h
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Copyright (C) 2007-2008 Michal Simek <monstr@monstr.eu>
- *
- * 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.
- */
-
-#ifndef _ASM_MICROBLAZE_SELFMOD_H
-#define _ASM_MICROBLAZE_SELFMOD_H
-
-/*
- * BARRIER_BASE_ADDR is constant address for selfmod function.
- * do not change this value - selfmod function is in
- * arch/microblaze/kernel/selfmod.c: selfmod_function()
- *
- * last 16 bits is used for storing register offset
- */
-
-#define BARRIER_BASE_ADDR	0x1234ff00
-
-void selfmod_function(const int *arr_fce, const unsigned int base);
-
-#endif /* _ASM_MICROBLAZE_SELFMOD_H */
diff --git a/arch/microblaze/kernel/Makefile b/arch/microblaze/kernel/Makefile
index 928c950fc14c..5b0e512c78e5 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
@@ -23,7 +22,6 @@ obj-y += dma.o exceptions.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/cpuinfo.c b/arch/microblaze/kernel/cpu/cpuinfo.c
index 410398f6db55..c9203b1007aa 100644
--- a/arch/microblaze/kernel/cpu/cpuinfo.c
+++ b/arch/microblaze/kernel/cpu/cpuinfo.c
@@ -39,6 +39,8 @@ const struct cpu_ver_key cpu_ver_lookup[] = {
 	{"8.30.a", 0x17},
 	{"8.40.a", 0x18},
 	{"8.40.b", 0x19},
+	{"9.0", 0x1b},
+	{"9.1", 0x1d},
 	{NULL, 0},
 };
 
diff --git a/arch/microblaze/kernel/intc.c b/arch/microblaze/kernel/intc.c
index d85fa3a2b0f8..581451ad4687 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 */
@@ -50,21 +43,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);
+		out_be32(intc_baseaddr + IAR, mask);
 
-	out_be32(INTC_BASE + SIE, mask);
+	out_be32(intc_baseaddr + SIE, mask);
 }
 
 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);
+	out_be32(intc_baseaddr + CIE, 1 << d->hwirq);
 }
 
 static void intc_ack(struct irq_data *d)
 {
 	pr_debug("ack: %ld\n", d->hwirq);
-	out_be32(INTC_BASE + IAR, 1 << d->hwirq);
+	out_be32(intc_baseaddr + IAR, 1 << d->hwirq);
 }
 
 static void intc_mask_ack(struct irq_data *d)
@@ -72,8 +65,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);
+	out_be32(intc_baseaddr + CIE, mask);
+	out_be32(intc_baseaddr + IAR, mask);
 }
 
 static struct irq_chip intc_dev = {
@@ -90,7 +83,7 @@ unsigned int get_irq(void)
 {
 	unsigned int hwirq, irq = -1;
 
-	hwirq = in_be32(INTC_BASE + IVR);
+	hwirq = in_be32(intc_baseaddr + IVR);
 	if (hwirq != -1U)
 		irq = irq_find_mapping(root_domain, hwirq);
 
@@ -120,40 +113,32 @@ 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))
 		pr_info(" ERROR: Mismatch in kind-of-intr param\n");
 
-#ifdef CONFIG_SELFMOD_INTC
-	selfmod_function((int *) arr_func, intc_baseaddr);
-#endif
-	pr_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);
 
 	/*
 	 * Disable all external interrupts until they are
@@ -174,4 +159,8 @@ void __init init_IRQ(void)
 							(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 ace700afbfdf..11e24de91aa4 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/reset.c b/arch/microblaze/kernel/reset.c
index 2e5079ab53d2..fbe58c6554a8 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 89508bdc9f3c..000000000000
--- 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 0263da7b83dd..0775e036c526 100644
--- a/arch/microblaze/kernel/setup.c
+++ b/arch/microblaze/kernel/setup.c
@@ -9,6 +9,7 @@
  */
 
 #include <linux/init.h>
+#include <linux/clocksource.h>
 #include <linux/string.h>
 #include <linux/seq_file.h>
 #include <linux/cpu.h>
@@ -68,10 +69,6 @@ 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;
@@ -196,6 +193,11 @@ void __init machine_early_init(const char *cmdline, unsigned int ram,
 	per_cpu(CURRENT_SAVE, 0) = (unsigned long)current;
 }
 
+void __init time_init(void)
+{
+	clocksource_of_init();
+}
+
 #ifdef CONFIG_DEBUG_FS
 struct dentry *of_debugfs_root;
 
diff --git a/arch/microblaze/kernel/timer.c b/arch/microblaze/kernel/timer.c
index aec5020a6e31..e4b3f33ef34c 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,16 @@
  * 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/clk.h>
-#include <linux/clocksource.h>
 #include <linux/clockchips.h>
-#include <linux/io.h>
-#include <linux/bug.h>
+#include <linux/of_address.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 +42,21 @@ static unsigned int timer_clock_freq;
 #define TCSR_PWMA	(1<<9)
 #define TCSR_ENALL	(1<<10)
 
-static inline void microblaze_timer0_stop(void)
+static inline void xilinx_timer0_stop(void)
 {
-	out_be32(TIMER_BASE + TCSR0, in_be32(TIMER_BASE + TCSR0) & ~TCSR_ENT);
+	out_be32(timer_baseaddr + TCSR0,
+		 in_be32(timer_baseaddr + TCSR0) & ~TCSR_ENT);
 }
 
-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 */
+	out_be32(timer_baseaddr + TLR0, load_val);
 
 	/* load the initial value */
-	out_be32(TIMER_BASE + TCSR0, TCSR_LOAD);
+	out_be32(timer_baseaddr + TCSR0, TCSR_LOAD);
 
 	/* see timer data sheet for detail
 	 * !ENALL - don't enable 'em all
@@ -86,38 +71,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,
+	out_be32(timer_baseaddr + TCSR0,
 			TCSR_TINT|TCSR_ENIT|TCSR_ENT|TCSR_ARHT|TCSR_UDT);
 }
 
-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 */
+	out_be32(timer_baseaddr + TLR0, load_val);
 
 	/* load the initial value */
-	out_be32(TIMER_BASE + TCSR0, TCSR_LOAD);
+	out_be32(timer_baseaddr + TCSR0, TCSR_LOAD);
 
-	out_be32(TIMER_BASE + TCSR0,
+	out_be32(timer_baseaddr + TCSR0,
 			TCSR_TINT|TCSR_ENIT|TCSR_ENT|TCSR_ARHT|TCSR_UDT);
 }
 
-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 +113,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,23 +121,23 @@ 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));
+	out_be32(timer_baseaddr + TCSR0, in_be32(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();
 #endif
@@ -164,73 +150,74 @@ static struct irqaction timer_irqaction = {
 	.handler = timer_interrupt,
 	.flags = IRQF_DISABLED | 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 cycle_t xilinx_read(struct clocksource *cs)
 {
 	/* reading actual value of timer 1 */
-	return (cycle_t) (in_be32(TIMER_BASE + TCR1));
+	return (cycle_t) (in_be32(timer_baseaddr + TCR1));
 }
 
-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);
+	out_be32(timer_baseaddr + TCSR1,
+		 in_be32(timer_baseaddr + TCSR1) & ~TCSR_ENT);
 	/* start timer1 - up counting without interrupt */
-	out_be32(TIMER_BASE + TCSR1, TCSR_TINT|TCSR_ENT|TCSR_ARHT);
+	out_be32(timer_baseaddr + TCSR1, TCSR_TINT|TCSR_ENT|TCSR_ARHT);
 
 	/* register timecounter - for ftrace support */
-	init_microblaze_timecounter();
+	init_xilinx_timecounter();
 	return 0;
 }
 
@@ -240,55 +227,31 @@ static int __init microblaze_clocksource_init(void)
  */
 static int timer_initialized;
 
-void __init time_init(void)
+static void __init xilinx_timer_init(struct device_node *timer)
 {
 	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);
+	int ret;
+
+	timer_baseaddr = of_iomap(timer, 0);
+	if (!timer_baseaddr) {
+		pr_err("ERROR: invalid timer base address\n");
+		BUG();
+	}
+
 	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);
+	pr_info("%s: irq=%d\n", timer->full_name, 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
+	ret = of_property_read_u32(timer, "clock-frequency", &timer_clock_freq);
+	if (ret < 0)
 		timer_clock_freq = cpuinfo.cpu_clock_freq;
 
 	freq_div_hz = timer_clock_freq / HZ;
@@ -297,8 +260,8 @@ void __init time_init(void)
 #ifdef CONFIG_HEART_BEAT
 	setup_heartbeat();
 #endif
-	microblaze_clocksource_init();
-	microblaze_clockevent_init();
+	xilinx_clocksource_init();
+	xilinx_clockevent_init();
 	timer_initialized = 1;
 }
 
@@ -312,3 +275,6 @@ unsigned long long notrace sched_clock(void)
 	}
 	return 0;
 }
+
+CLOCKSOURCE_OF_DECLARE(xilinx_timer, "xlnx,xps-timer-1.00.a",
+		       xilinx_timer_init);
diff --git a/arch/microblaze/pci/pci-common.c b/arch/microblaze/pci/pci-common.c
index bdb8ea100e73..1b93bf0892a0 100644
--- a/arch/microblaze/pci/pci-common.c
+++ b/arch/microblaze/pci/pci-common.c
@@ -657,67 +657,42 @@ void pci_resource_to_user(const struct pci_dev *dev, int bar,
 void pci_process_bridge_OF_ranges(struct pci_controller *hose,
 				  struct device_node *dev, int primary)
 {
-	const u32 *ranges;
-	int rlen;
-	int pna = of_n_addr_cells(dev);
-	int np = pna + 5;
 	int memno = 0, isa_hole = -1;
-	u32 pci_space;
-	unsigned long long pci_addr, cpu_addr, pci_next, cpu_next, size;
 	unsigned long long isa_mb = 0;
 	struct resource *res;
+	struct of_pci_range range;
+	struct of_pci_range_parser parser;
 
 	pr_info("PCI host bridge %s %s ranges:\n",
 	       dev->full_name, primary ? "(primary)" : "");
 
-	/* Get ranges property */
-	ranges = of_get_property(dev, "ranges", &rlen);
-	if (ranges == NULL)
+	/* Check for ranges property */
+	if (of_pci_range_parser_init(&parser, dev))
 		return;
 
-	/* Parse it */
 	pr_debug("Parsing ranges property...\n");
-	while ((rlen -= np * 4) >= 0) {
+	for_each_of_pci_range(&parser, &range) {
 		/* Read next ranges element */
-		pci_space = ranges[0];
-		pci_addr = of_read_number(ranges + 1, 2);
-		cpu_addr = of_translate_address(dev, ranges + 3);
-		size = of_read_number(ranges + pna + 3, 2);
-
 		pr_debug("pci_space: 0x%08x pci_addr:0x%016llx ",
-				pci_space, pci_addr);
+				range.pci_space, range.pci_addr);
 		pr_debug("cpu_addr:0x%016llx size:0x%016llx\n",
-					cpu_addr, size);
-
-		ranges += np;
+					range.cpu_addr, range.size);
 
 		/* If we failed translation or got a zero-sized region
 		 * (some FW try to feed us with non sensical zero sized regions
 		 * such as power3 which look like some kind of attempt
 		 * at exposing the VGA memory hole)
 		 */
-		if (cpu_addr == OF_BAD_ADDR || size == 0)
+		if (range.cpu_addr == OF_BAD_ADDR || range.size == 0)
 			continue;
 
-		/* Now consume following elements while they are contiguous */
-		for (; rlen >= np * sizeof(u32);
-		     ranges += np, rlen -= np * 4) {
-			if (ranges[0] != pci_space)
-				break;
-			pci_next = of_read_number(ranges + 1, 2);
-			cpu_next = of_translate_address(dev, ranges + 3);
-			if (pci_next != pci_addr + size ||
-			    cpu_next != cpu_addr + size)
-				break;
-			size += of_read_number(ranges + pna + 3, 2);
-		}
-
 		/* Act based on address space type */
 		res = NULL;
-		switch ((pci_space >> 24) & 0x3) {
-		case 1:		/* PCI IO space */
+		switch (range.flags & IORESOURCE_TYPE_BITS) {
+		case IORESOURCE_IO:
 			pr_info("  IO 0x%016llx..0x%016llx -> 0x%016llx\n",
-			       cpu_addr, cpu_addr + size - 1, pci_addr);
+				range.cpu_addr, range.cpu_addr + range.size - 1,
+				range.pci_addr);
 
 			/* We support only one IO range */
 			if (hose->pci_io_size) {
@@ -725,11 +700,12 @@ void pci_process_bridge_OF_ranges(struct pci_controller *hose,
 				continue;
 			}
 			/* On 32 bits, limit I/O space to 16MB */
-			if (size > 0x01000000)
-				size = 0x01000000;
+			if (range.size > 0x01000000)
+				range.size = 0x01000000;
 
 			/* 32 bits needs to map IOs here */
-			hose->io_base_virt = ioremap(cpu_addr, size);
+			hose->io_base_virt = ioremap(range.cpu_addr,
+						range.size);
 
 			/* Expect trouble if pci_addr is not 0 */
 			if (primary)
@@ -738,19 +714,20 @@ void pci_process_bridge_OF_ranges(struct pci_controller *hose,
 			/* pci_io_size and io_base_phys always represent IO
 			 * space starting at 0 so we factor in pci_addr
 			 */
-			hose->pci_io_size = pci_addr + size;
-			hose->io_base_phys = cpu_addr - pci_addr;
+			hose->pci_io_size = range.pci_addr + range.size;
+			hose->io_base_phys = range.cpu_addr - range.pci_addr;
 
 			/* Build resource */
 			res = &hose->io_resource;
-			res->flags = IORESOURCE_IO;
-			res->start = pci_addr;
+			range.cpu_addr = range.pci_addr;
+
 			break;
-		case 2:		/* PCI Memory space */
-		case 3:		/* PCI 64 bits Memory space */
+		case IORESOURCE_MEM:
 			pr_info(" MEM 0x%016llx..0x%016llx -> 0x%016llx %s\n",
-			       cpu_addr, cpu_addr + size - 1, pci_addr,
-			       (pci_space & 0x40000000) ? "Prefetch" : "");
+				range.cpu_addr, range.cpu_addr + range.size - 1,
+				range.pci_addr,
+				(range.pci_space & 0x40000000) ?
+				"Prefetch" : "");
 
 			/* We support only 3 memory ranges */
 			if (memno >= 3) {
@@ -758,13 +735,13 @@ void pci_process_bridge_OF_ranges(struct pci_controller *hose,
 				continue;
 			}
 			/* Handles ISA memory hole space here */
-			if (pci_addr == 0) {
-				isa_mb = cpu_addr;
+			if (range.pci_addr == 0) {
+				isa_mb = range.cpu_addr;
 				isa_hole = memno;
 				if (primary || isa_mem_base == 0)
-					isa_mem_base = cpu_addr;
-				hose->isa_mem_phys = cpu_addr;
-				hose->isa_mem_size = size;
+					isa_mem_base = range.cpu_addr;
+				hose->isa_mem_phys = range.cpu_addr;
+				hose->isa_mem_size = range.size;
 			}
 
 			/* We get the PCI/Mem offset from the first range or
@@ -772,30 +749,23 @@ void pci_process_bridge_OF_ranges(struct pci_controller *hose,
 			 * hole. If they don't match, bugger.
 			 */
 			if (memno == 0 ||
-			    (isa_hole >= 0 && pci_addr != 0 &&
+			    (isa_hole >= 0 && range.pci_addr != 0 &&
 			     hose->pci_mem_offset == isa_mb))
-				hose->pci_mem_offset = cpu_addr - pci_addr;
-			else if (pci_addr != 0 &&
-				 hose->pci_mem_offset != cpu_addr - pci_addr) {
+				hose->pci_mem_offset = range.cpu_addr -
+							range.pci_addr;
+			else if (range.pci_addr != 0 &&
+				 hose->pci_mem_offset != range.cpu_addr -
+							range.pci_addr) {
 				pr_info(" \\--> Skipped (offset mismatch) !\n");
 				continue;
 			}
 
 			/* Build resource */
 			res = &hose->mem_resources[memno++];
-			res->flags = IORESOURCE_MEM;
-			if (pci_space & 0x40000000)
-				res->flags |= IORESOURCE_PREFETCH;
-			res->start = cpu_addr;
 			break;
 		}
-		if (res != NULL) {
-			res->name = dev->full_name;
-			res->end = res->start + size - 1;
-			res->parent = NULL;
-			res->sibling = NULL;
-			res->child = NULL;
-		}
+		if (res != NULL)
+			of_pci_range_to_resource(&range, dev, res);
 	}
 
 	/* If there's an ISA hole and the pci_mem_offset is -not- matching
diff --git a/arch/microblaze/platform/Kconfig.platform b/arch/microblaze/platform/Kconfig.platform
index b1747211b8b1..db1aa5c22cea 100644
--- a/arch/microblaze/platform/Kconfig.platform
+++ b/arch/microblaze/platform/Kconfig.platform
@@ -18,28 +18,6 @@ config PLATFORM_GENERIC
 
 endchoice
 
-config SELFMOD
-	bool "Use self modified code for intc/timer"
-	depends on NO_MMU
-	default n
-	help
-	  This choice enables self-modified code for interrupt controller
-	  and timer.
-
-config SELFMOD_INTC
-	bool "Use self modified code for intc"
-	depends on SELFMOD
-	default y
-	help
-	  This choice enables self-modified code for interrupt controller.
-
-config SELFMOD_TIMER
-	bool "Use self modified code for timer"
-	depends on SELFMOD
-	default y
-	help
-	  This choice enables self-modified code for timer.
-
 config OPT_LIB_FUNCTION
 	bool "Optimalized lib function"
 	default y