]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
Merge branch 'for-linus' of git://git.armlinux.org.uk/~rmk/linux-arm
authorLinus Torvalds <torvalds@linux-foundation.org>
Tue, 28 Feb 2017 19:50:53 +0000 (11:50 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Tue, 28 Feb 2017 19:50:53 +0000 (11:50 -0800)
Pull ARM updates from Russell King:

 - nommu updates from Afzal Mohammed cleaning up the vectors support

 - allow DMA memory "mapping" for nommu Benjamin Gaignard

 - fixing a correctness issue with R_ARM_PREL31 relocations in the
   module linker

 - add strlen() prototype for the decompressor

 - support for DEBUG_VIRTUAL from Florian Fainelli

 - adjusting memory bounds after memory reservations have been
   registered

 - unipher cache handling updates from Masahiro Yamada

 - initrd and Thumb Kconfig cleanups

* 'for-linus' of git://git.armlinux.org.uk/~rmk/linux-arm: (23 commits)
  ARM: mm: round the initrd reservation to page boundaries
  ARM: mm: clean up initrd initialisation
  ARM: mm: move initrd init code out of arm_memblock_init()
  ARM: 8655/1: improve NOMMU definition of pgprot_*()
  ARM: 8654/1: decompressor: add strlen prototype
  ARM: 8652/1: cache-uniphier: clean up active way setup code
  ARM: 8651/1: cache-uniphier: include <linux/errno.h> instead of <linux/types.h>
  ARM: 8650/1: module: handle negative R_ARM_PREL31 addends correctly
  ARM: 8649/2: nommu: remove Hivecs configuration is asm
  ARM: 8648/2: nommu: display vectors base
  ARM: 8647/2: nommu: dynamic exception base address setting
  ARM: 8646/1: mmu: decouple VECTORS_BASE from Kconfig
  ARM: 8644/1: Reduce "CPU: shutdown" message to debug level
  ARM: 8641/1: treewide: Replace uses of virt_to_phys with __pa_symbol
  ARM: 8640/1: Add support for CONFIG_DEBUG_VIRTUAL
  ARM: 8639/1: Define KERNEL_START and KERNEL_END
  ARM: 8638/1: mtd: lart: Rename partition defines to be prefixed with PART_
  ARM: 8637/1: Adjust memory boundaries after reservations
  ARM: 8636/1: Cleanup sanity_check_meminfo
  ARM: add CPU_THUMB_CAPABLE to indicate possible Thumb support
  ...

12 files changed:
1  2 
arch/arm/Kconfig
arch/arm/kernel/smp.c
arch/arm/mach-exynos/mcpm-exynos.c
arch/arm/mach-exynos/platsmp.c
arch/arm/mach-exynos/suspend.c
arch/arm/mach-s3c64xx/pm.c
arch/arm/mach-s5pv210/pm.c
arch/arm/mach-shmobile/platsmp-apmu.c
arch/arm/mach-ux500/platsmp.c
arch/arm/mm/Kconfig
arch/arm/mm/dma-mapping.c
arch/arm/mm/init.c

diff --combined arch/arm/Kconfig
index fda6a46d27cfe2bda02257a8a8b30d316cd14612,4700294f4e095f71025161ba5807166f35dd80cf..0d4e71b42c77da986a2dc471a1f335be5e958527
@@@ -2,17 -2,13 +2,18 @@@ config AR
        bool
        default y
        select ARCH_CLOCKSOURCE_DATA
+       select ARCH_HAS_DEBUG_VIRTUAL
        select ARCH_HAS_DEVMEM_IS_ALLOWED
        select ARCH_HAS_ELF_RANDOMIZE
 +      select ARCH_HAS_SET_MEMORY
 +      select ARCH_HAS_STRICT_KERNEL_RWX if MMU && !XIP_KERNEL
 +      select ARCH_HAS_STRICT_MODULE_RWX if MMU
        select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST
        select ARCH_HAVE_CUSTOM_GPIO_H
        select ARCH_HAS_GCOV_PROFILE_ALL
        select ARCH_MIGHT_HAVE_PC_PARPORT
 +      select ARCH_OPTIONAL_KERNEL_RWX if ARCH_HAS_STRICT_KERNEL_RWX
 +      select ARCH_OPTIONAL_KERNEL_RWX_DEFAULT if CPU_V7
        select ARCH_SUPPORTS_ATOMIC_RMW
        select ARCH_USE_BUILTIN_BSWAP
        select ARCH_USE_CMPXCHG_LOCKREF
@@@ -1507,7 -1503,8 +1508,7 @@@ source kernel/Kconfig.preemp
  
  config HZ_FIXED
        int
 -      default 200 if ARCH_EBSA110 || ARCH_S3C24XX || \
 -              ARCH_S5PV210 || ARCH_EXYNOS4
 +      default 200 if ARCH_EBSA110
        default 128 if SOC_AT91RM9200
        default 0
  
diff --combined arch/arm/kernel/smp.c
index c6514ce0fcbc870893f2d2e9fc49044afbf7588f,46377c40d05683b2e42c4dae705e5a23055c2d92..5a07c5a4b8943c68487cc8669eee0c20408670c2
@@@ -251,7 -251,7 +251,7 @@@ void __cpu_die(unsigned int cpu
                pr_err("CPU%u: cpu didn't die\n", cpu);
                return;
        }
-       pr_notice("CPU%u: shutdown\n", cpu);
+       pr_debug("CPU%u: shutdown\n", cpu);
  
        /*
         * platform_cpu_kill() is generally expected to do the powering off
@@@ -371,7 -371,7 +371,7 @@@ asmlinkage void secondary_start_kernel(
         * reference and switch to it.
         */
        cpu = smp_processor_id();
 -      atomic_inc(&mm->mm_count);
 +      mmgrab(mm);
        current->active_mm = mm;
        cpumask_set_cpu(cpu, mm_cpumask(mm));
  
index 038fd8c993d0e6aa58acd7698be6c29cd287d4cc,214a9cfa92e94df2c48572e3cad8d68fc574227c..b42622562ea79871b5c0ccaa960011cd6eef8c6d
@@@ -32,7 -32,7 +32,7 @@@
  #define EXYNOS5420_USE_ARM_CORE_DOWN_STATE    BIT(29)
  #define EXYNOS5420_USE_L2_COMMON_UP_STATE     BIT(30)
  
 -static void __iomem *ns_sram_base_addr;
 +static void __iomem *ns_sram_base_addr __ro_after_init;
  
  /*
   * The common v7_exit_coherency_flush API could not be used because of the
@@@ -221,7 -221,7 +221,7 @@@ static void exynos_mcpm_setup_entry_poi
         */
        __raw_writel(0xe59f0000, ns_sram_base_addr);     /* ldr r0, [pc, #0] */
        __raw_writel(0xe12fff10, ns_sram_base_addr + 4); /* bx  r0 */
-       __raw_writel(virt_to_phys(mcpm_entry_point), ns_sram_base_addr + 8);
+       __raw_writel(__pa_symbol(mcpm_entry_point), ns_sram_base_addr + 8);
  }
  
  static struct syscore_ops exynos_mcpm_syscore_ops = {
index a5d68411a037994cfcf7f3c2b62c0afb5d91617f,9f4949f7ed88258e9220be2f5d2ce3b996b4af4a..5a03bffe7226030fe528eaf9c4c683b92822b4fd
@@@ -353,7 -353,7 +353,7 @@@ static int exynos_boot_secondary(unsign
  
                smp_rmb();
  
-               boot_addr = virt_to_phys(exynos4_secondary_startup);
+               boot_addr = __pa_symbol(exynos4_secondary_startup);
  
                ret = exynos_set_boot_addr(core_id, boot_addr);
                if (ret)
@@@ -385,6 -385,36 +385,6 @@@ fail
        return pen_release != -1 ? ret : 0;
  }
  
 -/*
 - * Initialise the CPU possible map early - this describes the CPUs
 - * which may be present or become present in the system.
 - */
 -
 -static void __init exynos_smp_init_cpus(void)
 -{
 -      void __iomem *scu_base = scu_base_addr();
 -      unsigned int i, ncores;
 -
 -      if (read_cpuid_part() == ARM_CPU_PART_CORTEX_A9)
 -              ncores = scu_base ? scu_get_core_count(scu_base) : 1;
 -      else
 -              /*
 -               * CPU Nodes are passed thru DT and set_cpu_possible
 -               * is set by "arm_dt_init_cpu_maps".
 -               */
 -              return;
 -
 -      /* sanity check */
 -      if (ncores > nr_cpu_ids) {
 -              pr_warn("SMP: %u cores greater than maximum (%u), clipping\n",
 -                      ncores, nr_cpu_ids);
 -              ncores = nr_cpu_ids;
 -      }
 -
 -      for (i = 0; i < ncores; i++)
 -              set_cpu_possible(i, true);
 -}
 -
  static void __init exynos_smp_prepare_cpus(unsigned int max_cpus)
  {
        int i;
  
                mpidr = cpu_logical_map(i);
                core_id = MPIDR_AFFINITY_LEVEL(mpidr, 0);
-               boot_addr = virt_to_phys(exynos4_secondary_startup);
+               boot_addr = __pa_symbol(exynos4_secondary_startup);
  
                ret = exynos_set_boot_addr(core_id, boot_addr);
                if (ret)
@@@ -449,6 -479,7 +449,6 @@@ static void exynos_cpu_die(unsigned in
  #endif /* CONFIG_HOTPLUG_CPU */
  
  const struct smp_operations exynos_smp_ops __initconst = {
 -      .smp_init_cpus          = exynos_smp_init_cpus,
        .smp_prepare_cpus       = exynos_smp_prepare_cpus,
        .smp_secondary_init     = exynos_secondary_init,
        .smp_boot_secondary     = exynos_boot_secondary,
index adf4e8f182bd650eb0ce7e3ab148492fae53b58e,97765be2cc12018cc131a05d8499f3d9f6753b9d..748cfb8d521247c2073b8cc064d963c1f7ab9eeb
@@@ -57,6 -57,7 +57,6 @@@ struct exynos_wkup_irq 
  struct exynos_pm_data {
        const struct exynos_wkup_irq *wkup_irq;
        unsigned int wake_disable_mask;
 -      unsigned int *release_ret_regs;
  
        void (*pm_prepare)(void);
        void (*pm_resume_prepare)(void);
@@@ -65,7 -66,7 +65,7 @@@
        int (*cpu_suspend)(unsigned long);
  };
  
 -static const struct exynos_pm_data *pm_data;
 +static const struct exynos_pm_data *pm_data __ro_after_init;
  
  static int exynos5420_cpu_state;
  static unsigned int exynos_pmu_spare3;
@@@ -94,6 -95,47 +94,6 @@@ static const struct exynos_wkup_irq exy
        { /* sentinel */ },
  };
  
 -static unsigned int exynos_release_ret_regs[] = {
 -      S5P_PAD_RET_MAUDIO_OPTION,
 -      S5P_PAD_RET_GPIO_OPTION,
 -      S5P_PAD_RET_UART_OPTION,
 -      S5P_PAD_RET_MMCA_OPTION,
 -      S5P_PAD_RET_MMCB_OPTION,
 -      S5P_PAD_RET_EBIA_OPTION,
 -      S5P_PAD_RET_EBIB_OPTION,
 -      REG_TABLE_END,
 -};
 -
 -static unsigned int exynos3250_release_ret_regs[] = {
 -      S5P_PAD_RET_MAUDIO_OPTION,
 -      S5P_PAD_RET_GPIO_OPTION,
 -      S5P_PAD_RET_UART_OPTION,
 -      S5P_PAD_RET_MMCA_OPTION,
 -      S5P_PAD_RET_MMCB_OPTION,
 -      S5P_PAD_RET_EBIA_OPTION,
 -      S5P_PAD_RET_EBIB_OPTION,
 -      S5P_PAD_RET_MMC2_OPTION,
 -      S5P_PAD_RET_SPI_OPTION,
 -      REG_TABLE_END,
 -};
 -
 -static unsigned int exynos5420_release_ret_regs[] = {
 -      EXYNOS_PAD_RET_DRAM_OPTION,
 -      EXYNOS_PAD_RET_MAUDIO_OPTION,
 -      EXYNOS_PAD_RET_JTAG_OPTION,
 -      EXYNOS5420_PAD_RET_GPIO_OPTION,
 -      EXYNOS5420_PAD_RET_UART_OPTION,
 -      EXYNOS5420_PAD_RET_MMCA_OPTION,
 -      EXYNOS5420_PAD_RET_MMCB_OPTION,
 -      EXYNOS5420_PAD_RET_MMCC_OPTION,
 -      EXYNOS5420_PAD_RET_HSI_OPTION,
 -      EXYNOS_PAD_RET_EBIA_OPTION,
 -      EXYNOS_PAD_RET_EBIB_OPTION,
 -      EXYNOS5420_PAD_RET_SPI_OPTION,
 -      EXYNOS5420_PAD_RET_DRAM_COREBLK_OPTION,
 -      REG_TABLE_END,
 -};
 -
  static int exynos_irq_set_wake(struct irq_data *data, unsigned int state)
  {
        const struct exynos_wkup_irq *wkup_irq;
@@@ -228,6 -270,7 +228,6 @@@ EXYNOS_PMU_IRQ(exynos3250_pmu_irq, "sam
  EXYNOS_PMU_IRQ(exynos4210_pmu_irq, "samsung,exynos4210-pmu");
  EXYNOS_PMU_IRQ(exynos4212_pmu_irq, "samsung,exynos4212-pmu");
  EXYNOS_PMU_IRQ(exynos4412_pmu_irq, "samsung,exynos4412-pmu");
 -EXYNOS_PMU_IRQ(exynos4415_pmu_irq, "samsung,exynos4415-pmu");
  EXYNOS_PMU_IRQ(exynos5250_pmu_irq, "samsung,exynos5250-pmu");
  EXYNOS_PMU_IRQ(exynos5420_pmu_irq, "samsung,exynos5420-pmu");
  
@@@ -301,7 -344,7 +301,7 @@@ static void exynos_pm_prepare(void
        exynos_pm_enter_sleep_mode();
  
        /* ensure at least INFORM0 has the resume address */
-       pmu_raw_writel(virt_to_phys(exynos_cpu_resume), S5P_INFORM0);
+       pmu_raw_writel(__pa_symbol(exynos_cpu_resume), S5P_INFORM0);
  }
  
  static void exynos3250_pm_prepare(void)
        exynos_pm_enter_sleep_mode();
  
        /* ensure at least INFORM0 has the resume address */
-       pmu_raw_writel(virt_to_phys(exynos_cpu_resume), S5P_INFORM0);
+       pmu_raw_writel(__pa_symbol(exynos_cpu_resume), S5P_INFORM0);
  }
  
  static void exynos5420_pm_prepare(void)
  
        /* ensure at least INFORM0 has the resume address */
        if (IS_ENABLED(CONFIG_EXYNOS5420_MCPM))
-               pmu_raw_writel(virt_to_phys(mcpm_entry_point), S5P_INFORM0);
+               pmu_raw_writel(__pa_symbol(mcpm_entry_point), S5P_INFORM0);
  
 -      tmp = pmu_raw_readl(EXYNOS5_ARM_L2_OPTION);
 -      tmp &= ~EXYNOS5_USE_RETENTION;
 -      pmu_raw_writel(tmp, EXYNOS5_ARM_L2_OPTION);
 +      tmp = pmu_raw_readl(EXYNOS_L2_OPTION(0));
 +      tmp &= ~EXYNOS_L2_USE_RETENTION;
 +      pmu_raw_writel(tmp, EXYNOS_L2_OPTION(0));
  
        tmp = pmu_raw_readl(EXYNOS5420_SFR_AXI_CGDIS1);
        tmp |= EXYNOS5420_UFS;
@@@ -399,6 -442,15 +399,6 @@@ static int exynos5420_pm_suspend(void
        return 0;
  }
  
 -static void exynos_pm_release_retention(void)
 -{
 -      unsigned int i;
 -
 -      for (i = 0; (pm_data->release_ret_regs[i] != REG_TABLE_END); i++)
 -              pmu_raw_writel(EXYNOS_WAKEUP_FROM_LOWPWR,
 -                              pm_data->release_ret_regs[i]);
 -}
 -
  static void exynos_pm_resume(void)
  {
        u32 cpuid = read_cpuid_part();
        if (exynos_pm_central_resume())
                goto early_wakeup;
  
 -      /* For release retention */
 -      exynos_pm_release_retention();
 -
        if (cpuid == ARM_CPU_PART_CORTEX_A9)
                scu_enable(S5P_VA_SCU);
  
@@@ -427,6 -482,9 +427,6 @@@ static void exynos3250_pm_resume(void
        if (exynos_pm_central_resume())
                goto early_wakeup;
  
 -      /* For release retention */
 -      exynos_pm_release_retention();
 -
        pmu_raw_writel(S5P_USE_STANDBY_WFI_ALL, S5P_CENTRAL_SEQ_OPTION);
  
        if (call_firmware_op(resume) == -ENOSYS
@@@ -464,6 -522,9 +464,6 @@@ static void exynos5420_pm_resume(void
        if (exynos_pm_central_resume())
                goto early_wakeup;
  
 -      /* For release retention */
 -      exynos_pm_release_retention();
 -
        pmu_raw_writel(exynos_pmu_spare3, S5P_PMU_SPARE3);
  
  early_wakeup:
@@@ -576,6 -637,7 +576,6 @@@ static const struct platform_suspend_op
  static const struct exynos_pm_data exynos3250_pm_data = {
        .wkup_irq       = exynos3250_wkup_irq,
        .wake_disable_mask = ((0xFF << 8) | (0x1F << 1)),
 -      .release_ret_regs = exynos3250_release_ret_regs,
        .pm_suspend     = exynos_pm_suspend,
        .pm_resume      = exynos3250_pm_resume,
        .pm_prepare     = exynos3250_pm_prepare,
  static const struct exynos_pm_data exynos4_pm_data = {
        .wkup_irq       = exynos4_wkup_irq,
        .wake_disable_mask = ((0xFF << 8) | (0x1F << 1)),
 -      .release_ret_regs = exynos_release_ret_regs,
        .pm_suspend     = exynos_pm_suspend,
        .pm_resume      = exynos_pm_resume,
        .pm_prepare     = exynos_pm_prepare,
  static const struct exynos_pm_data exynos5250_pm_data = {
        .wkup_irq       = exynos5250_wkup_irq,
        .wake_disable_mask = ((0xFF << 8) | (0x1F << 1)),
 -      .release_ret_regs = exynos_release_ret_regs,
        .pm_suspend     = exynos_pm_suspend,
        .pm_resume      = exynos_pm_resume,
        .pm_prepare     = exynos_pm_prepare,
  static const struct exynos_pm_data exynos5420_pm_data = {
        .wkup_irq       = exynos5250_wkup_irq,
        .wake_disable_mask = (0x7F << 7) | (0x1F << 1),
 -      .release_ret_regs = exynos5420_release_ret_regs,
        .pm_resume_prepare = exynos5420_prepare_pm_resume,
        .pm_resume      = exynos5420_pm_resume,
        .pm_suspend     = exynos5420_pm_suspend,
index b0be382ff6bb7fa7debce8a9f7cbc2b2384e2bc1,945a9d1e1a717136f49822ce94eba1f2e1309cec..2f579be8fe677adc72032ca91a647ac046f02a4a
@@@ -285,7 -285,7 +285,7 @@@ static int s3c64xx_cpu_suspend(unsigne
  }
  
  /* mapping of interrupts to parts of the wakeup mask */
 -static struct samsung_wakeup_mask wake_irqs[] = {
 +static const struct samsung_wakeup_mask wake_irqs[] = {
        { .irq = IRQ_RTC_ALARM, .bit = S3C64XX_PWRCFG_RTC_ALARM_DISABLE, },
        { .irq = IRQ_RTC_TIC,   .bit = S3C64XX_PWRCFG_RTC_TICK_DISABLE, },
        { .irq = IRQ_PENDN,     .bit = S3C64XX_PWRCFG_TS_DISABLE, },
@@@ -304,7 -304,7 +304,7 @@@ static void s3c64xx_pm_prepare(void
                              wake_irqs, ARRAY_SIZE(wake_irqs));
  
        /* store address of resume. */
-       __raw_writel(virt_to_phys(s3c_cpu_resume), S3C64XX_INFORM0);
+       __raw_writel(__pa_symbol(s3c_cpu_resume), S3C64XX_INFORM0);
  
        /* ensure previous wakeup state is cleared before sleeping */
        __raw_writel(__raw_readl(S3C64XX_WAKEUP_STAT), S3C64XX_WAKEUP_STAT);
index 7d69666de5ba2dd6b3c5c705d608ba4ad182767b,2d5f08015e34862e356daeadaa284aa0012dab05..07cee14a363b05eb1ca99418eb8d3c0074d0b04d
@@@ -69,7 -69,7 +69,7 @@@ static void s5pv210_pm_prepare(void
        __raw_writel(s5pv210_irqwake_intmask, S5P_WAKEUP_MASK);
  
        /* ensure at least INFORM0 has the resume address */
-       __raw_writel(virt_to_phys(s5pv210_cpu_resume), S5P_INFORM0);
+       __raw_writel(__pa_symbol(s5pv210_cpu_resume), S5P_INFORM0);
  
        tmp = __raw_readl(S5P_SLEEP_CFG);
        tmp &= ~(S5P_SLEEP_CFG_OSC_EN | S5P_SLEEP_CFG_USBOSC_EN);
@@@ -155,6 -155,13 +155,6 @@@ static const struct platform_suspend_op
   */
  static void s5pv210_pm_resume(void)
  {
 -      u32 tmp;
 -
 -      tmp = __raw_readl(S5P_OTHERS);
 -      tmp |= (S5P_OTHERS_RET_IO | S5P_OTHERS_RET_CF |\
 -              S5P_OTHERS_RET_MMC | S5P_OTHERS_RET_UART);
 -      __raw_writel(tmp , S5P_OTHERS);
 -
        s3c_pm_do_restore_core(s5pv210_core_save, ARRAY_SIZE(s5pv210_core_save));
  }
  
index e19266844e16126b855bd9ab1f82e3ae5fa7a5f4,71729b8d1900ff04844052b48ee50d954c2c0cb3..3ca2c13346f0cbc35d291cfdb28c966b71aba67e
@@@ -31,21 -31,9 +31,21 @@@ static struct 
        int bit;
  } apmu_cpus[NR_CPUS];
  
 -#define WUPCR_OFFS 0x10
 -#define PSTR_OFFS 0x40
 -#define CPUNCR_OFFS(n) (0x100 + (0x10 * (n)))
 +#define WUPCR_OFFS     0x10           /* Wake Up Control Register */
 +#define PSTR_OFFS      0x40           /* Power Status Register */
 +#define CPUNCR_OFFS(n)        (0x100 + (0x10 * (n)))
 +                                      /* CPUn Power Status Control Register */
 +#define DBGRCR_OFFS   0x180           /* Debug Resource Reset Control Reg. */
 +
 +/* Power Status Register */
 +#define CPUNST(r, n)  (((r) >> (n * 4)) & 3)  /* CPUn Status Bit */
 +#define CPUST_RUN     0               /* Run Mode */
 +#define CPUST_STANDBY 3               /* CoreStandby Mode */
 +
 +/* Debug Resource Reset Control Register */
 +#define DBGCPUREN     BIT(24)         /* CPU Other Reset Request Enable */
 +#define DBGCPUNREN(n) BIT((n) + 20)   /* CPUn Reset Request Enable */
 +#define DBGCPUPREN    BIT(19)         /* CPU Peripheral Reset Req. Enable */
  
  static int __maybe_unused apmu_power_on(void __iomem *p, int bit)
  {
@@@ -71,7 -59,7 +71,7 @@@ static int __maybe_unused apmu_power_of
        int k;
  
        for (k = 0; k < 1000; k++) {
 -              if (((readl_relaxed(p + PSTR_OFFS) >> (bit * 4)) & 0x03) == 3)
 +              if (CPUNST(readl_relaxed(p + PSTR_OFFS), bit) == CPUST_STANDBY)
                        return 1;
  
                mdelay(1);
@@@ -90,8 -78,6 +90,8 @@@ static int __maybe_unused apmu_wrap(in
  #ifdef CONFIG_SMP
  static void apmu_init_cpu(struct resource *res, int cpu, int bit)
  {
 +      u32 x;
 +
        if ((cpu >= ARRAY_SIZE(apmu_cpus)) || apmu_cpus[cpu].iomem)
                return;
  
        apmu_cpus[cpu].bit = bit;
  
        pr_debug("apmu ioremap %d %d %pr\n", cpu, bit, res);
 +
 +      /* Setup for debug mode */
 +      x = readl(apmu_cpus[cpu].iomem + DBGRCR_OFFS);
 +      x |= DBGCPUREN | DBGCPUNREN(bit) | DBGCPUPREN;
 +      writel(x, apmu_cpus[cpu].iomem + DBGRCR_OFFS);
  }
  
  static void apmu_parse_cfg(void (*fn)(struct resource *res, int cpu, int bit),
@@@ -190,7 -171,7 +190,7 @@@ static void apmu_parse_dt(void (*fn)(st
  static void __init shmobile_smp_apmu_setup_boot(void)
  {
        /* install boot code shared by all CPUs */
-       shmobile_boot_fn = virt_to_phys(shmobile_smp_boot);
+       shmobile_boot_fn = __pa_symbol(shmobile_smp_boot);
  }
  
  void __init shmobile_smp_apmu_prepare_cpus(unsigned int max_cpus,
  int shmobile_smp_apmu_boot_secondary(unsigned int cpu, struct task_struct *idle)
  {
        /* For this particular CPU register boot vector */
-       shmobile_smp_hook(cpu, virt_to_phys(secondary_startup), 0);
+       shmobile_smp_hook(cpu, __pa_symbol(secondary_startup), 0);
  
        return apmu_wrap(cpu, apmu_power_on);
  }
@@@ -216,9 -197,21 +216,9 @@@ static void __init shmobile_smp_apmu_pr
        rcar_gen2_pm_init();
  }
  
 -static int shmobile_smp_apmu_boot_secondary_md21(unsigned int cpu,
 -                                               struct task_struct *idle)
 -{
 -      /* Error out when hardware debug mode is enabled */
 -      if (rcar_gen2_read_mode_pins() & BIT(21)) {
 -              pr_warn("Unable to boot CPU%u when MD21 is set\n", cpu);
 -              return -ENOTSUPP;
 -      }
 -
 -      return shmobile_smp_apmu_boot_secondary(cpu, idle);
 -}
 -
  static struct smp_operations apmu_smp_ops __initdata = {
        .smp_prepare_cpus       = shmobile_smp_apmu_prepare_cpus_dt,
 -      .smp_boot_secondary     = shmobile_smp_apmu_boot_secondary_md21,
 +      .smp_boot_secondary     = shmobile_smp_apmu_boot_secondary,
  #ifdef CONFIG_HOTPLUG_CPU
        .cpu_can_disable        = shmobile_smp_cpu_can_disable,
        .cpu_die                = shmobile_smp_apmu_cpu_die,
@@@ -308,7 -301,7 +308,7 @@@ int shmobile_smp_apmu_cpu_kill(unsigne
  #if defined(CONFIG_SUSPEND)
  static int shmobile_smp_apmu_do_suspend(unsigned long cpu)
  {
-       shmobile_smp_hook(cpu, virt_to_phys(cpu_resume), 0);
+       shmobile_smp_hook(cpu, __pa_symbol(cpu_resume), 0);
        shmobile_smp_apmu_cpu_shutdown(cpu);
        cpu_do_idle(); /* WFI selects Core Standby */
        return 1;
index e0ee139fdebfeffbd51918948d3e94909ccc89b6,8c8f2638906704219b54767afb86252f012cb055..9b124c22035f4a336456eaaa5afc92799f4c68d2
  #define UX500_CPU1_JUMPADDR_OFFSET 0x1FF4
  #define UX500_CPU1_WAKEMAGIC_OFFSET 0x1FF0
  
 -static void wakeup_secondary(void)
 +static void __iomem *backupram;
 +
 +static void __init ux500_smp_prepare_cpus(unsigned int max_cpus)
  {
        struct device_node *np;
 -      static void __iomem *backupram;
 +      static void __iomem *scu_base;
 +      unsigned int ncores;
 +      int i;
  
        np = of_find_compatible_node(NULL, NULL, "ste,dbx500-backupram");
        if (!np) {
                return;
        }
  
 -      /*
 -       * write the address of secondary startup into the backup ram register
 -       * at offset 0x1FF4, then write the magic number 0xA1FEED01 to the
 -       * backup ram register at offset 0x1FF0, which is what boot rom code
 -       * is waiting for. This will wake up the secondary core from WFE.
 -       */
 -      writel(__pa_symbol(secondary_startup),
 -             backupram + UX500_CPU1_JUMPADDR_OFFSET);
 -      writel(0xA1FEED01,
 -             backupram + UX500_CPU1_WAKEMAGIC_OFFSET);
 -
 -      /* make sure write buffer is drained */
 -      mb();
 -      iounmap(backupram);
 -}
 -
 -static void __init ux500_smp_prepare_cpus(unsigned int max_cpus)
 -{
 -      struct device_node *np;
 -      static void __iomem *scu_base;
 -      unsigned int ncores;
 -      int i;
 -
        np = of_find_compatible_node(NULL, NULL, "arm,cortex-a9-scu");
        if (!np) {
                pr_err("No SCU base address\n");
  
  static int ux500_boot_secondary(unsigned int cpu, struct task_struct *idle)
  {
 -      wakeup_secondary();
 +      /*
 +       * write the address of secondary startup into the backup ram register
 +       * at offset 0x1FF4, then write the magic number 0xA1FEED01 to the
 +       * backup ram register at offset 0x1FF0, which is what boot rom code
 +       * is waiting for. This will wake up the secondary core from WFE.
 +       */
-       writel(virt_to_phys(secondary_startup),
++      writel(__pa_symbol(secondary_startup),
 +             backupram + UX500_CPU1_JUMPADDR_OFFSET);
 +      writel(0xA1FEED01,
 +             backupram + UX500_CPU1_WAKEMAGIC_OFFSET);
 +
 +      /* make sure write buffer is drained */
 +      mb();
        arch_send_wakeup_ipi_mask(cpumask_of(cpu));
        return 0;
  }
diff --combined arch/arm/mm/Kconfig
index 35e3a56e5d865bc38fed7a86ce91563c08e3dfa7,ac395eca7dee1fc7f082e3e4ebde5613afb3bccf..c6c4c9c8824b0f4b3c354538306d1c195ad7e90d
@@@ -29,6 -29,7 +29,7 @@@ config CPU_ARM720
        select CPU_COPY_V4WT if MMU
        select CPU_CP15_MMU
        select CPU_PABRT_LEGACY
+       select CPU_THUMB_CAPABLE
        select CPU_TLB_V4WT if MMU
        help
          A 32-bit RISC processor with 8kByte Cache, Write Buffer and
@@@ -46,6 -47,7 +47,7 @@@ config CPU_ARM740
        select CPU_CACHE_V4
        select CPU_CP15_MPU
        select CPU_PABRT_LEGACY
+       select CPU_THUMB_CAPABLE
        help
          A 32-bit RISC processor with 8KB cache or 4KB variants,
          write buffer and MPU(Protection Unit) built around
@@@ -79,6 -81,7 +81,7 @@@ config CPU_ARM920
        select CPU_COPY_V4WB if MMU
        select CPU_CP15_MMU
        select CPU_PABRT_LEGACY
+       select CPU_THUMB_CAPABLE
        select CPU_TLB_V4WBI if MMU
        help
          The ARM920T is licensed to be produced by numerous vendors,
@@@ -97,6 -100,7 +100,7 @@@ config CPU_ARM922
        select CPU_COPY_V4WB if MMU
        select CPU_CP15_MMU
        select CPU_PABRT_LEGACY
+       select CPU_THUMB_CAPABLE
        select CPU_TLB_V4WBI if MMU
        help
          The ARM922T is a version of the ARM920T, but with smaller
@@@ -116,6 -120,7 +120,7 @@@ config CPU_ARM925
        select CPU_COPY_V4WB if MMU
        select CPU_CP15_MMU
        select CPU_PABRT_LEGACY
+       select CPU_THUMB_CAPABLE
        select CPU_TLB_V4WBI if MMU
        help
          The ARM925T is a mix between the ARM920T and ARM926T, but with
@@@ -134,6 -139,7 +139,7 @@@ config CPU_ARM926
        select CPU_COPY_V4WB if MMU
        select CPU_CP15_MMU
        select CPU_PABRT_LEGACY
+       select CPU_THUMB_CAPABLE
        select CPU_TLB_V4WBI if MMU
        help
          This is a variant of the ARM920.  It has slightly different
@@@ -170,6 -176,7 +176,7 @@@ config CPU_ARM940
        select CPU_CACHE_VIVT
        select CPU_CP15_MPU
        select CPU_PABRT_LEGACY
+       select CPU_THUMB_CAPABLE
        help
          ARM940T is a member of the ARM9TDMI family of general-
          purpose microprocessors with MPU and separate 4KB
@@@ -188,6 -195,7 +195,7 @@@ config CPU_ARM946
        select CPU_CACHE_VIVT
        select CPU_CP15_MPU
        select CPU_PABRT_LEGACY
+       select CPU_THUMB_CAPABLE
        help
          ARM946E-S is a member of the ARM9E-S family of high-
          performance, 32-bit system-on-chip processor solutions.
@@@ -206,6 -214,7 +214,7 @@@ config CPU_ARM102
        select CPU_COPY_V4WB if MMU
        select CPU_CP15_MMU
        select CPU_PABRT_LEGACY
+       select CPU_THUMB_CAPABLE
        select CPU_TLB_V4WBI if MMU
        help
          The ARM1020 is the 32K cached version of the ARM10 processor,
@@@ -225,6 -234,7 +234,7 @@@ config CPU_ARM1020
        select CPU_COPY_V4WB if MMU
        select CPU_CP15_MMU
        select CPU_PABRT_LEGACY
+       select CPU_THUMB_CAPABLE
        select CPU_TLB_V4WBI if MMU
  
  # ARM1022E
@@@ -236,6 -246,7 +246,7 @@@ config CPU_ARM102
        select CPU_COPY_V4WB if MMU # can probably do better
        select CPU_CP15_MMU
        select CPU_PABRT_LEGACY
+       select CPU_THUMB_CAPABLE
        select CPU_TLB_V4WBI if MMU
        help
          The ARM1022E is an implementation of the ARMv5TE architecture
@@@ -254,6 -265,7 +265,7 @@@ config CPU_ARM102
        select CPU_COPY_V4WB if MMU # can probably do better
        select CPU_CP15_MMU
        select CPU_PABRT_LEGACY
+       select CPU_THUMB_CAPABLE
        select CPU_TLB_V4WBI if MMU
        help
          The ARM1026EJ-S is an implementation of the ARMv5TEJ architecture
@@@ -302,6 -314,7 +314,7 @@@ config CPU_XSCAL
        select CPU_CACHE_VIVT
        select CPU_CP15_MMU
        select CPU_PABRT_LEGACY
+       select CPU_THUMB_CAPABLE
        select CPU_TLB_V4WBI if MMU
  
  # XScale Core Version 3
@@@ -312,6 -325,7 +325,7 @@@ config CPU_XSC
        select CPU_CACHE_VIVT
        select CPU_CP15_MMU
        select CPU_PABRT_LEGACY
+       select CPU_THUMB_CAPABLE
        select CPU_TLB_V4WBI if MMU
        select IO_36
  
@@@ -324,6 -338,7 +338,7 @@@ config CPU_MOHAW
        select CPU_COPY_V4WB if MMU
        select CPU_CP15_MMU
        select CPU_PABRT_LEGACY
+       select CPU_THUMB_CAPABLE
        select CPU_TLB_V4WBI if MMU
  
  # Feroceon
@@@ -335,6 -350,7 +350,7 @@@ config CPU_FEROCEO
        select CPU_COPY_FEROCEON if MMU
        select CPU_CP15_MMU
        select CPU_PABRT_LEGACY
+       select CPU_THUMB_CAPABLE
        select CPU_TLB_FEROCEON if MMU
  
  config CPU_FEROCEON_OLD_ID
@@@ -367,6 -383,7 +383,7 @@@ config CPU_V
        select CPU_CP15_MMU
        select CPU_HAS_ASID if MMU
        select CPU_PABRT_V6
+       select CPU_THUMB_CAPABLE
        select CPU_TLB_V6 if MMU
  
  # ARMv6k
@@@ -381,6 -398,7 +398,7 @@@ config CPU_V6
        select CPU_CP15_MMU
        select CPU_HAS_ASID if MMU
        select CPU_PABRT_V6
+       select CPU_THUMB_CAPABLE
        select CPU_TLB_V6 if MMU
  
  # ARMv7
@@@ -396,6 -414,7 +414,7 @@@ config CPU_V
        select CPU_CP15_MPU if !MMU
        select CPU_HAS_ASID if MMU
        select CPU_PABRT_V7
+       select CPU_THUMB_CAPABLE
        select CPU_TLB_V7 if MMU
  
  # ARMv7M
@@@ -410,11 -429,17 +429,17 @@@ config CPU_V7
  
  config CPU_THUMBONLY
        bool
+       select CPU_THUMB_CAPABLE
        # There are no CPUs available with MMU that don't implement an ARM ISA:
        depends on !MMU
        help
          Select this if your CPU doesn't support the 32 bit ARM instructions.
  
+ config CPU_THUMB_CAPABLE
+       bool
+       help
+         Select this if your CPU can support Thumb mode.
  # Figure out what processor architecture version we should be using.
  # This defines the compiler instruction set which depends on the machine type.
  config CPU_32v3
@@@ -655,11 -680,7 +680,7 @@@ config ARCH_DMA_ADDR_T_64BI
  
  config ARM_THUMB
        bool "Support Thumb user binaries" if !CPU_THUMBONLY
-       depends on CPU_ARM720T || CPU_ARM740T || CPU_ARM920T || CPU_ARM922T || \
-               CPU_ARM925T || CPU_ARM926T || CPU_ARM940T || CPU_ARM946E || \
-               CPU_ARM1020 || CPU_ARM1020E || CPU_ARM1022 || CPU_ARM1026 || \
-               CPU_XSCALE || CPU_XSC3 || CPU_MOHAWK || CPU_V6 || CPU_V6K || \
-               CPU_V7 || CPU_FEROCEON || CPU_V7M
+       depends on CPU_THUMB_CAPABLE
        default y
        help
          Say Y if you want to include kernel support for running user space
@@@ -1051,9 -1072,21 +1072,9 @@@ config ARCH_SUPPORTS_BIG_ENDIA
          This option specifies the architecture can support big endian
          operation.
  
 -config DEBUG_RODATA
 -      bool "Make kernel text and rodata read-only"
 -      depends on MMU && !XIP_KERNEL
 -      default y if CPU_V7
 -      help
 -        If this is set, kernel text and rodata memory will be made
 -        read-only, and non-text kernel memory will be made non-executable.
 -        The tradeoff is that each region is padded to section-size (1MiB)
 -        boundaries (because their permissions are different and splitting
 -        the 1M pages into 4K ones causes TLB performance problems), which
 -        can waste memory.
 -
  config DEBUG_ALIGN_RODATA
        bool "Make rodata strictly non-executable"
 -      depends on DEBUG_RODATA
 +      depends on STRICT_KERNEL_RWX
        default y
        help
          If this is set, rodata will be made explicitly non-executable. This
index e309a5e2c9350788e6e651140d2c1efa03c7e667,afa64ed5e36b7b11aeb702243ab5529ea263c3f3..63eabb06f9f17551695e89efc0ed59e0ce6ba186
@@@ -180,7 -180,7 +180,7 @@@ static void arm_dma_sync_single_for_dev
        __dma_page_cpu_to_dev(page, offset, size, dir);
  }
  
 -struct dma_map_ops arm_dma_ops = {
 +const struct dma_map_ops arm_dma_ops = {
        .alloc                  = arm_dma_alloc,
        .free                   = arm_dma_free,
        .mmap                   = arm_dma_mmap,
@@@ -204,7 -204,7 +204,7 @@@ static int arm_coherent_dma_mmap(struc
                 void *cpu_addr, dma_addr_t dma_addr, size_t size,
                 unsigned long attrs);
  
 -struct dma_map_ops arm_coherent_dma_ops = {
 +const struct dma_map_ops arm_coherent_dma_ops = {
        .alloc                  = arm_coherent_dma_alloc,
        .free                   = arm_coherent_dma_free,
        .mmap                   = arm_coherent_dma_mmap,
@@@ -349,7 -349,7 +349,7 @@@ static void __dma_free_buffer(struct pa
  static void *__alloc_from_contiguous(struct device *dev, size_t size,
                                     pgprot_t prot, struct page **ret_page,
                                     const void *caller, bool want_vaddr,
 -                                   int coherent_flag);
 +                                   int coherent_flag, gfp_t gfp);
  
  static void *__alloc_remap_buffer(struct device *dev, size_t size, gfp_t gfp,
                                 pgprot_t prot, struct page **ret_page,
@@@ -420,8 -420,7 +420,8 @@@ static int __init atomic_pool_init(void
         */
        if (dev_get_cma_area(NULL))
                ptr = __alloc_from_contiguous(NULL, atomic_pool_size, prot,
 -                                    &page, atomic_pool_init, true, NORMAL);
 +                                    &page, atomic_pool_init, true, NORMAL,
 +                                    GFP_KERNEL);
        else
                ptr = __alloc_remap_buffer(NULL, atomic_pool_size, gfp, prot,
                                           &page, atomic_pool_init, true);
@@@ -595,14 -594,14 +595,14 @@@ static int __free_from_pool(void *start
  static void *__alloc_from_contiguous(struct device *dev, size_t size,
                                     pgprot_t prot, struct page **ret_page,
                                     const void *caller, bool want_vaddr,
 -                                   int coherent_flag)
 +                                   int coherent_flag, gfp_t gfp)
  {
        unsigned long order = get_order(size);
        size_t count = size >> PAGE_SHIFT;
        struct page *page;
        void *ptr = NULL;
  
 -      page = dma_alloc_from_contiguous(dev, count, order);
 +      page = dma_alloc_from_contiguous(dev, count, order, gfp);
        if (!page)
                return NULL;
  
@@@ -656,7 -655,7 +656,7 @@@ static inline pgprot_t __get_dma_pgprot
  #define __get_dma_pgprot(attrs, prot)                         __pgprot(0)
  #define __alloc_remap_buffer(dev, size, gfp, prot, ret, c, wv)        NULL
  #define __alloc_from_pool(size, ret_page)                     NULL
 -#define __alloc_from_contiguous(dev, size, prot, ret, c, wv, coherent_flag)   NULL
 +#define __alloc_from_contiguous(dev, size, prot, ret, c, wv, coherent_flag, gfp)      NULL
  #define __free_from_pool(cpu_addr, size)                      do { } while (0)
  #define __free_from_contiguous(dev, page, cpu_addr, size, wv) do { } while (0)
  #define __dma_free_remap(cpu_addr, size)                      do { } while (0)
@@@ -698,8 -697,7 +698,8 @@@ static void *cma_allocator_alloc(struc
  {
        return __alloc_from_contiguous(args->dev, args->size, args->prot,
                                       ret_page, args->caller,
 -                                     args->want_vaddr, args->coherent_flag);
 +                                     args->want_vaddr, args->coherent_flag,
 +                                     args->gfp);
  }
  
  static void cma_allocator_free(struct arm_dma_free_args *args)
@@@ -870,6 -868,9 +870,9 @@@ static int __arm_dma_mmap(struct devic
                                      vma->vm_end - vma->vm_start,
                                      vma->vm_page_prot);
        }
+ #else
+       ret = vm_iomap_memory(vma, vma->vm_start,
+                             (vma->vm_end - vma->vm_start));
  #endif        /* CONFIG_MMU */
  
        return ret;
@@@ -1069,7 -1070,7 +1072,7 @@@ static void __dma_page_dev_to_cpu(struc
  int arm_dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
                enum dma_data_direction dir, unsigned long attrs)
  {
 -      struct dma_map_ops *ops = get_dma_ops(dev);
 +      const struct dma_map_ops *ops = get_dma_ops(dev);
        struct scatterlist *s;
        int i, j;
  
  void arm_dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nents,
                enum dma_data_direction dir, unsigned long attrs)
  {
 -      struct dma_map_ops *ops = get_dma_ops(dev);
 +      const struct dma_map_ops *ops = get_dma_ops(dev);
        struct scatterlist *s;
  
        int i;
  void arm_dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg,
                        int nents, enum dma_data_direction dir)
  {
 -      struct dma_map_ops *ops = get_dma_ops(dev);
 +      const struct dma_map_ops *ops = get_dma_ops(dev);
        struct scatterlist *s;
        int i;
  
  void arm_dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg,
                        int nents, enum dma_data_direction dir)
  {
 -      struct dma_map_ops *ops = get_dma_ops(dev);
 +      const struct dma_map_ops *ops = get_dma_ops(dev);
        struct scatterlist *s;
        int i;
  
@@@ -1173,25 -1174,6 +1176,25 @@@ core_initcall(dma_debug_do_init)
  
  #ifdef CONFIG_ARM_DMA_USE_IOMMU
  
 +static int __dma_info_to_prot(enum dma_data_direction dir, unsigned long attrs)
 +{
 +      int prot = 0;
 +
 +      if (attrs & DMA_ATTR_PRIVILEGED)
 +              prot |= IOMMU_PRIV;
 +
 +      switch (dir) {
 +      case DMA_BIDIRECTIONAL:
 +              return prot | IOMMU_READ | IOMMU_WRITE;
 +      case DMA_TO_DEVICE:
 +              return prot | IOMMU_READ;
 +      case DMA_FROM_DEVICE:
 +              return prot | IOMMU_WRITE;
 +      default:
 +              return prot;
 +      }
 +}
 +
  /* IOMMU */
  
  static int extend_iommu_mapping(struct dma_iommu_mapping *mapping);
@@@ -1314,7 -1296,7 +1317,7 @@@ static struct page **__iommu_alloc_buff
                unsigned long order = get_order(size);
                struct page *page;
  
 -              page = dma_alloc_from_contiguous(dev, count, order);
 +              page = dma_alloc_from_contiguous(dev, count, order, gfp);
                if (!page)
                        goto error;
  
@@@ -1415,8 -1397,7 +1418,8 @@@ __iommu_alloc_remap(struct page **pages
   * Create a mapping in device IO address space for specified pages
   */
  static dma_addr_t
 -__iommu_create_mapping(struct device *dev, struct page **pages, size_t size)
 +__iommu_create_mapping(struct device *dev, struct page **pages, size_t size,
 +                     unsigned long attrs)
  {
        struct dma_iommu_mapping *mapping = to_dma_iommu_mapping(dev);
        unsigned int count = PAGE_ALIGN(size) >> PAGE_SHIFT;
  
                len = (j - i) << PAGE_SHIFT;
                ret = iommu_map(mapping->domain, iova, phys, len,
 -                              IOMMU_READ|IOMMU_WRITE);
 +                              __dma_info_to_prot(DMA_BIDIRECTIONAL, attrs));
                if (ret < 0)
                        goto fail;
                iova += len;
@@@ -1498,8 -1479,7 +1501,8 @@@ static struct page **__iommu_get_pages(
  }
  
  static void *__iommu_alloc_simple(struct device *dev, size_t size, gfp_t gfp,
 -                                dma_addr_t *handle, int coherent_flag)
 +                                dma_addr_t *handle, int coherent_flag,
 +                                unsigned long attrs)
  {
        struct page *page;
        void *addr;
        if (!addr)
                return NULL;
  
 -      *handle = __iommu_create_mapping(dev, &page, size);
 +      *handle = __iommu_create_mapping(dev, &page, size, attrs);
        if (*handle == DMA_ERROR_CODE)
                goto err_mapping;
  
@@@ -1545,7 -1525,7 +1548,7 @@@ static void *__arm_iommu_alloc_attrs(st
  
        if (coherent_flag  == COHERENT || !gfpflags_allow_blocking(gfp))
                return __iommu_alloc_simple(dev, size, gfp, handle,
 -                                          coherent_flag);
 +                                          coherent_flag, attrs);
  
        /*
         * Following is a work-around (a.k.a. hack) to prevent pages
        if (!pages)
                return NULL;
  
 -      *handle = __iommu_create_mapping(dev, pages, size);
 +      *handle = __iommu_create_mapping(dev, pages, size, attrs);
        if (*handle == DMA_ERROR_CODE)
                goto err_buffer;
  
@@@ -1695,6 -1675,27 +1698,6 @@@ static int arm_iommu_get_sgtable(struc
                                         GFP_KERNEL);
  }
  
 -static int __dma_direction_to_prot(enum dma_data_direction dir)
 -{
 -      int prot;
 -
 -      switch (dir) {
 -      case DMA_BIDIRECTIONAL:
 -              prot = IOMMU_READ | IOMMU_WRITE;
 -              break;
 -      case DMA_TO_DEVICE:
 -              prot = IOMMU_READ;
 -              break;
 -      case DMA_FROM_DEVICE:
 -              prot = IOMMU_WRITE;
 -              break;
 -      default:
 -              prot = 0;
 -      }
 -
 -      return prot;
 -}
 -
  /*
   * Map a part of the scatter-gather list into contiguous io address space
   */
@@@ -1724,7 -1725,7 +1727,7 @@@ static int __map_sg_chunk(struct devic
                if (!is_coherent && (attrs & DMA_ATTR_SKIP_CPU_SYNC) == 0)
                        __dma_page_cpu_to_dev(sg_page(s), s->offset, s->length, dir);
  
 -              prot = __dma_direction_to_prot(dir);
 +              prot = __dma_info_to_prot(dir, attrs);
  
                ret = iommu_map(mapping->domain, iova, phys, len, prot);
                if (ret < 0)
@@@ -1932,7 -1933,7 +1935,7 @@@ static dma_addr_t arm_coherent_iommu_ma
        if (dma_addr == DMA_ERROR_CODE)
                return dma_addr;
  
 -      prot = __dma_direction_to_prot(dir);
 +      prot = __dma_info_to_prot(dir, attrs);
  
        ret = iommu_map(mapping->domain, dma_addr, page_to_phys(page), len, prot);
        if (ret < 0)
@@@ -2038,7 -2039,7 +2041,7 @@@ static dma_addr_t arm_iommu_map_resourc
        if (dma_addr == DMA_ERROR_CODE)
                return dma_addr;
  
 -      prot = __dma_direction_to_prot(dir) | IOMMU_MMIO;
 +      prot = __dma_info_to_prot(dir, attrs) | IOMMU_MMIO;
  
        ret = iommu_map(mapping->domain, dma_addr, addr, len, prot);
        if (ret < 0)
@@@ -2101,7 -2102,7 +2104,7 @@@ static void arm_iommu_sync_single_for_d
        __dma_page_cpu_to_dev(page, offset, size, dir);
  }
  
 -struct dma_map_ops iommu_ops = {
 +const struct dma_map_ops iommu_ops = {
        .alloc          = arm_iommu_alloc_attrs,
        .free           = arm_iommu_free_attrs,
        .mmap           = arm_iommu_mmap_attrs,
        .unmap_resource         = arm_iommu_unmap_resource,
  };
  
 -struct dma_map_ops iommu_coherent_ops = {
 +const struct dma_map_ops iommu_coherent_ops = {
        .alloc          = arm_coherent_iommu_alloc_attrs,
        .free           = arm_coherent_iommu_free_attrs,
        .mmap           = arm_coherent_iommu_mmap_attrs,
@@@ -2321,7 -2322,7 +2324,7 @@@ void arm_iommu_detach_device(struct dev
  }
  EXPORT_SYMBOL_GPL(arm_iommu_detach_device);
  
 -static struct dma_map_ops *arm_get_iommu_dma_map_ops(bool coherent)
 +static const struct dma_map_ops *arm_get_iommu_dma_map_ops(bool coherent)
  {
        return coherent ? &iommu_coherent_ops : &iommu_ops;
  }
@@@ -2376,7 -2377,7 +2379,7 @@@ static void arm_teardown_iommu_dma_ops(
  
  #endif        /* CONFIG_ARM_DMA_USE_IOMMU */
  
 -static struct dma_map_ops *arm_get_dma_map_ops(bool coherent)
 +static const struct dma_map_ops *arm_get_dma_map_ops(bool coherent)
  {
        return coherent ? &arm_coherent_dma_ops : &arm_dma_ops;
  }
  void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
                        const struct iommu_ops *iommu, bool coherent)
  {
 -      struct dma_map_ops *dma_ops;
 +      const struct dma_map_ops *dma_ops;
  
        dev->archdata.dma_coherent = coherent;
        if (arm_setup_iommu_dma_ops(dev, dma_base, size, iommu))
diff --combined arch/arm/mm/init.c
index 4be0bee4c35700aacbaaa3994d5ae4a7ce92bfb5,d1e26610977d6f084f986699f01b352ef7d37935..bf4d3bc41a7a85e5144eeecb1231418f9870f54e
@@@ -27,6 -27,7 +27,7 @@@
  #include <asm/cp15.h>
  #include <asm/mach-types.h>
  #include <asm/memblock.h>
+ #include <asm/memory.h>
  #include <asm/prom.h>
  #include <asm/sections.h>
  #include <asm/setup.h>
@@@ -227,41 -228,59 +228,59 @@@ phys_addr_t __init arm_memblock_steal(p
        return phys;
  }
  
void __init arm_memblock_init(const struct machine_desc *mdesc)
static void __init arm_initrd_init(void)
  {
-       /* Register the kernel text, kernel data and initrd with memblock. */
- #ifdef CONFIG_XIP_KERNEL
-       memblock_reserve(__pa(_sdata), _end - _sdata);
- #else
-       memblock_reserve(__pa(_stext), _end - _stext);
- #endif
  #ifdef CONFIG_BLK_DEV_INITRD
+       phys_addr_t start;
+       unsigned long size;
        /* FDT scan will populate initrd_start */
        if (initrd_start && !phys_initrd_size) {
                phys_initrd_start = __virt_to_phys(initrd_start);
                phys_initrd_size = initrd_end - initrd_start;
        }
        initrd_start = initrd_end = 0;
-       if (phys_initrd_size &&
-           !memblock_is_region_memory(phys_initrd_start, phys_initrd_size)) {
+       if (!phys_initrd_size)
+               return;
+       /*
+        * Round the memory region to page boundaries as per free_initrd_mem()
+        * This allows us to detect whether the pages overlapping the initrd
+        * are in use, but more importantly, reserves the entire set of pages
+        * as we don't want these pages allocated for other purposes.
+        */
+       start = round_down(phys_initrd_start, PAGE_SIZE);
+       size = phys_initrd_size + (phys_initrd_start - start);
+       size = round_up(size, PAGE_SIZE);
+       if (!memblock_is_region_memory(start, size)) {
                pr_err("INITRD: 0x%08llx+0x%08lx is not a memory region - disabling initrd\n",
-                      (u64)phys_initrd_start, phys_initrd_size);
-               phys_initrd_start = phys_initrd_size = 0;
+                      (u64)start, size);
+               return;
        }
-       if (phys_initrd_size &&
-           memblock_is_region_reserved(phys_initrd_start, phys_initrd_size)) {
+       if (memblock_is_region_reserved(start, size)) {
                pr_err("INITRD: 0x%08llx+0x%08lx overlaps in-use memory region - disabling initrd\n",
-                      (u64)phys_initrd_start, phys_initrd_size);
-               phys_initrd_start = phys_initrd_size = 0;
+                      (u64)start, size);
+               return;
        }
-       if (phys_initrd_size) {
-               memblock_reserve(phys_initrd_start, phys_initrd_size);
  
-               /* Now convert initrd to virtual addresses */
-               initrd_start = __phys_to_virt(phys_initrd_start);
-               initrd_end = initrd_start + phys_initrd_size;
-       }
+       memblock_reserve(start, size);
+       /* Now convert initrd to virtual addresses */
+       initrd_start = __phys_to_virt(phys_initrd_start);
+       initrd_end = initrd_start + phys_initrd_size;
  #endif
+ }
+ void __init arm_memblock_init(const struct machine_desc *mdesc)
+ {
+       /* Register the kernel text, kernel data and initrd with memblock. */
+       memblock_reserve(__pa(KERNEL_START), KERNEL_END - KERNEL_START);
+       arm_initrd_init();
  
        arm_mm_memblock_reserve();
  
@@@ -521,8 -540,7 +540,7 @@@ void __init mem_init(void
                        "      .data : 0x%p" " - 0x%p" "   (%4td kB)\n"
                        "       .bss : 0x%p" " - 0x%p" "   (%4td kB)\n",
  
-                       MLK(UL(CONFIG_VECTORS_BASE), UL(CONFIG_VECTORS_BASE) +
-                               (PAGE_SIZE)),
+                       MLK(VECTORS_BASE, VECTORS_BASE + PAGE_SIZE),
  #ifdef CONFIG_HAVE_TCM
                        MLK(DTCM_OFFSET, (unsigned long) dtcm_end),
                        MLK(ITCM_OFFSET, (unsigned long) itcm_end),
        }
  }
  
 -#ifdef CONFIG_DEBUG_RODATA
 +#ifdef CONFIG_STRICT_KERNEL_RWX
  struct section_perm {
        const char *name;
        unsigned long start;
@@@ -741,7 -759,7 +759,7 @@@ void set_kernel_text_ro(void
  
  #else
  static inline void fix_kernmem_perms(void) { }
 -#endif /* CONFIG_DEBUG_RODATA */
 +#endif /* CONFIG_STRICT_KERNEL_RWX */
  
  void free_tcmmem(void)
  {