Merge branch 'for-linus' of git://ftp.arm.linux.org.uk/~rmk/linux-arm into next
authorLinus Torvalds <torvalds@linux-foundation.org>
Thu, 5 Jun 2014 22:57:04 +0000 (15:57 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Thu, 5 Jun 2014 22:57:04 +0000 (15:57 -0700)
Pull ARM updates from Russell King:

 - Major clean-up of the L2 cache support code.  The existing mess was
   becoming rather unmaintainable through all the additions that others
   have done over time.  This turns it into a much nicer structure, and
   implements a few performance improvements as well.

 - Clean up some of the CP15 control register tweaks for alignment
   support, moving some code and data into alignment.c

 - DMA properties for ARM, from Santosh and reviewed by DT people.  This
   adds DT properties to specify bus translations we can't discover
   automatically, and to indicate whether devices are coherent.

 - Hibernation support for ARM

 - Make ftrace work with read-only text in modules

 - add suspend support for PJ4B CPUs

 - rework interrupt masking for undefined instruction handling, which
   allows us to enable interrupts earlier in the handling of these
   exceptions.

 - support for big endian page tables

 - fix stacktrace support to exclude stacktrace functions from the
   trace, and add save_stack_trace_regs() implementation so that kprobes
   can record stack traces.

 - Add support for the Cortex-A17 CPU.

 - Remove last vestiges of ARM710 support.

 - Removal of ARM "meminfo" structure, finally converting us solely to
   memblock to handle the early memory initialisation.

* 'for-linus' of git://ftp.arm.linux.org.uk/~rmk/linux-arm: (142 commits)
  ARM: ensure C page table setup code follows assembly code (part II)
  ARM: ensure C page table setup code follows assembly code
  ARM: consolidate last remaining open-coded alignment trap enable
  ARM: remove global cr_no_alignment
  ARM: remove CPU_CP15 conditional from alignment.c
  ARM: remove unused adjust_cr() function
  ARM: move "noalign" command line option to alignment.c
  ARM: provide common method to clear bits in CPU control register
  ARM: 8025/1: Get rid of meminfo
  ARM: 8060/1: mm: allow sub-architectures to override PCI I/O memory type
  ARM: 8066/1: correction for ARM patch 8031/2
  ARM: 8049/1: ftrace/add save_stack_trace_regs() implementation
  ARM: 8065/1: remove last use of CONFIG_CPU_ARM710
  ARM: 8062/1: Modify ldrt fixup handler to re-execute the userspace instruction
  ARM: 8047/1: rwsem: use asm-generic rwsem implementation
  ARM: l2c: trial at enabling some Cortex-A9 optimisations
  ARM: l2c: add warnings for stuff modifying aux_ctrl register values
  ARM: l2c: print a warning with L2C-310 caches if the cache size is modified
  ARM: l2c: remove old .set_debug method
  ARM: l2c: kill L2X0_AUX_CTRL_MASK before anyone else makes use of this
  ...

39 files changed:
1  2 
arch/arm/Kconfig
arch/arm/boot/dts/prima2.dtsi
arch/arm/kernel/devtree.c
arch/arm/kernel/topology.c
arch/arm/mach-exynos/common.h
arch/arm/mach-exynos/exynos.c
arch/arm/mach-msm/board-msm7x30.c
arch/arm/mach-msm/board-trout.c
arch/arm/mach-mvebu/board-v7.c
arch/arm/mach-omap2/io.c
arch/arm/mach-omap2/omap-mpuss-lowpower.c
arch/arm/mach-omap2/omap4-common.c
arch/arm/mach-orion5x/common.h
arch/arm/mach-realview/core.c
arch/arm/mach-realview/core.h
arch/arm/mach-realview/realview_eb.c
arch/arm/mach-realview/realview_pb1176.c
arch/arm/mach-realview/realview_pb11mp.c
arch/arm/mach-realview/realview_pbx.c
arch/arm/mach-rockchip/rockchip.c
arch/arm/mach-s3c24xx/mach-smdk2413.c
arch/arm/mach-s3c24xx/mach-vstms.c
arch/arm/mach-shmobile/board-armadillo800eva-reference.c
arch/arm/mach-shmobile/board-armadillo800eva.c
arch/arm/mach-shmobile/setup-r8a7778.c
arch/arm/mach-shmobile/setup-r8a7779.c
arch/arm/mach-sti/board-dt.c
arch/arm/mach-vexpress/ct-ca9x4.c
arch/arm/mach-vexpress/v2m.c
arch/arm/mach-zynq/common.c
arch/arm/mm/dma-mapping.c
arch/arm/mm/init.c
drivers/of/address.c
drivers/of/platform.c
include/linux/device.h
include/linux/dma-mapping.h
include/linux/of_address.h
include/linux/suspend.h
kernel/events/uprobes.c

Simple merge
Simple merge
  #include <asm/mach/arch.h>
  #include <asm/mach-types.h>
  
- void __init early_init_dt_add_memory_arch(u64 base, u64 size)
 -void * __init early_init_dt_alloc_memory_arch(u64 size, u64 align)
--{
-       arm_add_memory(base, size);
 -      return memblock_virt_alloc(size, align);
--}
 -
 -void __init arm_dt_memblock_reserve(void)
 -{
 -      u64 *reserve_map, base, size;
  
 -      if (!initial_boot_params)
 -              return;
 +#ifdef CONFIG_SMP
 +extern struct of_cpu_method __cpu_method_of_table[];
  
 -      /* Reserve the dtb region */
 -      memblock_reserve(virt_to_phys(initial_boot_params),
 -                       be32_to_cpu(initial_boot_params->totalsize));
 +static const struct of_cpu_method __cpu_method_of_table_sentinel
 +      __used __section(__cpu_method_of_table_end);
  
 -      /*
 -       * Process the reserve map.  This will probably overlap the initrd
 -       * and dtb locations which are already reserved, but overlaping
 -       * doesn't hurt anything
 -       */
 -      reserve_map = ((void*)initial_boot_params) +
 -                      be32_to_cpu(initial_boot_params->off_mem_rsvmap);
 -      while (1) {
 -              base = be64_to_cpup(reserve_map++);
 -              size = be64_to_cpup(reserve_map++);
 -              if (!size)
 -                      break;
 -              memblock_reserve(base, size);
 -      }
 -}
 -
 -#ifdef CONFIG_SMP
 -extern struct of_cpu_method __cpu_method_of_table_begin[];
 -extern struct of_cpu_method __cpu_method_of_table_end[];
  
  static int __init set_smp_ops_by_method(struct device_node *node)
  {
Simple merge
Simple merge
@@@ -246,25 -305,17 +243,6 @@@ void __init exynos_init_io(void
        exynos_map_io();
  }
  
- static int __init exynos4_l2x0_cache_init(void)
- {
-       int ret;
-       if (!soc_is_exynos4())
-               return 0;
-       ret = l2x0_of_init(L2_AUX_VAL, L2_AUX_MASK);
-       if (ret)
-               return ret;
 -struct bus_type exynos_subsys = {
 -      .name           = "exynos-core",
 -      .dev_name       = "exynos-core",
 -};
--
-       if (IS_ENABLED(CONFIG_S5P_SLEEP)) {
-               l2x0_regs_phys = virt_to_phys(&l2x0_saved_regs);
-               clean_dcache_area(&l2x0_regs_phys, sizeof(unsigned long));
-       }
-       return 0;
 -static int __init exynos_core_init(void)
 -{
 -      return subsys_system_register(&exynos_subsys, NULL);
--}
- early_initcall(exynos4_l2x0_cache_init);
 -core_initcall(exynos_core_init);
--
  static void __init exynos_dt_machine_init(void)
  {
        struct device_node *i2c_np;
Simple merge
Simple merge
@@@ -195,8 -121,9 +197,10 @@@ static const char * const armada_375_dt
  };
  
  DT_MACHINE_START(ARMADA_375_DT, "Marvell Armada 375 (Device Tree)")
+       .l2c_aux_val    = 0,
+       .l2c_aux_mask   = ~0,
        .init_time      = mvebu_timer_and_clk_init,
 +      .init_machine   = mvebu_dt_init,
        .restart        = mvebu_restart,
        .dt_compat      = armada_375_dt_compat,
  MACHINE_END
Simple merge
@@@ -187,19 -187,15 +187,15 @@@ static void l2x0_pwrst_prepare(unsigne
   * in every restore MPUSS OFF path.
   */
  #ifdef CONFIG_CACHE_L2X0
- static void save_l2x0_context(void)
+ static void __init save_l2x0_context(void)
  {
-       u32 val;
-       void __iomem *l2x0_base = omap4_get_l2cache_base();
-       if (l2x0_base) {
-               val = readl_relaxed(l2x0_base + L2X0_AUX_CTRL);
-               writel_relaxed(val, sar_base + L2X0_AUXCTRL_OFFSET);
-               val = readl_relaxed(l2x0_base + L2X0_PREFETCH_CTRL);
-               writel_relaxed(val, sar_base + L2X0_PREFETCH_CTRL_OFFSET);
-       }
 -      __raw_writel(l2x0_saved_regs.aux_ctrl,
++      writel_relaxed(l2x0_saved_regs.aux_ctrl,
+                    sar_base + L2X0_AUXCTRL_OFFSET);
 -      __raw_writel(l2x0_saved_regs.prefetch_ctrl,
++      writel_relaxed(l2x0_saved_regs.prefetch_ctrl,
+                    sar_base + L2X0_PREFETCH_CTRL_OFFSET);
  }
  #else
- static void save_l2x0_context(void)
+ static void __init save_l2x0_context(void)
  {}
  #endif
  
Simple merge
@@@ -64,16 -64,16 +64,15 @@@ int orion5x_pci_sys_setup(int nr, struc
  struct pci_bus *orion5x_pci_sys_scan_bus(int nr, struct pci_sys_data *sys);
  int orion5x_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin);
  
- struct meminfo;
 -/* board init functions for boards not fully converted to fdt */
 -#ifdef CONFIG_MACH_EDMINI_V2_DT
 -void edmini_v2_init(void);
 -#else
 -static inline void edmini_v2_init(void) {};
 -#endif
 -
  struct tag;
- extern void __init tag_fixup_mem32(struct tag *, char **, struct meminfo *);
+ extern void __init tag_fixup_mem32(struct tag *, char **);
  
 +#ifdef CONFIG_MACH_MSS2_DT
 +extern void mss2_init(void);
 +#else
 +static inline void mss2_init(void) {}
 +#endif
 +
  /*****************************************************************************
   * Helpers to access Orion registers
   ****************************************************************************/
Simple merge
Simple merge
Simple merge
Simple merge
@@@ -39,6 -33,8 +33,7 @@@ static const char * const rockchip_boar
  };
  
  DT_MACHINE_START(ROCKCHIP_DT, "Rockchip Cortex-A9 (Device Tree)")
-       .init_machine   = rockchip_dt_init,
+       .l2c_aux_val    = 0,
+       .l2c_aux_mask   = ~0,
 -      .smp            = smp_ops(rockchip_smp_ops),
        .dt_compat      = rockchip_board_dt_compat,
  MACHINE_END
Simple merge
Simple merge
Simple merge
Simple merge
@@@ -370,10 -369,70 +370,9 @@@ MACHINE_START(VEXPRESS, "ARM-Versatile 
        .init_machine   = v2m_init,
  MACHINE_END
  
 -static struct map_desc v2m_rs1_io_desc __initdata = {
 -      .virtual        = V2M_PERIPH,
 -      .pfn            = __phys_to_pfn(0x1c000000),
 -      .length         = SZ_2M,
 -      .type           = MT_DEVICE,
 -};
 -
 -static int __init v2m_dt_scan_memory_map(unsigned long node, const char *uname,
 -              int depth, void *data)
 -{
 -      const char **map = data;
 -
 -      if (strcmp(uname, "motherboard") != 0)
 -              return 0;
 -
 -      *map = of_get_flat_dt_prop(node, "arm,v2m-memory-map", NULL);
 -
 -      return 1;
 -}
 -
 -void __init v2m_dt_map_io(void)
 -{
 -      const char *map = NULL;
 -
 -      of_scan_flat_dt(v2m_dt_scan_memory_map, &map);
 -
 -      if (map && strcmp(map, "rs1") == 0)
 -              iotable_init(&v2m_rs1_io_desc, 1);
 -      else
 -              iotable_init(v2m_io_desc, ARRAY_SIZE(v2m_io_desc));
 -
 -#if defined(CONFIG_SMP)
 -      vexpress_dt_smp_map_io();
 -#endif
 -}
 -
 -void __init v2m_dt_init_early(void)
 -{
 -      u32 dt_hbi;
 -
 -      vexpress_sysreg_of_early_init();
 -
 -      /* Confirm board type against DT property, if available */
 -      if (of_property_read_u32(of_allnodes, "arm,hbi", &dt_hbi) == 0) {
 -              u32 hbi = vexpress_get_hbi(VEXPRESS_SITE_MASTER);
 -
 -              if (WARN_ON(dt_hbi != hbi))
 -                      pr_warning("vexpress: DT HBI (%x) is not matching "
 -                                      "hardware (%x)!\n", dt_hbi, hbi);
 -      }
 -
 -      versatile_sched_clock_init(vexpress_get_24mhz_clock_base(), 24000000);
 -}
 -
 -static const struct of_device_id v2m_dt_bus_match[] __initconst = {
 -      { .compatible = "simple-bus", },
 -      { .compatible = "arm,amba-bus", },
 -      { .compatible = "arm,vexpress,config-bus", },
 -      {}
 -};
 -
  static void __init v2m_dt_init(void)
  {
-       l2x0_of_init(0x00400000, 0xfe0fffff);
 -      of_platform_populate(NULL, v2m_dt_bus_match, NULL, NULL);
 +      of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
  }
  
  static const char * const v2m_dt_match[] __initconst = {
  
  DT_MACHINE_START(VEXPRESS_DT, "ARM-Versatile Express")
        .dt_compat      = v2m_dt_match,
 -      .smp            = smp_ops(vexpress_smp_ops),
+       .l2c_aux_val    = 0x00400000,
+       .l2c_aux_mask   = 0xfe0fffff,
 +      .smp            = smp_ops(vexpress_smp_dt_ops),
        .smp_init       = smp_init_ops(vexpress_smp_init_ops),
 -      .map_io         = v2m_dt_map_io,
 -      .init_early     = v2m_dt_init_early,
        .init_machine   = v2m_dt_init,
  MACHINE_END
@@@ -105,43 -66,8 +105,38 @@@ static int __init zynq_get_revision(voi
  static void __init zynq_init_machine(void)
  {
        struct platform_device_info devinfo = { .name = "cpufreq-cpu0", };
-       /*
-        * 64KB way size, 8-way associativity, parity disabled
-        */
-       l2x0_of_init(0x02060000, 0xF0F0FFFF);
 +      struct soc_device_attribute *soc_dev_attr;
 +      struct soc_device *soc_dev;
 +      struct device *parent = NULL;
 +
 +      soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL);
 +      if (!soc_dev_attr)
 +              goto out;
 +
 +      system_rev = zynq_get_revision();
 +
 +      soc_dev_attr->family = kasprintf(GFP_KERNEL, "Xilinx Zynq");
 +      soc_dev_attr->revision = kasprintf(GFP_KERNEL, "0x%x", system_rev);
 +      soc_dev_attr->soc_id = kasprintf(GFP_KERNEL, "0x%x",
 +                                       zynq_slcr_get_device_id());
 +
 +      soc_dev = soc_device_register(soc_dev_attr);
 +      if (IS_ERR(soc_dev)) {
 +              kfree(soc_dev_attr->family);
 +              kfree(soc_dev_attr->revision);
 +              kfree(soc_dev_attr->soc_id);
 +              kfree(soc_dev_attr);
 +              goto out;
 +      }
 +
 +      parent = soc_device_to_device(soc_dev);
  
 -      of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
 +out:
 +      /*
 +       * Finished with the static registrations now; fill in the missing
 +       * devices
 +       */
 +      of_platform_populate(NULL, of_default_bus_match_table, NULL, parent);
  
        platform_device_register(&zynq_cpuidle_device);
        platform_device_register_full(&devinfo);
Simple merge
Simple merge
@@@ -701,3 -721,113 +701,113 @@@ void __iomem *of_iomap(struct device_no
        return ioremap(res.start, resource_size(&res));
  }
  EXPORT_SYMBOL(of_iomap);
 -EXPORT_SYMBOL_GPL(of_dma_is_coherent);
+ /**
+  * of_dma_get_range - Get DMA range info
+  * @np:               device node to get DMA range info
+  * @dma_addr: pointer to store initial DMA address of DMA range
+  * @paddr:    pointer to store initial CPU address of DMA range
+  * @size:     pointer to store size of DMA range
+  *
+  * Look in bottom up direction for the first "dma-ranges" property
+  * and parse it.
+  *  dma-ranges format:
+  *    DMA addr (dma_addr)     : naddr cells
+  *    CPU addr (phys_addr_t)  : pna cells
+  *    size                    : nsize cells
+  *
+  * It returns -ENODEV if "dma-ranges" property was not found
+  * for this device in DT.
+  */
+ int of_dma_get_range(struct device_node *np, u64 *dma_addr, u64 *paddr, u64 *size)
+ {
+       struct device_node *node = of_node_get(np);
+       const __be32 *ranges = NULL;
+       int len, naddr, nsize, pna;
+       int ret = 0;
+       u64 dmaaddr;
+       if (!node)
+               return -EINVAL;
+       while (1) {
+               naddr = of_n_addr_cells(node);
+               nsize = of_n_size_cells(node);
+               node = of_get_next_parent(node);
+               if (!node)
+                       break;
+               ranges = of_get_property(node, "dma-ranges", &len);
+               /* Ignore empty ranges, they imply no translation required */
+               if (ranges && len > 0)
+                       break;
+               /*
+                * At least empty ranges has to be defined for parent node if
+                * DMA is supported
+                */
+               if (!ranges)
+                       break;
+       }
+       if (!ranges) {
+               pr_debug("%s: no dma-ranges found for node(%s)\n",
+                        __func__, np->full_name);
+               ret = -ENODEV;
+               goto out;
+       }
+       len /= sizeof(u32);
+       pna = of_n_addr_cells(node);
+       /* dma-ranges format:
+        * DMA addr     : naddr cells
+        * CPU addr     : pna cells
+        * size         : nsize cells
+        */
+       dmaaddr = of_read_number(ranges, naddr);
+       *paddr = of_translate_dma_address(np, ranges);
+       if (*paddr == OF_BAD_ADDR) {
+               pr_err("%s: translation of DMA address(%pad) to CPU address failed node(%s)\n",
+                      __func__, dma_addr, np->full_name);
+               ret = -EINVAL;
+               goto out;
+       }
+       *dma_addr = dmaaddr;
+       *size = of_read_number(ranges + naddr + pna, nsize);
+       pr_debug("dma_addr(%llx) cpu_addr(%llx) size(%llx)\n",
+                *dma_addr, *paddr, *size);
+ out:
+       of_node_put(node);
+       return ret;
+ }
+ EXPORT_SYMBOL_GPL(of_dma_get_range);
+ /**
+  * of_dma_is_coherent - Check if device is coherent
+  * @np:       device node
+  *
+  * It returns true if "dma-coherent" property was found
+  * for this device in DT.
+  */
+ bool of_dma_is_coherent(struct device_node *np)
+ {
+       struct device_node *node = of_node_get(np);
+       while (node) {
+               if (of_property_read_bool(node, "dma-coherent")) {
+                       of_node_put(node);
+                       return true;
+               }
+               node = of_get_next_parent(node);
+       }
+       of_node_put(node);
+       return false;
+ }
++EXPORT_SYMBOL_GPL(of_dma_is_coherent);
@@@ -176,14 -269,9 +234,9 @@@ static struct platform_device *of_platf
  
        dev = of_device_alloc(np, bus_id, parent);
        if (!dev)
 -              return NULL;
 +              goto err_clear_flag;
  
- #if defined(CONFIG_MICROBLAZE)
-       dev->archdata.dma_mask = 0xffffffffUL;
- #endif
-       dev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
-       if (!dev->dev.dma_mask)
-               dev->dev.dma_mask = &dev->dev.coherent_dma_mask;
+       of_dma_configure(dev);
        dev->dev.bus = &platform_bus_type;
        dev->dev.platform_data = platform_data;
  
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge