Merge branch 'next' of git://git.monstr.eu/linux-2.6-microblaze
authorLinus Torvalds <torvalds@linux-foundation.org>
Wed, 28 Mar 2012 01:20:56 +0000 (18:20 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Wed, 28 Mar 2012 01:20:56 +0000 (18:20 -0700)
Pull arch/microblaze fixes from Michal Simek

* 'next' of git://git.monstr.eu/linux-2.6-microblaze:
  microblaze: Handle TLB skip size dynamically
  microblaze: Introduce TLB skip size
  microblaze: Improve TLB calculation for small systems
  microblaze: Extend space for compiled-in FDT to 32kB
  microblaze: Clear all MSR flags on the first kernel instruction
  microblaze: Use node name instead of compatible string
  microblaze: Fix mapin_ram function
  microblaze: Highmem support
  microblaze: Use active regions
  microblaze: Show more detailed information about memory
  microblaze: Introduce fixmap
  microblaze: mm: Fix lowmem max memory size limits
  microblaze: mm: Use ZONE_DMA instead of ZONE_NORMAL
  microblaze: trivial: Fix typo fault in timer.c
  microblaze: Use vsprintf extention %pf with builtin_return_address
  microblaze: Add PVR version string for MB 8.20.b and 8.30.a
  microblaze: Fix makefile to work with latest toolchain
  microblaze: Fix typo in early_printk.c

1  2 
arch/microblaze/Kconfig
arch/microblaze/include/asm/pgtable.h
arch/microblaze/kernel/intc.c
arch/microblaze/kernel/setup.c

diff --combined arch/microblaze/Kconfig
index 11060fa87da35c304df036bfe968fe66556851cd,d64c10093b409c367a36280994cc9a0a2fdb5daa..ac22dc7f4cab0ffa882182103fe6c0ccf1ad6963
@@@ -1,6 -1,7 +1,7 @@@
  config MICROBLAZE
        def_bool y
        select HAVE_MEMBLOCK
+       select HAVE_MEMBLOCK_NODE_MAP
        select HAVE_FUNCTION_TRACER
        select HAVE_FUNCTION_TRACE_MCOUNT_TEST
        select HAVE_FUNCTION_GRAPH_TRACER
@@@ -14,7 -15,6 +15,7 @@@
        select TRACING_SUPPORT
        select OF
        select OF_EARLY_FLATTREE
 +      select IRQ_DOMAIN
        select HAVE_GENERIC_HARDIRQS
        select GENERIC_IRQ_PROBE
        select GENERIC_IRQ_SHOW
@@@ -28,6 -28,12 +29,12 @@@ config SWA
  config RWSEM_GENERIC_SPINLOCK
        def_bool y
  
+ config ZONE_DMA
+       def_bool y
+ config ARCH_POPULATES_NODE_MAP
+       def_bool y
  config RWSEM_XCHGADD_ALGORITHM
        bool
  
@@@ -153,20 -159,18 +160,18 @@@ config XILINX_UNCACHED_SHADO
          The feature requires the design to define the RAM memory controller
          window to be twice as large as the actual physical memory.
  
- config HIGHMEM_START_BOOL
-       bool "Set high memory pool address"
-       depends on ADVANCED_OPTIONS && HIGHMEM
+ config HIGHMEM
+       bool "High memory support"
+       depends on MMU
        help
-         This option allows you to set the base address of the kernel virtual
-         area used to map high memory pages.  This can be useful in
-         optimizing the layout of kernel virtual memory.
+         The address space of Microblaze processors is only 4 Gigabytes large
+         and it has to accommodate user address space, kernel address
+         space as well as some memory mapped IO. That means that, if you
+         have a large amount of physical memory and/or IO, not all of the
+         memory can be "permanently mapped" by the kernel. The physical
+         memory that is not permanently mapped is called "high memory".
  
-         Say N here unless you know what you are doing.
- config HIGHMEM_START
-       hex "Virtual start address of high memory pool" if HIGHMEM_START_BOOL
-       depends on MMU
-       default "0xfe000000"
+         If unsure, say n.
  
  config LOWMEM_SIZE_BOOL
        bool "Set maximum low memory"
@@@ -255,6 -259,10 +260,10 @@@ config MICROBLAZE_32K_PAGE
  
  endchoice
  
+ config KERNEL_PAD
+       hex "Kernel PAD for unpacking" if ADVANCED_OPTIONS
+       default "0x80000" if MMU
  endmenu
  
  source "mm/Kconfig"
index 44dc67aa02773d577ab606d04109763956512432,d8f2c3c68d38636c3d9c189f225d0cea89680e7a..3ef7b9cafecaacea1722bf00dc680290bc97d427
@@@ -94,8 -94,7 +94,7 @@@ static inline pte_t pte_mkspecial(pte_
  /* Start and end of the vmalloc area. */
  /* Make sure to map the vmalloc area above the pinned kernel memory area
     of 32Mb.  */
- #define VMALLOC_START (CONFIG_KERNEL_START + \
-                               max(32 * 1024 * 1024UL, memory_size))
+ #define VMALLOC_START (CONFIG_KERNEL_START + CONFIG_LOWMEM_SIZE)
  #define VMALLOC_END   ioremap_bot
  
  #endif /* __ASSEMBLY__ */
@@@ -543,6 -542,8 +542,6 @@@ extern unsigned long iopa(unsigned lon
  /* Needs to be defined here and not in linux/mm.h, as it is arch dependent */
  #define kern_addr_valid(addr) (1)
  
 -#define io_remap_page_range remap_page_range
 -
  /*
   * No page table caches to initialise
   */
index ad120672cee5779eaf91e1f6fb48ff89ca44e3a4,3003d2f9f551e22d333e044acd37be0195c7a6dc..6c54d4dcdec311e0f6f5fce32a6635cf0095883f
@@@ -9,7 -9,6 +9,7 @@@
   */
  
  #include <linux/init.h>
 +#include <linux/irqdomain.h>
  #include <linux/irq.h>
  #include <asm/page.h>
  #include <linux/io.h>
@@@ -26,6 -25,8 +26,6 @@@ static unsigned int intc_baseaddr
  #define INTC_BASE     intc_baseaddr
  #endif
  
 -unsigned int nr_irq;
 -
  /* No one else should require these constants, so define them locally here. */
  #define ISR 0x00                      /* Interrupt Status Register */
  #define IPR 0x04                      /* Interrupt Pending Register */
@@@ -83,45 -84,24 +83,45 @@@ static struct irq_chip intc_dev = 
        .irq_mask_ack = intc_mask_ack,
  };
  
 -unsigned int get_irq(struct pt_regs *regs)
 +static struct irq_domain *root_domain;
 +
 +unsigned int get_irq(void)
  {
 -      int irq;
 +      unsigned int hwirq, irq = -1;
  
 -      /*
 -       * NOTE: This function is the one that needs to be improved in
 -       * order to handle multiple interrupt controllers. It currently
 -       * is hardcoded to check for interrupts only on the first INTC.
 -       */
 -      irq = in_be32(INTC_BASE + IVR) + NO_IRQ_OFFSET;
 -      pr_debug("get_irq: %d\n", irq);
 +      hwirq = in_be32(INTC_BASE + IVR);
 +      if (hwirq != -1U)
 +              irq = irq_find_mapping(root_domain, hwirq);
 +
 +      pr_debug("get_irq: hwirq=%d, irq=%d\n", hwirq, irq);
  
        return irq;
  }
  
 +int xintc_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hw)
 +{
 +      u32 intr_mask = (u32)d->host_data;
 +
 +      if (intr_mask & (1 << hw)) {
 +              irq_set_chip_and_handler_name(irq, &intc_dev,
 +                                              handle_edge_irq, "edge");
 +              irq_clear_status_flags(irq, IRQ_LEVEL);
 +      } else {
 +              irq_set_chip_and_handler_name(irq, &intc_dev,
 +                                              handle_level_irq, "level");
 +              irq_set_status_flags(irq, IRQ_LEVEL);
 +      }
 +      return 0;
 +}
 +
 +static const struct irq_domain_ops xintc_irq_domain_ops = {
 +      .xlate = irq_domain_xlate_onetwocell,
 +      .map = xintc_map,
 +};
 +
  void __init init_IRQ(void)
  {
 -      u32 i, intr_mask;
 +      u32 nr_irq, intr_mask;
        struct device_node *intc = NULL;
  #ifdef CONFIG_SELFMOD_INTC
        unsigned int intc_baseaddr = 0;
  #ifdef CONFIG_SELFMOD_INTC
        selfmod_function((int *) arr_func, intc_baseaddr);
  #endif
-       printk(KERN_INFO "XPS intc #0 at 0x%08x, num_irq=%d, edge=0x%x\n",
-               intc_baseaddr, nr_irq, intr_mask);
+       printk(KERN_INFO "%s #0 at 0x%08x, num_irq=%d, edge=0x%x\n",
+               intc->name, intc_baseaddr, nr_irq, intr_mask);
  
        /*
         * Disable all external interrupts until they are
        /* Turn on the Master Enable. */
        out_be32(intc_baseaddr + MER, MER_HIE | MER_ME);
  
 -      for (i = IRQ_OFFSET; i < (nr_irq + IRQ_OFFSET); ++i) {
 -              if (intr_mask & (0x00000001 << (i - IRQ_OFFSET))) {
 -                      irq_set_chip_and_handler_name(i, &intc_dev,
 -                              handle_edge_irq, "edge");
 -                      irq_clear_status_flags(i, IRQ_LEVEL);
 -              } else {
 -                      irq_set_chip_and_handler_name(i, &intc_dev,
 -                              handle_level_irq, "level");
 -                      irq_set_status_flags(i, IRQ_LEVEL);
 -              }
 -              irq_get_irq_data(i)->hwirq = i - IRQ_OFFSET;
 -      }
 +      /* 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);
  }
index 70e6d0b41ab4ff31688379fe795a1905f5c5599c,e4f5956ee13c9fe3059a80222d9bf6424d1c8489..9f79fb3bbfa08430d7d07fad8e85cd1e47d88ad8
@@@ -51,6 -51,8 +51,6 @@@ void __init setup_arch(char **cmdline_p
  
        unflatten_device_tree();
  
 -      /* NOTE I think that this function is not necessary to call */
 -      /* irq_early_init(); */
        setup_cpuinfo();
  
        microblaze_cache_init();
@@@ -95,8 -97,11 +95,11 @@@ inline unsigned get_romfs_len(unsigned 
  }
  #endif        /* CONFIG_MTD_UCLINUX_EBSS */
  
+ unsigned long kernel_tlb;
  void __init machine_early_init(const char *cmdline, unsigned int ram,
-               unsigned int fdt, unsigned int msr)
+               unsigned int fdt, unsigned int msr, unsigned int tlb0,
+               unsigned int tlb1)
  {
        unsigned long *src, *dst;
        unsigned int offset = 0;
        setup_early_printk(NULL);
  #endif
  
+       /* setup kernel_tlb after BSS cleaning
+        * Maybe worth to move to asm code */
+       kernel_tlb = tlb0 + tlb1;
+       /* printk("TLB1 0x%08x, TLB0 0x%08x, tlb 0x%x\n", tlb0,
+                                                       tlb1, kernel_tlb); */
        printk("Ramdisk addr 0x%08x, ", ram);
        if (fdt)
                printk("FDT at 0x%08x\n", fdt);
@@@ -197,6 -208,19 +206,19 @@@ static int microblaze_debugfs_init(void
        return of_debugfs_root == NULL;
  }
  arch_initcall(microblaze_debugfs_init);
+ static int __init debugfs_tlb(void)
+ {
+       struct dentry *d;
+       if (!of_debugfs_root)
+               return -ENODEV;
+       d = debugfs_create_u32("tlb_skip", S_IRUGO, of_debugfs_root, &tlb_skip);
+       if (!d)
+               return -ENOMEM;
+ }
+ device_initcall(debugfs_tlb);
  #endif
  
  static int dflt_bus_notify(struct notifier_block *nb,