summaryrefslogtreecommitdiffstats
path: root/arch/arm
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@woody.osdl.org>2006-12-13 15:58:32 -0800
committerLinus Torvalds <torvalds@woody.osdl.org>2006-12-13 15:58:32 -0800
commite05135d1550e73f722ae92909f9c9f44b305e9e2 (patch)
tree2348efab16091746012672c65b8b5140792a2da1 /arch/arm
parent8eefb2b7ad6195f4324629f35be0b9443cd8ee96 (diff)
parente9ccb79927225d8cd8d022a7c09bfb2fad935b89 (diff)
Merge branch 'for-linus' of master.kernel.org:/home/rmk/linux-2.6-arm
* 'for-linus' of master.kernel.org:/home/rmk/linux-2.6-arm: [ARM] 4017/1: [Jornada7xx] - Updating Jornada720.c [ARM] 3992/1: i.MX/MX1 CPU Frequency scaling support [ARM] Provide a method to alter the control register [ARM] 4016/1: prefetch macro is wrong wrt gcc's "delete-null-pointer-checks" [ARM] Remove empty fixup function [ARM] 4014/1: include drivers/hid/Kconfig [ARM] 4013/1: clocksource driver for netx [ARM] 4012/1: Clocksource for pxa [ARM] Clean up ioremap code [ARM] Unuse another Linux PTE bit [ARM] Clean up KERNEL_RAM_ADDR [ARM] Add sys_*at syscalls [ARM] 4004/1: S3C24XX: UDC remove implict addition of VA to regs [ARM] Formalise the ARMv6 processor name string [ARM] Handle HWCAP_VFP in VFP support code [ARM] 4011/1: AT91SAM9260: Fix compilation with NAND driver [ARM] 4010/1: AT91SAM9260-EK board: Prepare for MACB Ethernet support
Diffstat (limited to 'arch/arm')
-rw-r--r--arch/arm/Kconfig13
-rw-r--r--arch/arm/kernel/calls.S13
-rw-r--r--arch/arm/kernel/head.S19
-rw-r--r--arch/arm/kernel/setup.c3
-rw-r--r--arch/arm/mach-at91rm9200/at91sam9260_devices.c1
-rw-r--r--arch/arm/mach-at91rm9200/board-sam9260ek.c1
-rw-r--r--arch/arm/mach-imx/Makefile2
-rw-r--r--arch/arm/mach-imx/cpufreq.c287
-rw-r--r--arch/arm/mach-netx/time.c42
-rw-r--r--arch/arm/mach-pxa/time.c45
-rw-r--r--arch/arm/mach-pxa/trizeps4.c5
-rw-r--r--arch/arm/mach-sa1100/jornada720.c229
-rw-r--r--arch/arm/mm/consistent.c2
-rw-r--r--arch/arm/mm/copypage-v4mc.c2
-rw-r--r--arch/arm/mm/copypage-v6.c6
-rw-r--r--arch/arm/mm/copypage-xscale.c2
-rw-r--r--arch/arm/mm/fault-armv.c2
-rw-r--r--arch/arm/mm/flush.c2
-rw-r--r--arch/arm/mm/ioremap.c100
-rw-r--r--arch/arm/mm/mmu.c8
-rw-r--r--arch/arm/mm/pgd.c2
-rw-r--r--arch/arm/mm/proc-arm1020.S4
-rw-r--r--arch/arm/mm/proc-arm1020e.S4
-rw-r--r--arch/arm/mm/proc-arm1022.S6
-rw-r--r--arch/arm/mm/proc-arm1026.S6
-rw-r--r--arch/arm/mm/proc-arm6_7.S10
-rw-r--r--arch/arm/mm/proc-arm720.S6
-rw-r--r--arch/arm/mm/proc-arm920.S6
-rw-r--r--arch/arm/mm/proc-arm922.S6
-rw-r--r--arch/arm/mm/proc-arm925.S6
-rw-r--r--arch/arm/mm/proc-arm926.S8
-rw-r--r--arch/arm/mm/proc-sa110.S6
-rw-r--r--arch/arm/mm/proc-sa1100.S6
-rw-r--r--arch/arm/mm/proc-syms.c2
-rw-r--r--arch/arm/mm/proc-v6.S39
-rw-r--r--arch/arm/mm/proc-xsc3.S6
-rw-r--r--arch/arm/mm/proc-xscale.S6
-rw-r--r--arch/arm/vfp/vfpmodule.c26
38 files changed, 721 insertions, 218 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index aa1d400d721..6783c2e5512 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -740,7 +740,7 @@ config XIP_PHYS_ADDR
endmenu
-if (ARCH_SA1100 || ARCH_INTEGRATOR || ARCH_OMAP)
+if (ARCH_SA1100 || ARCH_INTEGRATOR || ARCH_OMAP || ARCH_IMX )
menu "CPU Frequency scaling"
@@ -767,6 +767,15 @@ config CPU_FREQ_INTEGRATOR
If in doubt, say Y.
+config CPU_FREQ_IMX
+ tristate "CPUfreq driver for i.MX CPUs"
+ depends on ARCH_IMX && CPU_FREQ
+ default n
+ help
+ This enables the CPUfreq driver for i.MX CPUs.
+
+ If in doubt, say N.
+
endmenu
endif
@@ -945,6 +954,8 @@ source "drivers/video/Kconfig"
source "sound/Kconfig"
+source "drivers/hid/Kconfig"
+
source "drivers/usb/Kconfig"
source "drivers/mmc/Kconfig"
diff --git a/arch/arm/kernel/calls.S b/arch/arm/kernel/calls.S
index 3173924a9b6..e8f74363328 100644
--- a/arch/arm/kernel/calls.S
+++ b/arch/arm/kernel/calls.S
@@ -331,6 +331,19 @@
CALL(sys_mbind)
/* 320 */ CALL(sys_get_mempolicy)
CALL(sys_set_mempolicy)
+ CALL(sys_openat)
+ CALL(sys_mkdirat)
+ CALL(sys_mknodat)
+/* 325 */ CALL(sys_fchownat)
+ CALL(sys_futimesat)
+ CALL(sys_fstatat64)
+ CALL(sys_unlinkat)
+ CALL(sys_renameat)
+/* 330 */ CALL(sys_linkat)
+ CALL(sys_symlinkat)
+ CALL(sys_readlinkat)
+ CALL(sys_fchmodat)
+ CALL(sys_faccessat)
#ifndef syscalls_counted
.equ syscalls_padding, ((NR_syscalls + 3) & ~3) - NR_syscalls
#define syscalls_counted
diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S
index bda0748ffb0..d994561816a 100644
--- a/arch/arm/kernel/head.S
+++ b/arch/arm/kernel/head.S
@@ -22,30 +22,31 @@
#include <asm/thread_info.h>
#include <asm/system.h>
-#define KERNEL_RAM_ADDR (PAGE_OFFSET + TEXT_OFFSET)
+#define KERNEL_RAM_VADDR (PAGE_OFFSET + TEXT_OFFSET)
+#define KERNEL_RAM_PADDR (PHYS_OFFSET + TEXT_OFFSET)
/*
* swapper_pg_dir is the virtual address of the initial page table.
- * We place the page tables 16K below KERNEL_RAM_ADDR. Therefore, we must
- * make sure that KERNEL_RAM_ADDR is correctly set. Currently, we expect
+ * We place the page tables 16K below KERNEL_RAM_VADDR. Therefore, we must
+ * make sure that KERNEL_RAM_VADDR is correctly set. Currently, we expect
* the least significant 16 bits to be 0x8000, but we could probably
- * relax this restriction to KERNEL_RAM_ADDR >= PAGE_OFFSET + 0x4000.
+ * relax this restriction to KERNEL_RAM_VADDR >= PAGE_OFFSET + 0x4000.
*/
-#if (KERNEL_RAM_ADDR & 0xffff) != 0x8000
-#error KERNEL_RAM_ADDR must start at 0xXXXX8000
+#if (KERNEL_RAM_VADDR & 0xffff) != 0x8000
+#error KERNEL_RAM_VADDR must start at 0xXXXX8000
#endif
.globl swapper_pg_dir
- .equ swapper_pg_dir, KERNEL_RAM_ADDR - 0x4000
+ .equ swapper_pg_dir, KERNEL_RAM_VADDR - 0x4000
.macro pgtbl, rd
- ldr \rd, =(__virt_to_phys(KERNEL_RAM_ADDR - 0x4000))
+ ldr \rd, =(KERNEL_RAM_PADDR - 0x4000)
.endm
#ifdef CONFIG_XIP_KERNEL
#define TEXTADDR XIP_VIRT_ADDR(CONFIG_XIP_PHYS_ADDR)
#else
-#define TEXTADDR KERNEL_RAM_ADDR
+#define TEXTADDR KERNEL_RAM_VADDR
#endif
/*
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index 238dd9b6db8..cf2bd424280 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -354,9 +354,6 @@ static void __init setup_processor(void)
#ifndef CONFIG_ARM_THUMB
elf_hwcap &= ~HWCAP_THUMB;
#endif
-#ifndef CONFIG_VFP
- elf_hwcap &= ~HWCAP_VFP;
-#endif
cpu_proc_init();
}
diff --git a/arch/arm/mach-at91rm9200/at91sam9260_devices.c b/arch/arm/mach-at91rm9200/at91sam9260_devices.c
index a6c596dc451..f42d3a40ec3 100644
--- a/arch/arm/mach-at91rm9200/at91sam9260_devices.c
+++ b/arch/arm/mach-at91rm9200/at91sam9260_devices.c
@@ -18,6 +18,7 @@
#include <asm/arch/gpio.h>
#include <asm/arch/at91sam9260.h>
#include <asm/arch/at91sam926x_mc.h>
+#include <asm/arch/at91sam9260_matrix.h>
#include "generic.h"
diff --git a/arch/arm/mach-at91rm9200/board-sam9260ek.c b/arch/arm/mach-at91rm9200/board-sam9260ek.c
index ffca9bdec37..da5d58ac870 100644
--- a/arch/arm/mach-at91rm9200/board-sam9260ek.c
+++ b/arch/arm/mach-at91rm9200/board-sam9260ek.c
@@ -119,6 +119,7 @@ static struct spi_board_info ek_spi_devices[] = {
* MACB Ethernet device
*/
static struct __initdata eth_platform_data ek_macb_data = {
+ .phy_irq_pin = AT91_PIN_PA7,
.is_rmii = 1,
};
diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile
index 0b27d79f2ef..02272aa36e9 100644
--- a/arch/arm/mach-imx/Makefile
+++ b/arch/arm/mach-imx/Makefile
@@ -9,6 +9,8 @@
obj-y += irq.o time.o dma.o generic.o
+obj-$(CONFIG_CPU_FREQ_IMX) += cpufreq.o
+
# Specific board support
obj-$(CONFIG_ARCH_MX1ADS) += mx1ads.o
diff --git a/arch/arm/mach-imx/cpufreq.c b/arch/arm/mach-imx/cpufreq.c
new file mode 100644
index 00000000000..ac5f9989566
--- /dev/null
+++ b/arch/arm/mach-imx/cpufreq.c
@@ -0,0 +1,287 @@
+/*
+ * cpu.c: clock scaling for the iMX
+ *
+ * Copyright (C) 2000 2001, The Delft University of Technology
+ * Copyright (c) 2004 Sascha Hauer <sascha@saschahauer.de>
+ * Copyright (C) 2006 Inky Lung <ilung@cwlinux.com>
+ * Copyright (C) 2006 Pavel Pisa, PiKRON <ppisa@pikron.com>
+ *
+ * Based on SA1100 version written by:
+ * - Johan Pouwelse (J.A.Pouwelse@its.tudelft.nl): initial version
+ * - Erik Mouw (J.A.K.Mouw@its.tudelft.nl):
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+/*#define DEBUG*/
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/cpufreq.h>
+#include <asm/system.h>
+
+#include <asm/hardware.h>
+
+#include "generic.h"
+
+#ifndef __val2mfld
+#define __val2mfld(mask,val) (((mask)&~((mask)<<1))*(val)&(mask))
+#endif
+#ifndef __mfld2val
+#define __mfld2val(mask,val) (((val)&(mask))/((mask)&~((mask)<<1)))
+#endif
+
+#define CR_920T_CLOCK_MODE 0xC0000000
+#define CR_920T_FASTBUS_MODE 0x00000000
+#define CR_920T_ASYNC_MODE 0xC0000000
+
+static u32 mpctl0_at_boot;
+
+static void imx_set_async_mode(void)
+{
+ adjust_cr(CR_920T_CLOCK_MODE, CR_920T_ASYNC_MODE);
+}
+
+static void imx_set_fastbus_mode(void)
+{
+ adjust_cr(CR_920T_CLOCK_MODE, CR_920T_FASTBUS_MODE);
+}
+
+static void imx_set_mpctl0(u32 mpctl0)
+{
+ unsigned long flags;
+
+ if (mpctl0 == 0) {
+ local_irq_save(flags);
+ CSCR &= ~CSCR_MPEN;
+ local_irq_restore(flags);
+ return;
+ }
+
+ local_irq_save(flags);
+ MPCTL0 = mpctl0;
+ CSCR |= CSCR_MPEN;
+ local_irq_restore(flags);
+}
+
+/**
+ * imx_compute_mpctl - compute new PLL parameters
+ * @new_mpctl: pointer to location assigned by new PLL control register value
+ * @cur_mpctl: current PLL control register parameters
+ * @freq: required frequency in Hz
+ * @relation: is one of %CPUFREQ_RELATION_L (supremum)
+ * and %CPUFREQ_RELATION_H (infimum)
+ */
+long imx_compute_mpctl(u32 *new_mpctl, u32 cur_mpctl, unsigned long freq, int relation)
+{
+ u32 f_ref = (CSCR & CSCR_SYSTEM_SEL) ? 16000000 : (CLK32 * 512);
+ u32 mfi;
+ u32 mfn;
+ u32 mfd;
+ u32 pd;
+ unsigned long long ll;
+ long l;
+ long quot;
+
+ /* Fdppl=2*Fref*(MFI+MFN/(MFD+1))/(PD+1) */
+ /* PD=<0,15>, MFD=<1,1023>, MFI=<5,15> MFN=<0,1022> */
+
+ if (cur_mpctl) {
+ mfd = ((cur_mpctl >> 16) & 0x3ff) + 1;
+ pd = ((cur_mpctl >> 26) & 0xf) + 1;
+ } else {
+ pd=2; mfd=313;
+ }
+
+ /* pd=2; mfd=313; mfi=8; mfn=183; */
+ /* (MFI+MFN/(MFD)) = Fdppl / (2*Fref) * (PD); */
+
+ quot = (f_ref + (1 << 9)) >> 10;
+ l = (freq * pd + quot) / (2 * quot);
+ mfi = l >> 10;
+ mfn = ((l & ((1 << 10) - 1)) * mfd + (1 << 9)) >> 10;
+
+ mfd -= 1;
+ pd -= 1;
+
+ *new_mpctl = ((mfi & 0xf) << 10) | (mfn & 0x3ff) | ((mfd & 0x3ff) << 16)
+ | ((pd & 0xf) << 26);
+
+ ll = 2 * (unsigned long long)f_ref * ( (mfi<<16) + (mfn<<16) / (mfd+1) );
+ quot = (pd+1) * (1<<16);
+ ll += quot / 2;
+ do_div(ll, quot);
+ freq = ll;
+
+ pr_debug(KERN_DEBUG "imx: new PLL parameters pd=%d mfd=%d mfi=%d mfn=%d, freq=%ld\n",
+ pd, mfd, mfi, mfn, freq);
+
+ return freq;
+}
+
+
+static int imx_verify_speed(struct cpufreq_policy *policy)
+{
+ if (policy->cpu != 0)
+ return -EINVAL;
+
+ cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq, policy->cpuinfo.max_freq);
+
+ return 0;
+}
+
+static unsigned int imx_get_speed(unsigned int cpu)
+{
+ unsigned int freq;
+ unsigned int cr;
+ unsigned int cscr;
+ unsigned int bclk_div;
+
+ if (cpu)
+ return 0;
+
+ cscr = CSCR;
+ bclk_div = __mfld2val(CSCR_BCLK_DIV, cscr) + 1;
+ cr = get_cr();
+
+ if((cr & CR_920T_CLOCK_MODE) == CR_920T_FASTBUS_MODE) {
+ freq = imx_get_system_clk();
+ freq = (freq + bclk_div/2) / bclk_div;
+ } else {
+ freq = imx_get_mcu_clk();
+ if (cscr & CSCR_MPU_PRESC)
+ freq /= 2;
+ }
+
+ freq = (freq + 500) / 1000;
+
+ return freq;
+}
+
+static int imx_set_target(struct cpufreq_policy *policy,
+ unsigned int target_freq,
+ unsigned int relation)
+{
+ struct cpufreq_freqs freqs;
+ u32 mpctl0 = 0;
+ u32 cscr;
+ unsigned long flags;
+ long freq;
+ long sysclk;
+ unsigned int bclk_div = 1;
+
+ freq = target_freq * 1000;
+
+ pr_debug(KERN_DEBUG "imx: requested frequency %ld Hz, mpctl0 at boot 0x%08x\n",
+ freq, mpctl0_at_boot);
+
+ sysclk = imx_get_system_clk();
+
+ if (freq > sysclk + 1000000) {
+ freq = imx_compute_mpctl(&mpctl0, mpctl0_at_boot, freq, relation);
+ if (freq < 0) {
+ printk(KERN_WARNING "imx: target frequency %ld Hz cannot be set\n", freq);
+ return -EINVAL;
+ }
+ } else {
+ if(freq + 1000 < sysclk) {
+ if (relation == CPUFREQ_RELATION_L)
+ bclk_div = (sysclk - 1000) / freq;
+ else
+ bclk_div = (sysclk + freq + 1000) / freq;
+
+ if(bclk_div > 16)
+ bclk_div = 16;
+ }
+ freq = (sysclk + bclk_div / 2) / bclk_div;
+ }
+
+ freqs.old = imx_get_speed(0);
+ freqs.new = (freq + 500) / 1000;
+ freqs.cpu = 0;
+ freqs.flags = 0;
+
+ cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
+
+ local_irq_save(flags);
+
+ imx_set_fastbus_mode();
+
+ imx_set_mpctl0(mpctl0);
+
+ cscr = CSCR;
+ cscr &= ~CSCR_BCLK_DIV;
+ cscr |= __val2mfld(CSCR_BCLK_DIV, bclk_div - 1);
+ CSCR = cscr;
+
+ if(mpctl0) {
+ CSCR |= CSCR_MPLL_RESTART;
+
+ /* Wait until MPLL is stablized */
+ while( CSCR & CSCR_MPLL_RESTART );
+
+ imx_set_async_mode();
+ }
+
+ local_irq_restore(flags);
+
+ cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
+
+ pr_debug(KERN_INFO "imx: set frequency %ld Hz, running from %s\n",
+ freq, mpctl0? "MPLL": "SPLL");
+
+ return 0;
+}
+
+static int __init imx_cpufreq_driver_init(struct cpufreq_policy *policy)
+{
+ printk(KERN_INFO "i.MX cpu freq change driver v1.0\n");
+
+ if (policy->cpu != 0)
+ return -EINVAL;
+
+ policy->cur = policy->min = policy->max = imx_get_speed(0);
+ policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
+ policy->cpuinfo.min_freq = 8000;
+ policy->cpuinfo.max_freq = 200000;
+ policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL;
+ return 0;
+}
+
+static struct cpufreq_driver imx_driver = {
+ .flags = CPUFREQ_STICKY,
+ .verify = imx_verify_speed,
+ .target = imx_set_target,
+ .get = imx_get_speed,
+ .init = imx_cpufreq_driver_init,
+ .name = "imx",
+};
+
+static int __init imx_cpufreq_init(void)
+{
+
+ mpctl0_at_boot = 0;
+
+ if((CSCR & CSCR_MPEN) &&
+ ((get_cr() & CR_920T_CLOCK_MODE) != CR_920T_FASTBUS_MODE))
+ mpctl0_at_boot = MPCTL0;
+
+ return cpufreq_register_driver(&imx_driver);
+}
+
+arch_initcall(imx_cpufreq_init);
+
diff --git a/arch/arm/mach-netx/time.c b/arch/arm/mach-netx/time.c
index 0993336c0b5..5773b55ef4a 100644
--- a/arch/arm/mach-netx/time.c
+++ b/arch/arm/mach-netx/time.c
@@ -19,6 +19,8 @@
#include <linux/init.h>
#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/clocksource.h>
#include <asm/hardware.h>
#include <asm/io.h>
@@ -26,15 +28,6 @@
#include <asm/arch/netx-regs.h>
/*
- * Returns number of us since last clock interrupt. Note that interrupts
- * will have been disabled by do_gettimeoffset()
- */
-static unsigned long netx_gettimeoffset(void)
-{
- return readl(NETX_GPIO_COUNTER_CURRENT(0)) / 100;
-}
-
-/*
* IRQ handler for the timer
*/
static irqreturn_t
@@ -43,6 +36,7 @@ netx_timer_interrupt(int irq, void *dev_id)
write_seqlock(&xtime_lock);
timer_tick();
+
write_sequnlock(&xtime_lock);
/* acknowledge interrupt */
@@ -51,13 +45,26 @@ netx_timer_interrupt(int irq, void *dev_id)
return IRQ_HANDLED;
}
-
static struct irqaction netx_timer_irq = {
.name = "NetX Timer Tick",
.flags = IRQF_DISABLED | IRQF_TIMER,
.handler = netx_timer_interrupt,
};
+cycle_t netx_get_cycles(void)
+{
+ return readl(NETX_GPIO_COUNTER_CURRENT(1));
+}
+
+static struct clocksource clocksource_netx = {
+ .name = "netx_timer",
+ .rating = 200,
+ .read = netx_get_cycles,
+ .mask = CLOCKSOURCE_MASK(32),
+ .shift = 20,
+ .is_continuous = 1,
+};
+
/*
* Set up timer interrupt
*/
@@ -80,9 +87,20 @@ static void __init netx_timer_init(void)
NETX_GPIO_COUNTER_CTRL(0));
setup_irq(NETX_IRQ_TIMER0, &netx_timer_irq);
+
+ /* Setup timer one for clocksource */
+ writel(0, NETX_GPIO_COUNTER_CTRL(1));
+ writel(0, NETX_GPIO_COUNTER_CURRENT(1));
+ writel(0xFFFFFFFF, NETX_GPIO_COUNTER_MAX(1));
+
+ writel(NETX_GPIO_COUNTER_CTRL_RUN,
+ NETX_GPIO_COUNTER_CTRL(1));
+
+ clocksource_netx.mult =
+ clocksource_hz2mult(CLOCK_TICK_RATE, clocksource_netx.shift);
+ clocksource_register(&clocksource_netx);
}
struct sys_timer netx_timer = {
- .init = netx_timer_init,
- .offset = netx_gettimeoffset,
+ .init = netx_timer_init,
};
diff --git a/arch/arm/mach-pxa/time.c b/arch/arm/mach-pxa/time.c
index b9146686102..3775b8f3842 100644
--- a/arch/arm/mach-pxa/time.c
+++ b/arch/arm/mach-pxa/time.c
@@ -18,6 +18,7 @@
#include <linux/signal.h>
#include <linux/errno.h>
#include <linux/sched.h>
+#include <linux/clocksource.h>
#include <asm/system.h>
#include <asm/hardware.h>
@@ -48,27 +49,6 @@ static int pxa_set_rtc(void)
return 0;
}
-/* IRQs are disabled before entering here from do_gettimeofday() */
-static unsigned long pxa_gettimeoffset (void)
-{
- long ticks_to_match, elapsed, usec;
-
- /* Get ticks before next timer match */
- ticks_to_match = OSMR0 - OSCR;
-
- /* We need elapsed ticks since last match */
- elapsed = LATCH - ticks_to_match;
-
- /* don't get fooled by the workaround in pxa_timer_interrupt() */
- if (elapsed <= 0)
- return 0;
-
- /* Now convert them to usec */
- usec = (unsigned long)(elapsed * (tick_nsec / 1000))/LATCH;
-
- return usec;
-}
-
#ifdef CONFIG_NO_IDLE_HZ
static unsigned long initial_match;
static int match_posponed;
@@ -121,6 +101,20 @@ static struct irqaction pxa_timer_irq = {
.handler = pxa_timer_interrupt,
};
+cycle_t pxa_get_cycles(void)
+{
+ return OSCR;
+}
+
+static struct clocksource clocksource_pxa = {
+ .name = "pxa_timer",
+ .rating = 200,
+ .read = pxa_get_cycles,
+ .mask = CLOCKSOURCE_MASK(32),
+ .shift = 20,
+ .is_continuous = 1,
+};
+
static void __init pxa_timer_init(void)
{
struct timespec tv;
@@ -139,6 +133,14 @@ static void __init pxa_timer_init(void)
OIER = OIER_E0; /* enable match on timer 0 to cause interrupts */
OSMR0 = OSCR + LATCH; /* set initial match */
local_irq_restore(flags);
+
+ /* on PXA OSCR runs continiously and is not written to, so we can use it
+ * as clock source directly.
+ */
+ clocksource_pxa.mult =
+ clocksource_hz2mult(CLOCK_TICK_RATE, clocksource_pxa.shift);
+ clocksource_register(&clocksource_pxa);
+
}
#ifdef CONFIG_NO_IDLE_HZ
@@ -211,7 +213,6 @@ struct sys_timer pxa_timer = {
.init = pxa_timer_init,
.suspend = pxa_timer_suspend,
.resume = pxa_timer_resume,
- .offset = pxa_gettimeoffset,
#ifdef CONFIG_NO_IDLE_HZ
.dyn_tick = &pxa_dyn_tick,
#endif
diff --git a/arch/arm/mach-pxa/trizeps4.c b/arch/arm/mach-pxa/trizeps4.c
index c1827d021ba..119c64b7223 100644
--- a/arch/arm/mach-pxa/trizeps4.c
+++ b/arch/arm/mach-pxa/trizeps4.c
@@ -393,10 +393,6 @@ static struct pxafb_mach_info sharp_lcd = {
.pxafb_backlight_power = board_backlight_power,
};
-static void __init trizeps4_fixup(struct machine_desc *desc, struct tag *tags, char **cmdline, struct meminfo *mi)
-{
-}
-
static void __init trizeps4_init(void)
{
platform_add_devices(trizeps4_devices, ARRAY_SIZE(trizeps4_devices));
@@ -469,7 +465,6 @@ MACHINE_START(TRIZEPS4, "Keith und Koep Trizeps IV module")
.phys_io = 0x40000000,
.io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
.boot_params = TRIZEPS4_SDRAM_BASE + 0x100,
- .fixup = trizeps4_fixup,
.init_machine = trizeps4_init,
.map_io = trizeps4_map_io,
.init_irq = pxa_init_irq,
diff --git a/arch/arm/mach-sa1100/jornada720.c b/arch/arm/mach-sa1100/jornada720.c
index 17f5a43acdb..54ecdaa373d 100644
--- a/arch/arm/mach-sa1100/jornada720.c
+++ b/arch/arm/mach-sa1100/jornada720.c
@@ -1,5 +1,15 @@
/*
* linux/arch/arm/mach-sa1100/jornada720.c
+ *
+ * HP Jornada720 init code
+ *
+ * Copyright (C) 2006 Filip Zyzniewski <filip.zyzniewski@tefnet.pl>
+ * Copyright (C) 2005 Michael Gernoth <michael@gernoth.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
*/
#include <linux/init.h>
@@ -10,13 +20,13 @@
#include <linux/ioport.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
+#include <video/s1d13xxxfb.h>
#include <asm/hardware.h>
#include <asm/hardware/sa1111.h>
#include <asm/irq.h>
#include <asm/mach-types.h>
#include <asm/setup.h>
-
#include <asm/mach/arch.h>
#include <asm/mach/flash.h>
#include <asm/mach/map.h>
@@ -24,13 +34,170 @@
#include "generic.h"
+/*
+ * HP Documentation referred in this file:
+ * http://www.jlime.com/downloads/development/docs/jornada7xx/jornada720.txt
+ */
+
+/* line 110 of HP's doc */
+#define TUCR_VAL 0x20000400
+
+/* memory space (line 52 of HP's doc) */
+#define SA1111REGSTART 0x40000000
+#define SA1111REGLEN 0x00001fff
+#define EPSONREGSTART 0x48000000
+#define EPSONREGLEN 0x00100000
+#define EPSONFBSTART 0x48200000
+/* 512kB framebuffer */
+#define EPSONFBLEN 512*1024
+
+static struct s1d13xxxfb_regval s1d13xxxfb_initregs[] = {
+ /* line 344 of HP's doc */
+ {0x0001,0x00}, // Miscellaneous Register
+ {0x01FC,0x00}, // Display Mode Register
+ {0x0004,0x00}, // General IO Pins Configuration Register 0
+ {0x0005,0x00}, // General IO Pins Configuration Register 1
+ {0x0008,0x00}, // General IO Pins Control Register 0
+ {0x0009,0x00}, // General IO Pins Control Register 1
+ {0x0010,0x01}, // Memory Clock Configuration Register
+ {0x0014,0x11}, // LCD Pixel Clock Configuration Register
+ {0x0018,0x01}, // CRT/TV Pixel Clock Configuration Register
+ {0x001C,0x01}, // MediaPlug Clock Configuration Register
+ {0x001E,0x01}, // CPU To Memory Wait State Select Register
+ {0x0020,0x00}, // Memory Configuration Register
+ {0x0021,0x45}, // DRAM Refresh Rate Register
+ {0x002A,0x01}, // DRAM Timings Control Register 0
+ {0x002B,0x03}, // DRAM Timings Control Register 1
+ {0x0030,0x1c}, // Panel Type Register
+ {0x0031,0x00}, // MOD Rate Register
+ {0x0032,0x4F}, // LCD Horizontal Display Width Register
+ {0x0034,0x07}, // LCD Horizontal Non-Display Period Register
+ {0x0035,0x01}, // TFT FPLINE Start Position Register
+ {0x0036,0x0B}, // TFT FPLINE Pulse Width Register
+ {0x0038,0xEF}, // LCD Vertical Display Height Register 0
+ {0x0039,0x00}, // LCD Vertical Display Height Register 1
+ {0x003A,0x13}, // LCD Vertical Non-Display Period Register
+ {0x003B,0x0B}, // TFT FPFRAME Start Position Register
+ {0x003C,0x01}, // TFT FPFRAME Pulse Width Register
+ {0x0040,0x05}, // LCD Display Mode Register (2:4bpp,3:8bpp,5:16bpp)
+ {0x0041,0x00}, // LCD Miscellaneous Register
+ {0x0042,0x00}, // LCD Display Start Address Register 0
+ {0x0043,0x00}, // LCD Display Start Address Register 1
+ {0x0044,0x00}, // LCD Display Start Address Register 2
+ {0x0046,0x80}, // LCD Memory Address Offset Register 0
+ {0x0047,0x02}, // LCD Memory Address Offset Register 1
+ {0x0048,0x00}, // LCD Pixel Panning Register
+ {0x004A,0x00}, // LCD Display FIFO High Threshold Control Register
+ {0x004B,0x00}, // LCD Display FIFO Low Threshold Control Register
+ {0x0050,0x4F}, // CRT/TV Horizontal Display Width Register
+ {0x0052,0x13}, // CRT/TV Horizontal Non-Display Period Register
+ {0x0053,0x01}, // CRT/TV HRTC Start Position Register
+ {0x0054,0x0B}, // CRT/TV HRTC Pulse Width Register
+ {0x0056,0xDF}, // CRT/TV Vertical Display Height Register 0
+ {0x0057,0x01}, // CRT/TV Vertical Display Height Register 1
+ {0x0058,0x2B}, // CRT/TV Vertical Non-Display Period Register
+ {0x0059,0x09}, // CRT/TV VRTC Start Position Register
+ {0x005A,0x01}, // CRT/TV VRTC Pulse Width Register
+ {0x005B,0x10}, // TV Output Control Register
+ {0x0060,0x03}, // CRT/TV Display Mode Register (2:4bpp,3:8bpp,5:16bpp)
+ {0x0062,0x00}, // CRT/TV Display Start Address Register 0
+ {0x0063,0x00}, // CRT/TV Display Start Address Register 1
+ {0x0064,0x00}, // CRT/TV Display Start Address Register 2
+ {0x0066,0x40}, // CRT/TV Memory Address Offset Register 0
+ {0x0067,0x01}, // CRT/TV Memory Address Offset Register 1
+ {0x0068,0x00}, // CRT/TV Pixel Panning Register
+ {0x006A,0x00}, // CRT/TV Display FIFO High Threshold Control Register
+ {0x006B,0x00}, // CRT/TV Display FIFO Low Threshold Control Register
+ {0x0070,0x00}, // LCD Ink/Cursor Control Register
+ {0x0071,0x01}, // LCD Ink/Cursor Start Address Register
+ {0x0072,0x00}, // LCD Cursor X Position Register 0
+ {0x0073,0x00}, // LCD Cursor X Position Register 1
+ {0x0074,0x00}, // LCD Cursor Y Position Register 0
+ {0x0075,0x00}, // LCD Cursor Y Position Register 1
+ {0x0076,0x00}, // LCD Ink/Cursor Blue Color 0 Register
+ {0x0077,0x00}, // LCD Ink/Cursor Green Color 0 Register
+ {0x0078,0x00}, // LCD Ink/Cursor Red Color 0 Register
+ {0x007A,0x1F}, // LCD Ink/Cursor Blue Color 1 Register
+ {0x007B,0x3F}, // LCD Ink/Cursor Green Color 1 Register
+ {0x007C,0x1F}, // LCD Ink/Cursor Red Color 1 Register
+ {0x007E,0x00}, // LCD Ink/Cursor FIFO Threshold Register
+ {0x0080,0x00}, // CRT/TV Ink/Cursor Control Register
+ {0x0081,0x01}, // CRT/TV Ink/Cursor Start Address Register
+ {0x0082,0x00}, // CRT/TV Cursor X Position Register 0
+ {0x0083,0x00}, // CRT/TV Cursor X Position Register 1
+ {0x0084,0x00}, // CRT/TV Cursor Y Position Register 0
+ {0x0085,0x00}, // CRT/TV Cursor Y Position Register 1
+ {0x0086,0x00}, // CRT/TV Ink/Cursor Blue Color 0 Register
+ {0x0087,0x00}, // CRT/TV Ink/Cursor Green Color 0 Register
+ {0x0088,0x00}, // CRT/TV Ink/Cursor Red Color 0 Register
+ {0x008A,0x1F}, // CRT/TV Ink/Cursor Blue Color 1 Register
+ {0x008B,0x3F}, // CRT/TV Ink/Cursor Green Color 1 Register
+ {0x008C,0x1F}, // CRT/TV Ink/Cursor Red Color 1 Register
+ {0x008E,0x00}, // CRT/TV Ink/Cursor FIFO Threshold Register
+ {0x0100,0x00}, // BitBlt Control Register 0
+ {0x0101,0x00}, // BitBlt Control Register 1
+ {0x0102,0x00}, // BitBlt ROP Code/Color Expansion Register
+ {0x0103,0x00}, // BitBlt Operation Register
+ {0x0104,0x00}, // BitBlt Source Start Address Register 0
+ {0x0105,0x00}, // BitBlt Source Start Address Register 1
+ {0x0106,0x00}, // BitBlt Source Start Address Register 2
+ {0x0108,0x00}, // BitBlt Destination Start Address Register 0
+ {0x0109,0x00}, // BitBlt Destination Start Address Register 1
+ {0x010A,0x00}, // BitBlt Destination Start Address Register 2
+ {0x010C,0x00}, // BitBlt Memory Address Offset Register 0
+ {0x010D,0x00}, // BitBlt Memory Address Offset Register 1
+ {0x0110,0x00}, // BitBlt Width Register 0
+ {0x0111,0x00}, // BitBlt Width Register 1
+ {0x0112,0x00}, // BitBlt Height Register 0
+ {0x0113,0x00}, // BitBlt Height Register 1
+ {0x0114,0x00}, // BitBlt Background Color Register 0
+ {0x0115,0x00}, // BitBlt Background Color Register 1
+ {0x0118,0x00}, // BitBlt Foreground Color Register 0
+ {0x0119,0x00}, // BitBlt Foreground Color Register 1
+ {0x01E0,0x00}, // Look-Up Table Mode Register
+ {0x01E2,0x00}, // Look-Up Table Address Register
+ /* not sure, wouldn't like to mess with the driver */
+ {0x01E4,0x00}, // Look-Up Table Data Register
+ /* jornada doc says 0x00, but I trust the driver */
+ {0x01F0,0x10}, // Power Save Configuration Register
+ {0x01F1,0x00}, // Power Save Status Register
+ {0x01F4,0x00}, // CPU-to-Memory Access Watchdog Timer Register
+ {0x01FC,0x01}, // Display Mode Register(0x01:LCD, 0x02:CRT, 0x03:LCD&CRT)
+};
+
+static struct s1d13xxxfb_pdata s1d13xxxfb_data = {
+ .initregs = s1d13xxxfb_initregs,
+ .initregssize = ARRAY_SIZE(s1d13xxxfb_initregs),
+ .platform_init_video = NULL
+};
-#define JORTUCR_VAL 0x20000400
+static struct resource s1d13xxxfb_resources[] = {
+ [0] = {
+ .start = EPSONFBSTART,
+ .end = EPSONFBSTART + EPSONFBLEN,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = EPSONREGSTART,
+ .end = EPSONREGSTART + EPSONREGLEN,
+ .flags = IORESOURCE_MEM,
+ }
+};
+
+static struct platform_device s1d13xxxfb_device = {
+ .name = S1D_DEVICENAME,
+ .id = 0,
+ .dev = {
+ .platform_data = &s1d13xxxfb_data,
+ },
+ .num_resources = ARRAY_SIZE(s1d13xxxfb_resources),
+ .resource = s1d13xxxfb_resources,
+};
static struct resource sa1111_resources[] = {
[0] = {
- .start = 0x40000000,
- .end = 0x40001fff,
+ .start = SA1111REGSTART,
+ .end = SA1111REGSTART + SA1111REGLEN,
.flags = IORESOURCE_MEM,
},
[1] = {
@@ -53,18 +220,32 @@ static struct platform_device sa1111_device = {
.resource = sa1111_resources,
};
+static struct platform_device jornada720_mcu_device = {
+ .name = "jornada720_mcu",
+ .id = -1,
+};
+
static struct platform_device *devices[] __initdata = {
&sa1111_device,
+ &jornada720_mcu_device,
+ &s1d13xxxfb_device,
};
+/* a stub for now, we theoretically cannot suspend without a flashboard */
+int pm_suspend(suspend_state_t state)
+{
+ return -1;
+}
+
static int __init jornada720_init(void)
{
int ret = -ENODEV;
if (machine_is_jornada720()) {
GPDR |= GPIO_GPIO20;
- TUCR = JORTUCR_VAL; /* set the oscillator out to the SA-1101 */
-
+ /* oscillator setup (line 116 of HP's doc) */
+ TUCR = TUCR_VAL;
+ /* resetting SA1111 (line 118 of HP's doc) */
GPSR = GPIO_GPIO20;
udelay(1);
GPCR = GPIO_GPIO20;
@@ -72,10 +253,6 @@ static int __init jornada720_init(void)
GPSR = GPIO_GPIO20;
udelay(20);
- /* LDD4 is speaker, LDD3 is microphone */
- PPSR &= ~(PPC_LDD3 | PPC_LDD4);
- PPDR |= PPC_LDD3 | PPC_LDD4;
-
ret = platform_add_devices(devices, ARRAY_SIZE(devices));
}
return ret;
@@ -85,19 +262,19 @@ arch_initcall(jornada720_init);
static struct map_desc jornada720_io_desc[] __initdata = {
{ /* Epson registers */
- .virtual = 0xf0000000,
- .pfn = __phys_to_pfn(0x48000000),
- .length = 0x00100000,
+ .virtual = 0xf0000000,
+ .pfn = __phys_to_pfn(EPSONREGSTART),
+ .length = EPSONREGLEN,
.type = MT_DEVICE
}, { /* Epson frame buffer */
- .virtual = 0xf1000000,
- .pfn = __phys_to_pfn(0x48200000),
- .length = 0x00100000,
+ .virtual = 0xf1000000,
+ .pfn = __phys_to_pfn(EPSONFBSTART),
+ .length = EPSONFBLEN,
.type = MT_DEVICE
}, { /* SA-1111 */
- .virtual = 0xf4000000,
- .pfn = __phys_to_pfn(0x40000000),
- .length = 0x00100000,
+ .virtual = 0xf4000000,
+ .pfn = __phys_to_pfn(SA1111REGSTART),
+ .length = SA1111REGLEN,
.type = MT_DEVICE
}
};
@@ -106,7 +283,7 @@ static void __init jornada720_map_io(void)
{
sa1100_map_io();
iotable_init(jornada720_io_desc, ARRAY_SIZE(jornada720_io_desc));
-
+
sa1100_register_uart(0, 3);
sa1100_register_uart(1, 1);
}
@@ -116,7 +293,7 @@ static struct mtd_partition jornada720_partitions[] = {
.name = "JORNADA720 boot firmware",
.size = 0x00040000,
.offset = 0,
- .mask_flags = MTD_WRITEABLE, /* force read-only */
+ .mask_flags = MTD_WRITEABLE, /* force read-only */
}, {
.name = "JORNADA720 kernel",
.size = 0x000c0000,
@@ -139,7 +316,7 @@ static struct mtd_partition jornada720_partitions[] = {
.offset = 0x00540000,
}, {
.name = "JORNADA720 usr local",
- .size = 0, /* will expand to the end of the flash */
+ .size = 0, /* will expand to the end of the flash */
.offset = 0x00d00000,
}
};
@@ -147,10 +324,12 @@ static struct mtd_partition jornada720_partitions[] = {
static void jornada720_set_vpp(int vpp)
{
if (vpp)
- PPSR |= 0x80;
+ /* enabling flash write (line 470 of HP's doc) */
+ PPSR |= PPC_LDD7;
else
- PPSR &= ~0x80;
- PPDR |= 0x80;
+ /* disabling flash write (line 470 of HP's doc) */
+ PPSR &= ~PPC_LDD7;
+ PPDR |= PPC_LDD7;
}
static struct flash_platform_data jornada720_flash_data = {
diff --git a/arch/arm/mm/consistent.c b/arch/arm/mm/consistent.c
index b797217e82b..6a9c362fef5 100644
--- a/arch/arm/mm/consistent.c
+++ b/arch/arm/mm/consistent.c
@@ -238,7 +238,7 @@ __dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp,
* x86 does not mark the pages reserved...
*/
SetPageReserved(page);
- set_pte(pte, mk_pte(page, prot));
+ set_pte_ext(pte, mk_pte(page, prot), 0);
page++;
pte++;
off++;
diff --git a/arch/arm/mm/copypage-v4mc.c b/arch/arm/mm/copypage-v4mc.c
index df1645e14b4..408b05ae6b9 100644
--- a/arch/arm/mm/copypage-v4mc.c
+++ b/arch/arm/mm/copypage-v4mc.c
@@ -71,7 +71,7 @@ void v4_mc_copy_user_page(void *kto, const void *kfrom, unsigned long vaddr)
{
spin_lock(&minicache_lock);
- set_pte(TOP_PTE(0xffff8000), pfn_pte(__pa(kfrom) >> PAGE_SHIFT, minicache_pgprot));
+ set_pte_ext(TOP_PTE(0xffff8000), pfn_pte(__pa(kfrom) >> PAGE_SHIFT, minicache_pgprot), 0);
flush_tlb_kernel_page(0xffff8000);
mc_copy_user_page((void *)0xffff8000, kto);
diff --git a/arch/arm/mm/copypage-v6.c b/arch/arm/mm/copypage-v6.c
index 3d0d3a963d2..865777dec16 100644
--- a/arch/arm/mm/copypage-v6.c
+++ b/arch/arm/mm/copypage-v6.c
@@ -70,8 +70,8 @@ static void v6_copy_user_page_aliasing(void *kto, const void *kfrom, unsigned lo
*/
spin_lock(&v6_lock);
- set_pte(TOP_PTE(from_address) + offset, pfn_pte(__pa(kfrom) >> PAGE_SHIFT, PAGE_KERNEL));
- set_pte(TOP_PTE(to_address) + offset, pfn_pte(__pa(kto) >> PAGE_SHIFT, PAGE_KERNEL));
+ set_pte_ext(TOP_PTE(from_address) + offset, pfn_pte(__pa(kfrom) >> PAGE_SHIFT, PAGE_KERNEL), 0);
+ set_pte_ext(TOP_PTE(to_address) + offset, pfn_pte(__pa(kto) >> PAGE_SHIFT, PAGE_KERNEL), 0);
from = from_address + (offset << PAGE_SHIFT);
to = to_address + (offset << PAGE_SHIFT);
@@ -110,7 +110,7 @@ static void v6_clear_user_page_aliasing(void *kaddr, unsigned long vaddr)
*/
spin_lock(&v6_lock);
- set_pte(TOP_PTE(to_address) + offset, pfn_pte(__pa(kaddr) >> PAGE_SHIFT, PAGE_KERNEL));
+ set_pte_ext(TOP_PTE(to_address) + offset, pfn_pte(__pa(kaddr) >> PAGE_SHIFT, PAGE_KERNEL), 0);
flush_tlb_kernel_page(to);
clear_page((void *)to);
diff --git a/arch/arm/mm/copypage-xscale.c b/arch/arm/mm/copypage-xscale.c
index 84ebe0aa379..aea5da72359 100644
--- a/arch/arm/mm/copypage-xscale.c
+++ b/arch/arm/mm/copypage-xscale.c
@@ -93,7 +93,7 @@ void xscale_mc_copy_user_page(void *kto, const void *kfrom, unsigned long vaddr)
{
spin_lock(&minicache_lock);
- set_pte(TOP_PTE(COPYPAGE_MINICACHE), pfn_pte(__pa(kfrom) >> PAGE_SHIFT, minicache_pgprot));
+ set_pte_ext(TOP_PTE(COPYPAGE_MINICACHE), pfn_pte(__pa(kfrom) >> PAGE_SHIFT, minicache_pgprot), 0);
flush_tlb_kernel_page(COPYPAGE_MINICACHE);
mc_copy_user_page((void *)COPYPAGE_MINICACHE, kto);
diff --git a/arch/arm/mm/fault-armv.c b/arch/arm/mm/fault-armv.c
index 7fc1b35a674..cf95c5d0ce4 100644
--- a/arch/arm/mm/fault-armv.c
+++ b/arch/arm/mm/fault-armv.c
@@ -61,7 +61,7 @@ static int adjust_pte(struct vm_area_struct *vma, unsigned long address)
if (pte_present(entry) && pte_val(entry) & shared_pte_mask) {
flush_cache_page(vma, address, pte_pfn(entry));
pte_val(entry) &= ~shared_pte_mask;
- set_pte(pte, entry);
+ set_pte_at(vma->vm_mm, address, pte, entry);
flush_tlb_page(vma, address);
ret = 1;
}
diff --git a/arch/arm/mm/flush.c b/arch/arm/mm/flush.c
index 454205b789d..628348c9f6c 100644
--- a/arch/arm/mm/flush.c
+++ b/arch/arm/mm/flush.c
@@ -26,7 +26,7 @@ static void flush_pfn_alias(unsigned long pfn, unsigned long vaddr)
unsigned long to = ALIAS_FLUSH_START + (CACHE_COLOUR(vaddr) << PAGE_SHIFT);
const int zero = 0;
- set_pte(TOP_PTE(to), pfn_pte(pfn, PAGE_KERNEL));
+ set_pte_ext(TOP_PTE(to), pfn_pte(pfn, PAGE_KERNEL), 0);
flush_tlb_kernel_page(to);
asm( "mcrr p15, 0, %1, %0, c14\n"
diff --git a/arch/arm/mm/ioremap.c b/arch/arm/mm/ioremap.c
index 46544059279..3bb3951920b 100644
--- a/arch/arm/mm/ioremap.c
+++ b/arch/arm/mm/ioremap.c
@@ -38,89 +38,71 @@
*/
#define VM_ARM_SECTION_MAPPING 0x80000000
-static inline void
-remap_area_pte(pte_t * pte, unsigned long address, unsigned long size,
- unsigned long phys_addr, pgprot_t pgprot)
+static int remap_area_pte(pmd_t *pmd, unsigned long addr, unsigned long end,
+ unsigned long phys_addr, pgprot_t prot)
{
- unsigned long end;
+ pte_t *pte;
+
+ pte = pte_alloc_kernel(pmd, addr);
+ if (!pte)
+ return -ENOMEM;
- address &= ~PMD_MASK;
- end = address + size;
- if (end > PMD_SIZE)
- end = PMD_SIZE;
- BUG_ON(address >= end);
do {
if (!pte_none(*pte))
goto bad;
- set_pte(pte, pfn_pte(phys_addr >> PAGE_SHIFT, pgprot));
- address += PAGE_SIZE;
+ set_pte_ext(pte, pfn_pte(phys_addr >> PAGE_SHIFT, prot), 0);
phys_addr += PAGE_SIZE;
- pte++;
- } while (address && (address < end));
- return;
+ } while (pte++, addr += PAGE_SIZE, addr != end);
+ return 0;
bad:
- printk("remap_area_pte: page already exists\n");
+ printk(KERN_CRIT "remap_area_pte: page already exists\n");
BUG();
}
-static inline int
-remap_area_pmd(pmd_t * pmd, unsigned long address, unsigned long size,
- unsigned long phys_addr, unsigned long flags)
+static inline int remap_area_pmd(pgd_t *pgd, unsigned long addr,
+ unsigned long end, unsigned long phys_addr,
+ pgprot_t prot)
{
- unsigned long end;
- pgprot_t pgprot;
-
- address &= ~PGDIR_MASK;
- end = address + size;
+ unsigned long next;
+ pmd_t *pmd;
+ int ret = 0;
- if (end > PGDIR_SIZE)
- end = PGDIR_SIZE;
+ pmd = pmd_alloc(&init_mm, pgd, addr);
+ if (!pmd)
+ return -ENOMEM;
- phys_addr -= address;
- BUG_ON(address >= end);
-
- pgprot = __pgprot(L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY | L_PTE_WRITE | flags);
do {
- pte_t * pte = pte_alloc_kernel(pmd, address);
- if (!pte)
- return -ENOMEM;
- remap_area_pte(pte, address, end - address, address + phys_addr, pgprot);
- address = (address + PMD_SIZE) & PMD_MASK;
- pmd++;
- } while (address && (address < end));
- return 0;
+ next = pmd_addr_end(addr, end);
+ ret = remap_area_pte(pmd, addr, next, phys_addr, prot);
+ if (ret)
+ return ret;
+ phys_addr += next - addr;
+ } while (pmd++, addr = next, addr != end);
+ return ret;
}
-static int
-remap_area_pages(unsigned long start, unsigned long pfn,
- unsigned long size, unsigned long flags)
+static int remap_area_pages(unsigned long start, unsigned long pfn,
+ unsigned long size, unsigned long flags)
{
- unsigned long address = start;
- unsigned long end = start + size;
+ unsigned long addr = start;
+ unsigned long next, end = start + size;
unsigned long phys_addr = __pfn_to_phys(pfn);
+ pgprot_t prot = __pgprot(L_PTE_PRESENT | L_PTE_YOUNG |
+ L_PTE_DIRTY | L_PTE_WRITE | flags);
+ pgd_t *pgd;
int err = 0;
- pgd_t * dir;
- phys_addr -= address;
- dir = pgd_offset(&init_mm, address);
- BUG_ON(address >= end);
+ BUG_ON(addr >= end);
+ pgd = pgd_offset_k(addr);
do {
- pmd_t *pmd = pmd_alloc(&init_mm, dir, address);
- if (!pmd) {
- err = -ENOMEM;
- break;
- }
- if (remap_area_pmd(pmd, address, end - address,
- phys_addr + address, flags)) {
- err = -ENOMEM;
+ next = pgd_addr_end(addr, end);
+ err = remap_area_pmd(pgd, addr, next, phys_addr, prot);
+ if (err)
break;
- }
-
- address = (address + PGDIR_SIZE) & PGDIR_MASK;
- dir++;
- } while (address && (address < end));
+ phys_addr += next - addr;
+ } while (pgd++, addr = next, addr != end);
return err;
}
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
index b7f194af20b..f028aef9a86 100644
--- a/arch/arm/mm/mmu.c
+++ b/arch/arm/mm/mmu.c
@@ -294,12 +294,6 @@ static void __init build_mem_type_table(void)
mem_types[MT_DEVICE].prot_pte |= L_PTE_BUFFERABLE;
mem_types[MT_DEVICE].prot_sect |= PMD_SECT_BUFFERED;
- /*
- * User pages need to be mapped with the ASID
- * (iow, non-global)
- */
- user_pgprot |= L_PTE_ASID;
-
#ifdef CONFIG_SMP
/*
* Mark memory with the "shared" attribute for SMP systems
@@ -408,7 +402,7 @@ alloc_init_page(unsigned long virt, unsigned long phys, unsigned int prot_l1, pg
}
ptep = pte_offset_kernel(pmdp, virt);
- set_pte(ptep, pfn_pte(phys >> PAGE_SHIFT, prot));
+ set_pte_ext(ptep, pfn_pte(phys >> PAGE_SHIFT, prot), 0);
}
/*
diff --git a/arch/arm/mm/pgd.c b/arch/arm/mm/pgd.c
index 20c1b0df75f..50b9aed6000 100644
--- a/arch/arm/mm/pgd.c
+++ b/arch/arm/mm/pgd.c
@@ -57,7 +57,7 @@ pgd_t *get_pgd_slow(struct mm_struct *mm)
init_pmd = pmd_offset(init_pgd, 0);
init_pte = pte_offset_map_nested(init_pmd, 0);
- set_pte(new_pte, *init_pte);
+ set_pte_ext(new_pte, *init_pte, 0);
pte_unmap_nested(init_pte);
pte_unmap(new_pte);
}
diff --git a/arch/arm/mm/proc-arm1020.S b/arch/arm/mm/proc-arm1020.S
index 289b8e6f504..700c04d6996 100644
--- a/arch/arm/mm/proc-arm1020.S
+++ b/arch/arm/mm/proc-arm1020.S
@@ -397,7 +397,7 @@ ENTRY(cpu_arm1020_switch_mm)
* Set a PTE and flush it out
*/
.align 5
-ENTRY(cpu_arm1020_set_pte)
+ENTRY(cpu_arm1020_set_pte_ext)
#ifdef CONFIG_MMU
str r1, [r0], #-2048 @ linux version
@@ -477,7 +477,7 @@ arm1020_processor_functions:
.word cpu_arm1020_do_idle
.word cpu_arm1020_dcache_clean_area
.word cpu_arm1020_switch_mm
- .word cpu_arm1020_set_pte
+ .word cpu_arm1020_set_pte_ext
.size arm1020_processor_functions, . - arm1020_processor_functions
.section ".rodata"
diff --git a/arch/arm/mm/proc-arm1020e.S b/arch/arm/mm/proc-arm1020e.S
index bed9db6ba58..1cc206ab5ea 100644
--- a/arch/arm/mm/proc-arm1020e.S
+++ b/arch/arm/mm/proc-arm1020e.S
@@ -381,7 +381,7 @@ ENTRY(cpu_arm1020e_switch_mm)
* Set a PTE and flush it out
*/
.align 5
-ENTRY(cpu_arm1020e_set_pte)
+ENTRY(cpu_arm1020e_set_pte_ext)
#ifdef CONFIG_MMU
str r1, [r0], #-2048 @ linux version
@@ -458,7 +458,7 @@ arm1020e_processor_functions:
.word cpu_arm1020e_do_idle
.word cpu_arm1020e_dcache_clean_area
.word cpu_arm1020e_switch_mm
- .word cpu_arm1020e_set_pte
+ .word cpu_arm1020e_set_pte_ext
.size arm1020e_processor_functions, . - arm1020e_processor_functions
.section ".rodata"
diff --git a/arch/arm/mm/proc-arm1022.S b/arch/arm/mm/proc-arm1022.S
index d2a7c1b9cab..aff0ea08e2f 100644
--- a/arch/arm/mm/proc-arm1022.S
+++ b/arch/arm/mm/proc-arm1022.S
@@ -358,12 +358,12 @@ ENTRY(cpu_arm1022_switch_mm)
mov pc, lr
/*
- * cpu_arm1022_set_pte(ptep, pte)
+ * cpu_arm1022_set_pte_ext(ptep, pte, ext)
*
* Set a PTE and flush it out
*/
.align 5
-ENTRY(cpu_arm1022_set_pte)
+ENTRY(cpu_arm1022_set_pte_ext)
#ifdef CONFIG_MMU
str r1, [r0], #-2048 @ linux version
@@ -441,7 +441,7 @@ arm1022_processor_functions:
.word cpu_arm1022_do_idle
.word cpu_arm1022_dcache_clean_area
.word cpu_arm1022_switch_mm
- .word cpu_arm1022_set_pte
+ .word cpu_arm1022_set_pte_ext
.size arm1022_processor_functions, . - arm1022_processor_functions
.section ".rodata"
diff --git a/arch/arm/mm/proc-arm1026.S b/arch/arm/mm/proc-arm1026.S
index 3247ce5c017..65e43a10908 100644
--- a/arch/arm/mm/proc-arm1026.S
+++ b/arch/arm/mm/proc-arm1026.S
@@ -347,12 +347,12 @@ ENTRY(cpu_arm1026_switch_mm)
mov pc, lr
/*
- * cpu_arm1026_set_pte(ptep, pte)
+ * cpu_arm1026_set_pte_ext(ptep, pte, ext)
*
* Set a PTE and flush it out
*/
.align 5
-ENTRY(cpu_arm1026_set_pte)
+ENTRY(cpu_arm1026_set_pte_ext)
#ifdef CONFIG_MMU
str r1, [r0], #-2048 @ linux version
@@ -436,7 +436,7 @@ arm1026_processor_functions:
.word cpu_arm1026_do_idle
.word cpu_arm1026_dcache_clean_area
.word cpu_arm1026_switch_mm
- .word cpu_arm1026_set_pte
+ .word cpu_arm1026_set_pte_ext
.size arm1026_processor_functions, . - arm1026_processor_functions
.section .rodata
diff --git a/arch/arm/mm/proc-arm6_7.S b/arch/arm/mm/proc-arm6_7.S
index ce4f9eef763..123a7dc7a43 100644
--- a/arch/arm/mm/proc-arm6_7.S
+++ b/arch/arm/mm/proc-arm6_7.S
@@ -209,14 +209,14 @@ ENTRY(cpu_arm7_switch_mm)
mov pc, lr
/*
- * Function: arm6_7_set_pte(pte_t *ptep, pte_t pte)
+ * Function: arm6_7_set_pte_ext(pte_t *ptep, pte_t pte, unsigned int ext)
* Params : r0 = Address to set
* : r1 = value to set
* Purpose : Set a PTE and flush it out of any WB cache
*/
.align 5
-ENTRY(cpu_arm6_set_pte)
-ENTRY(cpu_arm7_set_pte)
+ENTRY(cpu_arm6_set_pte_ext)
+ENTRY(cpu_arm7_set_pte_ext)
#ifdef CONFIG_MMU
str r1, [r0], #-2048 @ linux version
@@ -299,7 +299,7 @@ ENTRY(arm6_processor_functions)
.word cpu_arm6_do_idle
.word cpu_arm6_dcache_clean_area
.word cpu_arm6_switch_mm
- .word cpu_arm6_set_pte
+ .word cpu_arm6_set_pte_ext
.size arm6_processor_functions, . - arm6_processor_functions
/*
@@ -315,7 +315,7 @@ ENTRY(arm7_processor_functions)
.word cpu_arm7_do_idle
.word cpu_arm7_dcache_clean_area
.word cpu_arm7_switch_mm
- .word cpu_arm7_set_pte
+ .word cpu_arm7_set_pte_ext
.size arm7_processor_functions, . - arm7_processor_functions
.section ".rodata"
diff --git a/arch/arm/mm/proc-arm720.S b/arch/arm/mm/proc-arm720.S
index c04c194da78..dc763be4336 100644
--- a/arch/arm/mm/proc-arm720.S
+++ b/arch/arm/mm/proc-arm720.S
@@ -88,13 +88,13 @@ ENTRY(cpu_arm720_switch_mm)
mov pc, lr
/*
- * Function: arm720_set_pte(pte_t *ptep, pte_t pte)
+ * Function: arm720_set_pte_ext(pte_t *ptep, pte_t pte, unsigned int ext)
* Params : r0 = Address to set
* : r1 = value to set
* Purpose : Set a PTE and flush it out of any WB cache
*/
.align 5
-ENTRY(cpu_arm720_set_pte)
+ENTRY(cpu_arm720_set_pte_ext)
#ifdef CONFIG_MMU
str r1, [r0], #-2048 @ linux version
@@ -204,7 +204,7 @@ ENTRY(arm720_processor_functions)
.word cpu_arm720_do_idle
.word cpu_arm720_dcache_clean_area
.word cpu_arm720_switch_mm
- .word cpu_arm720_set_pte
+ .word cpu_arm720_set_pte_ext
.size arm720_processor_functions, . - arm720_processor_functions
.section ".rodata"
diff --git a/arch/arm/mm/proc-arm920.S b/arch/arm/mm/proc-arm920.S
index 65cbb2851bf..75c945ed6c4 100644
--- a/arch/arm/mm/proc-arm920.S
+++ b/arch/arm/mm/proc-arm920.S
@@ -344,12 +344,12 @@ ENTRY(cpu_arm920_switch_mm)
mov pc, lr
/*
- * cpu_arm920_set_pte(ptep, pte)
+ * cpu_arm920_set_pte(ptep, pte, ext)
*
* Set a PTE and flush it out
*/
.align 5
-ENTRY(cpu_arm920_set_pte)
+ENTRY(cpu_arm920_set_pte_ext)
#ifdef CONFIG_MMU
str r1, [r0], #-2048 @ linux version
@@ -423,7 +423,7 @@ arm920_processor_functions:
.word cpu_arm920_do_idle
.word cpu_arm920_dcache_clean_area
.word cpu_arm920_switch_mm
- .word cpu_arm920_set_pte
+ .word cpu_arm920_set_pte_ext
.size arm920_processor_functions, . - arm920_processor_functions
.section ".rodata"
diff --git a/arch/arm/mm/proc-arm922.S b/arch/arm/mm/proc-arm922.S
index 52761b70d73..ffb751b877f 100644
--- a/arch/arm/mm/proc-arm922.S
+++ b/arch/arm/mm/proc-arm922.S
@@ -348,12 +348,12 @@ ENTRY(cpu_arm922_switch_mm)
mov pc, lr
/*
- * cpu_arm922_set_pte(ptep, pte)
+ * cpu_arm922_set_pte_ext(ptep, pte, ext)
*
* Set a PTE and flush it out
*/
.align 5
-ENTRY(cpu_arm922_set_pte)
+ENTRY(cpu_arm922_set_pte_ext)
#ifdef CONFIG_MMU
str r1, [r0], #-2048 @ linux version
@@ -427,7 +427,7 @@ arm922_processor_functions:
.word cpu_arm922_do_idle
.word cpu_arm922_dcache_clean_area
.word cpu_arm922_switch_mm
- .word cpu_arm922_set_pte
+ .word cpu_arm922_set_pte_ext
.size arm922_processor_functions, . - arm922_processor_functions
.section ".rodata"
diff --git a/arch/arm/mm/proc-arm925.S b/arch/arm/mm/proc-arm925.S
index 5b74339d158..44c2c997819 100644
--- a/arch/arm/mm/proc-arm925.S
+++ b/arch/arm/mm/proc-arm925.S
@@ -391,12 +391,12 @@ ENTRY(cpu_arm925_switch_mm)
mov pc, lr
/*
- * cpu_arm925_set_pte(ptep, pte)
+ * cpu_arm925_set_pte_ext(ptep, pte, ext)
*
* Set a PTE and flush it out
*/
.align 5
-ENTRY(cpu_arm925_set_pte)
+ENTRY(cpu_arm925_set_pte_ext)
#ifdef CONFIG_MMU
str r1, [r0], #-2048 @ linux version
@@ -490,7 +490,7 @@ arm925_processor_functions:
.word cpu_arm925_do_idle
.word cpu_arm925_dcache_clean_area
.word cpu_arm925_switch_mm
- .word cpu_arm925_set_pte
+ .word cpu_arm925_set_pte_ext
.size arm925_processor_functions, . - arm925_processor_functions
.section ".rodata"
diff --git a/arch/arm/mm/proc-arm926.S b/arch/arm/mm/proc-arm926.S
index 8628ed29a95..5b80b6bdd0c 100644
--- a/arch/arm/mm/proc-arm926.S
+++ b/arch/arm/mm/proc-arm926.S
@@ -348,12 +348,12 @@ ENTRY(cpu_arm926_switch_mm)
mov pc, lr
/*
- * cpu_arm926_set_pte(ptep, pte)
+ * cpu_arm926_set_pte_ext(ptep, pte, ext)
*
* Set a PTE and flush it out
*/
.align 5
-ENTRY(cpu_arm926_set_pte)
+ENTRY(cpu_arm926_set_pte_ext)
#ifdef CONFIG_MMU
str r1, [r0], #-2048 @ linux version
@@ -439,7 +439,7 @@ arm926_processor_functions:
.word cpu_arm926_do_idle
.word cpu_arm926_dcache_clean_area
.word cpu_arm926_switch_mm
- .word cpu_arm926_set_pte
+ .word cpu_arm926_set_pte_ext
.size arm926_processor_functions, . - arm926_processor_functions
.section ".rodata"
@@ -480,7 +480,7 @@ __arm926_proc_info:
b __arm926_setup
.long cpu_arch_name
.long cpu_elf_name
- .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_VFP|HWCAP_EDSP|HWCAP_JAVA
+ .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP|HWCAP_JAVA
.long cpu_arm926_name
.long arm926_processor_functions
.long v4wbi_tlb_fns
diff --git a/arch/arm/mm/proc-sa110.S b/arch/arm/mm/proc-sa110.S
index cd7d865c9d1..6e226e12989 100644
--- a/arch/arm/mm/proc-sa110.S
+++ b/arch/arm/mm/proc-sa110.S
@@ -146,12 +146,12 @@ ENTRY(cpu_sa110_switch_mm)
#endif
/*
- * cpu_sa110_set_pte(ptep, pte)
+ * cpu_sa110_set_pte_ext(ptep, pte, ext)
*
* Set a PTE and flush it out
*/
.align 5
-ENTRY(cpu_sa110_set_pte)
+ENTRY(cpu_sa110_set_pte_ext)
#ifdef CONFIG_MMU
str r1, [r0], #-2048 @ linux version
@@ -222,7 +222,7 @@ ENTRY(sa110_processor_functions)
.word cpu_sa110_do_idle
.word cpu_sa110_dcache_clean_area
.word cpu_sa110_switch_mm
- .word cpu_sa110_set_pte
+ .word cpu_sa110_set_pte_ext
.size sa110_processor_functions, . - sa110_processor_functions
.section ".rodata"
diff --git a/arch/arm/mm/proc-sa1100.S b/arch/arm/mm/proc-sa1100.S
index b776653cc31..9afb11d089f 100644
--- a/arch/arm/mm/proc-sa1100.S
+++ b/arch/arm/mm/proc-sa1100.S
@@ -159,12 +159,12 @@ ENTRY(cpu_sa1100_switch_mm)
#endif
/*
- * cpu_sa1100_set_pte(ptep, pte)
+ * cpu_sa1100_set_pte_ext(ptep, pte, ext)
*
* Set a PTE and flush it out
*/
.align 5
-ENTRY(cpu_sa1100_set_pte)
+ENTRY(cpu_sa1100_set_pte_ext)
#ifdef CONFIG_MMU
str r1, [r0], #-2048 @ linux version
@@ -237,7 +237,7 @@ ENTRY(sa1100_processor_functions)
.word cpu_sa1100_do_idle
.word cpu_sa1100_dcache_clean_area
.word cpu_sa1100_switch_mm
- .word cpu_sa1100_set_pte
+ .word cpu_sa1100_set_pte_ext
.size sa1100_processor_functions, . - sa1100_processor_functions
.section ".rodata"
diff --git a/arch/arm/mm/proc-syms.c b/arch/arm/mm/proc-syms.c
index ab143557e68..9f396b4fa0b 100644
--- a/arch/arm/mm/proc-syms.c
+++ b/arch/arm/mm/proc-syms.c
@@ -17,7 +17,7 @@
#ifndef MULTI_CPU
EXPORT_SYMBOL(cpu_dcache_clean_area);
-EXPORT_SYMBOL(cpu_set_pte);
+EXPORT_SYMBOL(cpu_set_pte_ext);
#else
EXPORT_SYMBOL(processor);
#endif
diff --git a/arch/arm/mm/proc-v6.S b/arch/arm/mm/proc-v6.S
index b440c8a1d34..7b1843befb9 100644
--- a/arch/arm/mm/proc-v6.S
+++ b/arch/arm/mm/proc-v6.S
@@ -103,13 +103,14 @@ ENTRY(cpu_v6_switch_mm)
mov pc, lr
/*
- * cpu_v6_set_pte(ptep, pte)
+ * cpu_v6_set_pte_ext(ptep, pte, ext)
*
* Set a level 2 translation table entry.
*
* - ptep - pointer to level 2 translation table entry
* (hardware version is stored at -1024 bytes)
* - pte - PTE value to store
+ * - ext - value for extended PTE bits
*
* Permissions:
* YUWD APX AP1 AP0 SVC User
@@ -121,33 +122,34 @@ ENTRY(cpu_v6_switch_mm)
* 11x0 0 1 0 r/w r/o
* 1111 0 1 1 r/w r/w
*/
-ENTRY(cpu_v6_set_pte)
+ENTRY(cpu_v6_set_pte_ext)
#ifdef CONFIG_MMU
str r1, [r0], #-2048 @ linux version
- bic r2, r1, #0x000003f0
- bic r2, r2, #0x00000003
- orr r2, r2, #PTE_EXT_AP0 | 2
+ bic r3, r1, #0x000003f0
+ bic r3, r3, #0x00000003
+ orr r3, r3, r2
+ orr r3, r3, #PTE_EXT_AP0 | 2
tst r1, #L_PTE_WRITE
tstne r1, #L_PTE_DIRTY
- orreq r2, r2, #PTE_EXT_APX
+ orreq r3, r3, #PTE_EXT_APX
tst r1, #L_PTE_USER
- orrne r2, r2, #PTE_EXT_AP1
- tstne r2, #PTE_EXT_APX
- bicne r2, r2, #PTE_EXT_APX | PTE_EXT_AP0
+ orrne r3, r3, #PTE_EXT_AP1
+ tstne r3, #PTE_EXT_APX
+ bicne r3, r3, #PTE_EXT_APX | PTE_EXT_AP0
tst r1, #L_PTE_YOUNG
- biceq r2, r2, #PTE_EXT_APX | PTE_EXT_AP_MASK
+ biceq r3, r3, #PTE_EXT_APX | PTE_EXT_AP_MASK
tst r1, #L_PTE_EXEC
- orreq r2, r2, #PTE_EXT_XN
+ orreq r3, r3, #PTE_EXT_XN
tst r1, #L_PTE_PRESENT
- moveq r2, #0
+ moveq r3, #0
- str r2, [r0]
+ str r3, [r0]
mcr p15, 0, r0, c7, c10, 1 @ flush_pte
#endif
mov pc, lr
@@ -156,7 +158,7 @@ ENTRY(cpu_v6_set_pte)
cpu_v6_name:
- .asciz "Some Random V6 Processor"
+ .asciz "ARMv6-compatible processor"
.align
.section ".text.init", #alloc, #execinstr
@@ -207,11 +209,6 @@ __v6_setup:
#endif
mcr p15, 0, r4, c2, c0, 1 @ load TTB1
#endif /* CONFIG_MMU */
-#ifdef CONFIG_VFP
- mrc p15, 0, r0, c1, c0, 2
- orr r0, r0, #(0xf << 20)
- mcr p15, 0, r0, c1, c0, 2 @ Enable full access to VFP
-#endif
adr r5, v6_crval
ldmia r5, {r5, r6}
mrc p15, 0, r0, c1, c0, 0 @ read control register
@@ -238,7 +235,7 @@ ENTRY(v6_processor_functions)
.word cpu_v6_do_idle
.word cpu_v6_dcache_clean_area
.word cpu_v6_switch_mm
- .word cpu_v6_set_pte
+ .word cpu_v6_set_pte_ext
.size v6_processor_functions, . - v6_processor_functions
.type cpu_arch_name, #object
@@ -273,7 +270,7 @@ __v6_proc_info:
b __v6_setup
.long cpu_arch_name
.long cpu_elf_name
- .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_VFP|HWCAP_EDSP|HWCAP_JAVA
+ .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP|HWCAP_JAVA
.long cpu_v6_name
.long v6_processor_functions
.long v6wbi_tlb_fns
diff --git a/arch/arm/mm/proc-xsc3.S b/arch/arm/mm/proc-xsc3.S
index 1ef564d0957..43494ae8f01 100644
--- a/arch/arm/mm/proc-xsc3.S
+++ b/arch/arm/mm/proc-xsc3.S
@@ -357,13 +357,13 @@ ENTRY(cpu_xsc3_switch_mm)
cpwait_ret lr, ip
/*
- * cpu_xsc3_set_pte(ptep, pte)
+ * cpu_xsc3_set_pte_ext(ptep, pte, ext)
*
* Set a PTE and flush it out
*
*/
.align 5
-ENTRY(cpu_xsc3_set_pte)
+ENTRY(cpu_xsc3_set_pte_ext)
str r1, [r0], #-2048 @ linux version
bic r2, r1, #0xff0 @ Keep C, B bits
@@ -457,7 +457,7 @@ ENTRY(xsc3_processor_functions)
.word cpu_xsc3_do_idle
.word cpu_xsc3_dcache_clean_area
.word cpu_xsc3_switch_mm
- .word cpu_xsc3_set_pte
+ .word cpu_xsc3_set_pte_ext
.size xsc3_processor_functions, . - xsc3_processor_functions
.section ".rodata"
diff --git a/arch/arm/mm/proc-xscale.S b/arch/arm/mm/proc-xscale.S
index cc1004b3e51..490e11b3423 100644
--- a/arch/arm/mm/proc-xscale.S
+++ b/arch/arm/mm/proc-xscale.S
@@ -421,14 +421,14 @@ ENTRY(cpu_xscale_switch_mm)
cpwait_ret lr, ip
/*
- * cpu_xscale_set_pte(ptep, pte)
+ * cpu_xscale_set_pte_ext(ptep, pte, ext)
*
* Set a PTE and flush it out
*
* Errata 40: must set memory to write-through for user read-only pages.
*/
.align 5
-ENTRY(cpu_xscale_set_pte)
+ENTRY(cpu_xscale_set_pte_ext)
str r1, [r0], #-2048 @ linux version
bic r2, r1, #0xff0
@@ -529,7 +529,7 @@ ENTRY(xscale_processor_functions)
.word cpu_xscale_do_idle
.word cpu_xscale_dcache_clean_area
.word cpu_xscale_switch_mm
- .word cpu_xscale_set_pte
+ .word cpu_xscale_set_pte_ext
.size xscale_processor_functions, . - xscale_processor_functions
.section ".rodata"
diff --git a/arch/arm/vfp/vfpmodule.c b/arch/arm/vfp/vfpmodule.c
index f08eafbddcc..e26cc1f5994 100644
--- a/arch/arm/vfp/vfpmodule.c
+++ b/arch/arm/vfp/vfpmodule.c
@@ -263,13 +263,24 @@ void VFP9_bounce(u32 trigger, u32 fpexc, struct pt_regs *regs)
if (exceptions)
vfp_raise_exceptions(exceptions, trigger, orig_fpscr, regs);
}
-
+
/*
* VFP support code initialisation.
*/
static int __init vfp_init(void)
{
unsigned int vfpsid;
+ unsigned int cpu_arch = cpu_architecture();
+ u32 access = 0;
+
+ if (cpu_arch >= CPU_ARCH_ARMv6) {
+ access = get_copro_access();
+
+ /*
+ * Enable full access to VFP (cp10 and cp11)
+ */
+ set_copro_access(access | CPACC_FULL(10) | CPACC_FULL(11));
+ }
/*
* First check that there is a VFP that we can use.
@@ -281,6 +292,12 @@ static int __init vfp_init(void)
printk(KERN_INFO "VFP support v0.3: ");
if (VFP_arch) {
printk("not present\n");
+
+ /*
+ * Restore the copro access register.
+ */
+ if (cpu_arch >= CPU_ARCH_ARMv6)
+ set_copro_access(access);
} else if (vfpsid & FPSID_NODOUBLE) {
printk("no double precision support\n");
} else {
@@ -291,9 +308,16 @@ static int __init vfp_init(void)
(vfpsid & FPSID_PART_MASK) >> FPSID_PART_BIT,
(vfpsid & FPSID_VARIANT_MASK) >> FPSID_VARIANT_BIT,
(vfpsid & FPSID_REV_MASK) >> FPSID_REV_BIT);
+
vfp_vector = vfp_support_entry;
thread_register_notifier(&vfp_notifier_block);
+
+ /*
+ * We detected VFP, and the support code is
+ * in place; report VFP support to userspace.
+ */
+ elf_hwcap |= HWCAP_VFP;
}
return 0;
}