diff options
author | Jiri Kosina <jkosina@suse.cz> | 2013-12-19 15:08:03 +0100 |
---|---|---|
committer | Jiri Kosina <jkosina@suse.cz> | 2013-12-19 15:08:32 +0100 |
commit | e23c34bb41da65f354fb7eee04300c56ee48f60c (patch) | |
tree | 549fbe449d55273b81ef104a9755109bf4ae7817 /arch/microblaze | |
parent | b481c2cb3534c85dca625973b33eba15f9af3e4c (diff) | |
parent | 319e2e3f63c348a9b66db4667efa73178e18b17d (diff) |
Merge branch 'master' into for-next
Sync with Linus' tree to be able to apply fixes on top of newer things
in tree (efi-stub).
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
Diffstat (limited to 'arch/microblaze')
27 files changed, 225 insertions, 545 deletions
diff --git a/arch/microblaze/Kconfig b/arch/microblaze/Kconfig index 4fab52294d9..e23cccde9c2 100644 --- a/arch/microblaze/Kconfig +++ b/arch/microblaze/Kconfig @@ -1,5 +1,6 @@ config MICROBLAZE def_bool y + select ARCH_MIGHT_HAVE_PC_PARPORT select HAVE_MEMBLOCK select HAVE_MEMBLOCK_NODE_MAP select HAVE_FUNCTION_TRACER @@ -18,7 +19,6 @@ config MICROBLAZE select ARCH_WANT_IPC_PARSE_VERSION select HAVE_DEBUG_KMEMLEAK select IRQ_DOMAIN - select HAVE_GENERIC_HARDIRQS select VIRT_TO_BUS select GENERIC_IRQ_PROBE select GENERIC_IRQ_SHOW @@ -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 @@ -82,11 +83,6 @@ config MMU bool "MMU support" default n -config NO_MMU - bool - depends on !MMU - default y - comment "Boot options" config CMDLINE_BOOL @@ -250,10 +246,6 @@ config MICROBLAZE_64K_PAGES endchoice -config KERNEL_PAD - hex "Kernel PAD for unpacking" if ADVANCED_OPTIONS - default "0x80000" if MMU - endmenu source "mm/Kconfig" diff --git a/arch/microblaze/Makefile b/arch/microblaze/Makefile index 0a603d3ecf2..40350a3c24e 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 80fe54fb7ca..8e211cc28da 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/boot/dts/Makefile b/arch/microblaze/boot/dts/Makefile index c3b3a5d67b8..c4982d16e55 100644 --- a/arch/microblaze/boot/dts/Makefile +++ b/arch/microblaze/boot/dts/Makefile @@ -1,6 +1,4 @@ # -# arch/microblaze/boot/Makefile -# obj-y += linked_dtb.o diff --git a/arch/microblaze/include/asm/Kbuild b/arch/microblaze/include/asm/Kbuild index d3c51a6a601..ce0bbf8f564 100644 --- a/arch/microblaze/include/asm/Kbuild +++ b/arch/microblaze/include/asm/Kbuild @@ -3,3 +3,4 @@ generic-y += clkdev.h generic-y += exec.h generic-y += trace_clock.h generic-y += syscalls.h +generic-y += preempt.h diff --git a/arch/microblaze/include/asm/pci.h b/arch/microblaze/include/asm/pci.h index d52abb6812f..935f9bec414 100644 --- a/arch/microblaze/include/asm/pci.h +++ b/arch/microblaze/include/asm/pci.h @@ -127,8 +127,6 @@ extern void of_scan_pci_bridge(struct device_node *node, extern void of_scan_bus(struct device_node *node, struct pci_bus *bus); extern void of_rescan_bus(struct device_node *node, struct pci_bus *bus); -extern int pci_read_irq_line(struct pci_dev *dev); - extern int pci_bus_find_capability(struct pci_bus *bus, unsigned int devfn, int cap); diff --git a/arch/microblaze/include/asm/pgalloc.h b/arch/microblaze/include/asm/pgalloc.h index ebd35792482..7fdf7fabc7d 100644 --- a/arch/microblaze/include/asm/pgalloc.h +++ b/arch/microblaze/include/asm/pgalloc.h @@ -122,8 +122,13 @@ static inline struct page *pte_alloc_one(struct mm_struct *mm, #endif ptepage = alloc_pages(flags, 0); - if (ptepage) - clear_highpage(ptepage); + if (!ptepage) + return NULL; + clear_highpage(ptepage); + if (!pgtable_page_ctor(ptepage)) { + __free_page(ptepage); + return NULL; + } return ptepage; } @@ -158,8 +163,9 @@ extern inline void pte_free_slow(struct page *ptepage) __free_page(ptepage); } -extern inline void pte_free(struct mm_struct *mm, struct page *ptepage) +static inline void pte_free(struct mm_struct *mm, struct page *ptepage) { + pgtable_page_dtor(ptepage); __free_page(ptepage); } diff --git a/arch/microblaze/include/asm/prom.h b/arch/microblaze/include/asm/prom.h index 9977816c5ad..2f03ac81585 100644 --- a/arch/microblaze/include/asm/prom.h +++ b/arch/microblaze/include/asm/prom.h @@ -11,19 +11,10 @@ * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. */ - -#include <linux/of.h> /* linux/of.h gets to determine #include ordering */ - #ifndef _ASM_MICROBLAZE_PROM_H #define _ASM_MICROBLAZE_PROM_H -#ifdef __KERNEL__ -#ifndef __ASSEMBLY__ - -#include <linux/types.h> -#include <asm/irq.h> -#include <linux/atomic.h> -#define HAVE_ARCH_DEVTREE_FIXUPS +#include <linux/of.h> /* Other Prototypes */ enum early_consoles { @@ -33,32 +24,4 @@ enum early_consoles { extern int of_early_console(void *version); -/* - * OF address retreival & translation - */ - -#ifdef CONFIG_PCI -extern unsigned long pci_address_to_pio(phys_addr_t address); -#define pci_address_to_pio pci_address_to_pio -#endif /* CONFIG_PCI */ - -/* Parse the ibm,dma-window property of an OF node into the busno, phys and - * size parameters. - */ -void of_parse_dma_window(struct device_node *dn, const void *dma_window_prop, - unsigned long *busno, unsigned long *phys, unsigned long *size); - -extern void kdump_move_device_tree(void); - -#endif /* __ASSEMBLY__ */ -#endif /* __KERNEL__ */ - -/* These includes are put at the bottom because they may contain things - * that are overridden by this file. Ideally they shouldn't be included - * by this file, but there are a bunch of .c files that currently depend - * on it. Eventually they will be cleaned up. */ -#include <linux/of_fdt.h> -#include <linux/of_irq.h> -#include <linux/platform_device.h> - #endif /* _ASM_MICROBLAZE_PROM_H */ diff --git a/arch/microblaze/include/asm/selfmod.h b/arch/microblaze/include/asm/selfmod.h deleted file mode 100644 index c42aff2e6cd..00000000000 --- 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/include/asm/thread_info.h b/arch/microblaze/include/asm/thread_info.h index de26ea6373d..8c9d36591a0 100644 --- a/arch/microblaze/include/asm/thread_info.h +++ b/arch/microblaze/include/asm/thread_info.h @@ -106,8 +106,6 @@ static inline struct thread_info *current_thread_info(void) /* thread information allocation */ #endif /* __ASSEMBLY__ */ -#define PREEMPT_ACTIVE 0x10000000 - /* * thread information flags * - these are process state flags that various assembly files may diff --git a/arch/microblaze/kernel/Makefile b/arch/microblaze/kernel/Makefile index 928c950fc14..5b0e512c78e 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 410398f6db5..c9203b1007a 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/head.S b/arch/microblaze/kernel/head.S index fcc797feb9d..817b7eec95b 100644 --- a/arch/microblaze/kernel/head.S +++ b/arch/microblaze/kernel/head.S @@ -176,7 +176,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 */ diff --git a/arch/microblaze/kernel/hw_exception_handler.S b/arch/microblaze/kernel/hw_exception_handler.S index 61b3a1fed46..fc6b89f4dd3 100644 --- a/arch/microblaze/kernel/hw_exception_handler.S +++ b/arch/microblaze/kernel/hw_exception_handler.S @@ -193,8 +193,8 @@ * - W S REG EXC * * - * STACK FRAME STRUCTURE (for NO_MMU) - * --------------------------------- + * STACK FRAME STRUCTURE (for CONFIG_MMU=n) + * ---------------------------------------- * * +-------------+ + 0 * | MSR | diff --git a/arch/microblaze/kernel/intc.c b/arch/microblaze/kernel/intc.c index d85fa3a2b0f..581451ad468 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 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/prom.c b/arch/microblaze/kernel/prom.c index 0a2c68f9f9b..abdfb10e7ec 100644 --- a/arch/microblaze/kernel/prom.c +++ b/arch/microblaze/kernel/prom.c @@ -30,6 +30,7 @@ #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,16 +42,6 @@ #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; @@ -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; + early_init_dt_scan(params); + if (!strlen(boot_command_line)) + strlcpy(boot_command_line, cmd_line, COMMAND_LINE_SIZE); - /* 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); - - /* 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(); @@ -135,16 +115,6 @@ 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 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 0263da7b83d..8de8ebc309f 100644 --- a/arch/microblaze/kernel/setup.c +++ b/arch/microblaze/kernel/setup.c @@ -9,12 +9,14 @@ */ #include <linux/init.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 +51,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,10 +70,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 +194,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/sys_microblaze.c b/arch/microblaze/kernel/sys_microblaze.c index f905b3ae68c..f1e1f666ddd 100644 --- a/arch/microblaze/kernel/sys_microblaze.c +++ b/arch/microblaze/kernel/sys_microblaze.c @@ -33,12 +33,23 @@ #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..b882ad50535 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 */ diff --git a/arch/microblaze/kernel/timer.c b/arch/microblaze/kernel/timer.c index aec5020a6e3..3e39b1082fd 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/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,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 +72,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 +114,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 +122,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 @@ -162,75 +149,76 @@ 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 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(µblaze_tc, µblaze_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 +228,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)µblaze_read, - (int)&timer_interrupt, - (int)µblaze_clocksource_init, - (int)µblaze_timer_set_mode, - (int)µblaze_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 +261,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 +276,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/mm/consistent.c b/arch/microblaze/mm/consistent.c index 5226b09cbbb..dbbf2246a26 100644 --- a/arch/microblaze/mm/consistent.c +++ b/arch/microblaze/mm/consistent.c @@ -176,8 +176,7 @@ void consistent_free(size_t size, void *vaddr) page = virt_to_page(vaddr); do { - ClearPageReserved(page); - __free_page(page); + __free_reserved_page(page); page++; } while (size -= PAGE_SIZE); #else @@ -194,9 +193,7 @@ void consistent_free(size_t size, void *vaddr) pte_clear(&init_mm, (unsigned int)vaddr, ptep); if (pfn_valid(pfn)) { page = pfn_to_page(pfn); - - ClearPageReserved(page); - __free_page(page); + __free_reserved_page(page); } } vaddr += PAGE_SIZE; diff --git a/arch/microblaze/mm/fault.c b/arch/microblaze/mm/fault.c index 731f739d17a..fa4cf52aa7a 100644 --- a/arch/microblaze/mm/fault.c +++ b/arch/microblaze/mm/fault.c @@ -92,8 +92,7 @@ void do_page_fault(struct pt_regs *regs, unsigned long address, int code = SEGV_MAPERR; int is_write = error_code & ESR_S; int fault; - unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE | - (is_write ? FAULT_FLAG_WRITE : 0); + unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE; regs->ear = address; regs->esr = error_code; @@ -121,6 +120,9 @@ void do_page_fault(struct pt_regs *regs, unsigned long address, die("Weird page fault", regs, SIGSEGV); } + if (user_mode(regs)) + flags |= FAULT_FLAG_USER; + /* When running in the kernel we expect faults to occur only to * addresses in user space. All other faults represent errors in the * kernel and should generate an OOPS. Unfortunately, in the case of an @@ -199,6 +201,7 @@ good_area: if (unlikely(is_write)) { if (unlikely(!(vma->vm_flags & VM_WRITE))) goto bad_area; + flags |= FAULT_FLAG_WRITE; /* a read */ } else { /* protection fault */ diff --git a/arch/microblaze/pci/pci-common.c b/arch/microblaze/pci/pci-common.c index bdb8ea100e7..66804adcacf 100644 --- a/arch/microblaze/pci/pci-common.c +++ b/arch/microblaze/pci/pci-common.c @@ -29,6 +29,7 @@ #include <linux/slab.h> #include <linux/of.h> #include <linux/of_address.h> +#include <linux/of_irq.h> #include <linux/of_pci.h> #include <linux/export.h> @@ -193,76 +194,6 @@ void pcibios_set_master(struct pci_dev *dev) } /* - * Reads the interrupt pin to determine if interrupt is use by card. - * If the interrupt is used, then gets the interrupt line from the - * openfirmware and sets it in the pci_dev and pci_config line. - */ -int pci_read_irq_line(struct pci_dev *pci_dev) -{ - struct of_irq oirq; - unsigned int virq; - - /* The current device-tree that iSeries generates from the HV - * PCI informations doesn't contain proper interrupt routing, - * and all the fallback would do is print out crap, so we - * don't attempt to resolve the interrupts here at all, some - * iSeries specific fixup does it. - * - * In the long run, we will hopefully fix the generated device-tree - * instead. - */ - pr_debug("PCI: Try to map irq for %s...\n", pci_name(pci_dev)); - -#ifdef DEBUG - memset(&oirq, 0xff, sizeof(oirq)); -#endif - /* Try to get a mapping from the device-tree */ - if (of_irq_map_pci(pci_dev, &oirq)) { - u8 line, pin; - - /* If that fails, lets fallback to what is in the config - * space and map that through the default controller. We - * also set the type to level low since that's what PCI - * interrupts are. If your platform does differently, then - * either provide a proper interrupt tree or don't use this - * function. - */ - if (pci_read_config_byte(pci_dev, PCI_INTERRUPT_PIN, &pin)) - return -1; - if (pin == 0) - return -1; - if (pci_read_config_byte(pci_dev, PCI_INTERRUPT_LINE, &line) || - line == 0xff || line == 0) { - return -1; - } - pr_debug(" No map ! Using line %d (pin %d) from PCI config\n", - line, pin); - - virq = irq_create_mapping(NULL, line); - if (virq) - irq_set_irq_type(virq, IRQ_TYPE_LEVEL_LOW); - } else { - pr_debug(" Got one, spec %d cells (0x%08x 0x%08x...) on %s\n", - oirq.size, oirq.specifier[0], oirq.specifier[1], - of_node_full_name(oirq.controller)); - - virq = irq_create_of_mapping(oirq.controller, oirq.specifier, - oirq.size); - } - if (!virq) { - pr_debug(" Failed to map !\n"); - return -1; - } - - pr_debug(" Mapped to linux irq %d\n", virq); - - pci_dev->irq = virq; - - return 0; -} -EXPORT_SYMBOL(pci_read_irq_line); - -/* * Platform support for /proc/bus/pci/X/Y mmap()s, * modelled on the sparc64 implementation by Dave Miller. * -- paulus. @@ -657,67 +588,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 +631,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 +645,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 +666,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 +680,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 @@ -990,7 +891,7 @@ void pcibios_setup_bus_devices(struct pci_bus *bus) dev->dev.archdata.dma_data = (void *)PCI_DRAM_OFFSET; /* Read default IRQs and fixup if necessary */ - pci_read_irq_line(dev); + dev->irq = of_irq_parse_and_map_pci(dev, 0, 0); } } diff --git a/arch/microblaze/platform/Kconfig.platform b/arch/microblaze/platform/Kconfig.platform index b1747211b8b..db1aa5c22ce 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 |