aboutsummaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/Kconfig1
-rw-r--r--arch/arm/Makefile4
-rw-r--r--arch/arm/boot/Makefile2
-rw-r--r--arch/arm/boot/dts/isee-igep-v2.dts7
-rw-r--r--arch/arm/boot/dts/isee-igep-v3.dts7
-rw-r--r--arch/arm/boot/dts/vexpress.dts10
-rw-r--r--arch/arm/include/asm/cti.h157
-rw-r--r--arch/arm/include/asm/elf.h1
-rw-r--r--arch/arm/include/asm/pmu.h15
-rw-r--r--arch/arm/include/asm/ptrace.h6
-rw-r--r--arch/arm/include/asm/thread_notify.h1
-rw-r--r--arch/arm/kernel/elf.c19
-rw-r--r--arch/arm/kernel/hw_breakpoint.c7
-rw-r--r--arch/arm/kernel/perf_event.c20
-rw-r--r--arch/arm/kernel/process.c2
-rw-r--r--arch/arm/kernel/ptrace.c348
-rw-r--r--arch/arm/mach-exynos4/Makefile1
-rw-r--r--arch/arm/mach-exynos4/Makefile.boot2
-rw-r--r--arch/arm/mach-exynos4/cpuidle.c86
-rw-r--r--arch/arm/mach-exynos4/gpiolib.c8
-rw-r--r--arch/arm/mach-exynos4/mach-smdkv310.c6
-rw-r--r--arch/arm/mach-mx5/Makefile.boot5
-rw-r--r--arch/arm/mach-omap2/Makefile.boot6
-rw-r--r--arch/arm/mach-omap2/board-3430sdp.c1
-rw-r--r--arch/arm/mach-omap2/board-am3517evm.c2
-rw-r--r--arch/arm/mach-omap2/board-cm-t35.c2
-rw-r--r--arch/arm/mach-omap2/board-devkit8000.c2
-rw-r--r--arch/arm/mach-omap2/board-igep0020.c7
-rw-r--r--arch/arm/mach-omap2/board-igep0030.c6
-rw-r--r--arch/arm/mach-omap2/board-omap3beagle.c1
-rw-r--r--arch/arm/mach-omap2/board-omap3evm.c1
-rw-r--r--arch/arm/mach-omap2/board-omap3stalker.c2
-rw-r--r--arch/arm/mach-omap2/board-overo.c1
-rw-r--r--arch/arm/mach-omap2/devices.c109
-rw-r--r--arch/arm/mach-tegra/Makefile.boot2
-rw-r--r--arch/arm/mach-versatile/Makefile.boot2
-rw-r--r--arch/arm/mach-vexpress/Makefile.boot2
-rw-r--r--arch/arm/mach-vexpress/v2m.c6
-rw-r--r--arch/arm/mm/mmap.c4
-rw-r--r--arch/arm/plat-omap/include/plat/display.h39
-rw-r--r--arch/arm/plat-omap/include/plat/omap44xx.h2
-rw-r--r--arch/arm/plat-omap/include/plat/panel-generic-dpi.h2
-rw-r--r--arch/arm/plat-samsung/gpio-config.c23
-rw-r--r--arch/arm/plat-samsung/include/plat/gpio-cfg-helpers.h25
-rw-r--r--arch/arm/vfp/vfpmodule.c34
-rw-r--r--arch/powerpc/kernel/time.c2
-rw-r--r--arch/x86/crypto/aesni-intel_asm.S5
-rw-r--r--arch/x86/crypto/aesni-intel_glue.c14
-rw-r--r--arch/x86/kernel/cpu/mtrr/main.c20
-rw-r--r--arch/x86/kernel/head64.c3
-rw-r--r--arch/x86/kernel/setup.c5
-rw-r--r--arch/x86/mm/init.c19
-rw-r--r--arch/x86/mm/init_64.c11
53 files changed, 909 insertions, 166 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index f82dccad257..d4ca75b04bc 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1563,7 +1563,6 @@ config HIGHMEM
config HIGHPTE
bool "Allocate 2nd-level pagetables from highmem"
depends on HIGHMEM
- depends on !OUTER_CACHE
config HW_PERF_EVENTS
bool "Enable hardware performance counter support for perf events"
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index d51ab6c6482..4570ca76a9a 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -292,6 +292,9 @@ zinstall uinstall install: vmlinux
%.dtb:
$(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $(boot)/$@
+dtbs:
+ $(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $(boot)/$@
+
# We use MRPROPER_FILES and CLEAN_FILES now
archclean:
$(Q)$(MAKE) $(clean)=$(boot)
@@ -308,6 +311,7 @@ define archhelp
echo ' uImage - U-Boot wrapped zImage'
echo ' bootpImage - Combined zImage and initial RAM disk'
echo ' (supply initrd image via make variable INITRD=<path>)'
+ echo ' dtbs - Build device tree blobs for enabled boards'
echo ' install - Install uncompressed kernel'
echo ' zinstall - Install compressed kernel'
echo ' uinstall - Install U-Boot wrapped compressed kernel'
diff --git a/arch/arm/boot/Makefile b/arch/arm/boot/Makefile
index 08fc37f1dec..a1edfd5a129 100644
--- a/arch/arm/boot/Makefile
+++ b/arch/arm/boot/Makefile
@@ -63,6 +63,8 @@ endif
$(obj)/%.dtb: $(src)/dts/%.dts
$(call cmd,dtc)
+$(obj)/dtbs: $(addprefix $(obj)/, $(dtb-y))
+
quiet_cmd_uimage = UIMAGE $@
cmd_uimage = $(CONFIG_SHELL) $(MKIMAGE) -A arm -O linux -T kernel \
-C none -a $(LOADADDR) -e $(STARTADDR) \
diff --git a/arch/arm/boot/dts/isee-igep-v2.dts b/arch/arm/boot/dts/isee-igep-v2.dts
new file mode 100644
index 00000000000..72caabb85b7
--- /dev/null
+++ b/arch/arm/boot/dts/isee-igep-v2.dts
@@ -0,0 +1,7 @@
+/dts-v1/;
+/include/ "skeleton.dtsi"
+
+/ {
+ model = "ISSE IGEPv2 Board";
+ compatible = "ISEE,igep-v2";
+};
diff --git a/arch/arm/boot/dts/isee-igep-v3.dts b/arch/arm/boot/dts/isee-igep-v3.dts
new file mode 100644
index 00000000000..f40886fef69
--- /dev/null
+++ b/arch/arm/boot/dts/isee-igep-v3.dts
@@ -0,0 +1,7 @@
+/dts-v1/;
+/include/ "skeleton.dtsi"
+
+/ {
+ model = "ISSE IGEPv3 Module";
+ compatible = "ISEE,igep-v3";
+};
diff --git a/arch/arm/boot/dts/vexpress.dts b/arch/arm/boot/dts/vexpress.dts
new file mode 100644
index 00000000000..5f3bc1d1f1c
--- /dev/null
+++ b/arch/arm/boot/dts/vexpress.dts
@@ -0,0 +1,10 @@
+/dts-v1/;
+/include/ "skeleton.dtsi"
+
+/ {
+ model = "ARM Versatile Express";
+ compatible = "arm,vexpress";
+ memory {
+ reg = <0x60000000 0x40000000>;
+ };
+};
diff --git a/arch/arm/include/asm/cti.h b/arch/arm/include/asm/cti.h
new file mode 100644
index 00000000000..26e7450beb6
--- /dev/null
+++ b/arch/arm/include/asm/cti.h
@@ -0,0 +1,157 @@
+#ifndef __ASMARM_CTI_H
+#define __ASMARM_CTI_H
+
+#include <asm/io.h>
+
+/* The registers' definition is from section 3.2 of
+ * Embedded Cross Trigger Revision: r0p0
+ */
+#define CTICONTROL 0x000
+#define CTISTATUS 0x004
+#define CTILOCK 0x008
+#define CTIPROTECTION 0x00C
+#define CTIINTACK 0x010
+#define CTIAPPSET 0x014
+#define CTIAPPCLEAR 0x018
+#define CTIAPPPULSE 0x01c
+#define CTIINEN 0x020
+#define CTIOUTEN 0x0A0
+#define CTITRIGINSTATUS 0x130
+#define CTITRIGOUTSTATUS 0x134
+#define CTICHINSTATUS 0x138
+#define CTICHOUTSTATUS 0x13c
+#define CTIPERIPHID0 0xFE0
+#define CTIPERIPHID1 0xFE4
+#define CTIPERIPHID2 0xFE8
+#define CTIPERIPHID3 0xFEC
+#define CTIPCELLID0 0xFF0
+#define CTIPCELLID1 0xFF4
+#define CTIPCELLID2 0xFF8
+#define CTIPCELLID3 0xFFC
+
+/* The below are from section 3.6.4 of
+ * CoreSight v1.0 Architecture Specification
+ */
+#define LOCKACCESS 0xFB0
+#define LOCKSTATUS 0xFB4
+
+/* write this value to LOCKACCESS will unlock the module, and
+ * other value will lock the module
+ */
+#define LOCKCODE 0xC5ACCE55
+
+/**
+ * struct cti - cross trigger interface struct
+ * @base: mapped virtual address for the cti base
+ * @irq: irq number for the cti
+ * @trig_out_for_irq: triger out number which will cause
+ * the @irq happen
+ *
+ * cti struct used to operate cti registers.
+ */
+struct cti {
+ void __iomem *base;
+ int irq;
+ int trig_out_for_irq;
+};
+
+/**
+ * cti_init - initialize the cti instance
+ * @cti: cti instance
+ * @base: mapped virtual address for the cti base
+ * @irq: irq number for the cti
+ * @trig_out: triger out number which will cause
+ * the @irq happen
+ *
+ * called by machine code to pass the board dependent
+ * @base, @irq and @trig_out to cti.
+ */
+static inline void cti_init(struct cti *cti,
+ void __iomem *base, int irq, int trig_out)
+{
+ cti->base = base;
+ cti->irq = irq;
+ cti->trig_out_for_irq = trig_out;
+}
+
+/**
+ * cti_map_trigger - use the @chan to map @trig_in to @trig_out
+ * @cti: cti instance
+ * @trig_in: trigger in number
+ * @trig_out: trigger out number
+ * @channel: channel number
+ *
+ * This function maps one trigger in of @trig_in to one trigger
+ * out of @trig_out using the channel @chan.
+ */
+static inline void cti_map_trigger(struct cti *cti,
+ int trig_in, int trig_out, int chan)
+{
+ void __iomem *base = cti->base;
+
+ __raw_writel(BIT(chan), base + CTIINEN + trig_in * 4);
+ __raw_writel(BIT(chan), base + CTIOUTEN + trig_out * 4);
+}
+
+/**
+ * cti_enable - enable the cti module
+ * @cti: cti instance
+ *
+ * enable the cti module
+ */
+static inline void cti_enable(struct cti *cti)
+{
+ __raw_writel(0x1, cti->base + CTICONTROL);
+}
+
+/**
+ * cti_disable - disable the cti module
+ * @cti: cti instance
+ *
+ * enable the cti module
+ */
+static inline void cti_disable(struct cti *cti)
+{
+ __raw_writel(0, cti->base + CTICONTROL);
+}
+
+/**
+ * cti_irq_ack - clear the cti irq
+ * @cti: cti instance
+ *
+ * clear the cti irq
+ */
+static inline void cti_irq_ack(struct cti *cti)
+{
+ void __iomem *base = cti->base;
+ unsigned long val;
+
+ val = __raw_readl(base + CTIINTACK);
+ val |= BIT(cti->trig_out_for_irq);
+ __raw_writel(val, base + CTIINTACK);
+}
+
+/**
+ * cti_unlock - unlock cti module
+ * @cti: cti instance
+ *
+ * unlock the cti module, or else any writes to the cti
+ * module is not allowed.
+ */
+static inline void cti_unlock(struct cti *cti)
+{
+ __raw_writel(LOCKCODE, cti->base + LOCKACCESS);
+}
+
+/**
+ * cti_lock - lock cti module
+ * @cti: cti instance
+ *
+ * lock the cti module, so any writes to the cti
+ * module will be not allowed.
+ */
+static inline void cti_lock(struct cti *cti)
+{
+ __raw_writel(~LOCKCODE, cti->base + LOCKACCESS);
+}
+#endif
diff --git a/arch/arm/include/asm/elf.h b/arch/arm/include/asm/elf.h
index c3cd8755e64..0e9ce8d9686 100644
--- a/arch/arm/include/asm/elf.h
+++ b/arch/arm/include/asm/elf.h
@@ -108,6 +108,7 @@ struct task_struct;
int dump_task_regs(struct task_struct *t, elf_gregset_t *elfregs);
#define ELF_CORE_COPY_TASK_REGS dump_task_regs
+#define CORE_DUMP_USE_REGSET
#define ELF_EXEC_PAGESIZE 4096
/* This is the location that an ET_DYN program is loaded if exec'ed. Typical
diff --git a/arch/arm/include/asm/pmu.h b/arch/arm/include/asm/pmu.h
index 7544ce6b481..7ca3d15046d 100644
--- a/arch/arm/include/asm/pmu.h
+++ b/arch/arm/include/asm/pmu.h
@@ -22,13 +22,22 @@ enum arm_pmu_type {
/*
* struct arm_pmu_platdata - ARM PMU platform data
*
- * @handle_irq: an optional handler which will be called from the interrupt and
- * passed the address of the low level handler, and can be used to implement
- * any platform specific handling before or after calling it.
+ * @handle_irq: an optional handler which will be called from the
+ * interrupt and passed the address of the low level handler,
+ * and can be used to implement any platform specific handling
+ * before or after calling it.
+ * @enable_irq: an optional handler which will be called after
+ * request_irq and be used to handle some platform specific
+ * irq enablement
+ * @disable_irq: an optional handler which will be called before
+ * free_irq and be used to handle some platform specific
+ * irq disablement
*/
struct arm_pmu_platdata {
irqreturn_t (*handle_irq)(int irq, void *dev,
irq_handler_t pmu_handler);
+ void (*enable_irq)(int irq);
+ void (*disable_irq)(int irq);
};
#ifdef CONFIG_CPU_HAS_PMU
diff --git a/arch/arm/include/asm/ptrace.h b/arch/arm/include/asm/ptrace.h
index a8ff22b2a39..312d10877bd 100644
--- a/arch/arm/include/asm/ptrace.h
+++ b/arch/arm/include/asm/ptrace.h
@@ -128,6 +128,12 @@ struct pt_regs {
#define ARM_r0 uregs[0]
#define ARM_ORIG_r0 uregs[17]
+/*
+ * The size of the user-visible VFP state as seen by PTRACE_GET/SETVFPREGS
+ * and core dumps.
+ */
+#define ARM_VFPREGS_SIZE ( 32 * 8 /*fpregs*/ + 4 /*fpscr*/ )
+
#ifdef __KERNEL__
#define user_mode(regs) \
diff --git a/arch/arm/include/asm/thread_notify.h b/arch/arm/include/asm/thread_notify.h
index c4391ba2035..1dc98067589 100644
--- a/arch/arm/include/asm/thread_notify.h
+++ b/arch/arm/include/asm/thread_notify.h
@@ -43,6 +43,7 @@ static inline void thread_notify(unsigned long rc, struct thread_info *thread)
#define THREAD_NOTIFY_FLUSH 0
#define THREAD_NOTIFY_EXIT 1
#define THREAD_NOTIFY_SWITCH 2
+#define THREAD_NOTIFY_COPY 3
#endif
#endif
diff --git a/arch/arm/kernel/elf.c b/arch/arm/kernel/elf.c
index d4a0da1e48f..8524d096300 100644
--- a/arch/arm/kernel/elf.c
+++ b/arch/arm/kernel/elf.c
@@ -40,16 +40,23 @@ EXPORT_SYMBOL(elf_check_arch);
void elf_set_personality(const struct elf32_hdr *x)
{
unsigned int eflags = x->e_flags;
- unsigned int personality = PER_LINUX_32BIT;
+ unsigned int personality = current->personality;
/*
+ * Inherit most personality flags from parent, except for those
+ * we're about to choose. Beware: PER_LINUX_32BIT carries flag bits
+ * outside of PER_MASK.
+ */
+ personality &= ~(PER_MASK | PER_LINUX | PER_LINUX_32BIT);
+
+ /*
* APCS-26 is only valid for OABI executables
*/
- if ((eflags & EF_ARM_EABI_MASK) == EF_ARM_EABI_UNKNOWN) {
- if (eflags & EF_ARM_APCS_26)
- personality = PER_LINUX;
- }
-
+ if ((eflags & EF_ARM_EABI_MASK) == EF_ARM_EABI_UNKNOWN &&
+ (eflags & EF_ARM_APCS_26))
+ personality |= PER_LINUX;
+ else
+ personality |= PER_LINUX_32BIT;
set_personality(personality);
/*
diff --git a/arch/arm/kernel/hw_breakpoint.c b/arch/arm/kernel/hw_breakpoint.c
index 8dbc126f715..87acc25d7a3 100644
--- a/arch/arm/kernel/hw_breakpoint.c
+++ b/arch/arm/kernel/hw_breakpoint.c
@@ -868,6 +868,13 @@ static void reset_ctrl_regs(void *info)
*/
asm volatile("mcr p14, 0, %0, c1, c0, 4" : : "r" (0));
isb();
+
+ /*
+ * Clear any configured vector-catch events before
+ * enabling monitor mode.
+ */
+ asm volatile("mcr p14, 0, %0, c0, c7, 0" : : "r" (0));
+ isb();
}
if (enable_monitor_mode())
diff --git a/arch/arm/kernel/perf_event.c b/arch/arm/kernel/perf_event.c
index 69cfee0fe00..1a0d6afbb35 100644
--- a/arch/arm/kernel/perf_event.c
+++ b/arch/arm/kernel/perf_event.c
@@ -221,7 +221,7 @@ again:
prev_raw_count &= armpmu->max_period;
if (overflow)
- delta = armpmu->max_period - prev_raw_count + new_raw_count;
+ delta = armpmu->max_period - prev_raw_count + new_raw_count + 1;
else
delta = new_raw_count - prev_raw_count;
@@ -426,14 +426,18 @@ armpmu_reserve_hardware(void)
pr_warning("unable to request IRQ%d for ARM perf "
"counters\n", irq);
break;
- }
+ } else if (plat->enable_irq)
+ plat->enable_irq(irq);
}
if (err) {
for (i = i - 1; i >= 0; --i) {
irq = platform_get_irq(pmu_device, i);
- if (irq >= 0)
+ if (irq >= 0) {
+ if (plat->disable_irq)
+ plat->disable_irq(irq);
free_irq(irq, NULL);
+ }
}
release_pmu(pmu_device);
pmu_device = NULL;
@@ -446,11 +450,16 @@ static void
armpmu_release_hardware(void)
{
int i, irq;
+ struct arm_pmu_platdata *plat =
+ dev_get_platdata(&pmu_device->dev);
for (i = pmu_device->num_resources - 1; i >= 0; --i) {
irq = platform_get_irq(pmu_device, i);
- if (irq >= 0)
+ if (irq >= 0) {
+ if (plat->disable_irq)
+ plat->disable_irq(irq);
free_irq(irq, NULL);
+ }
}
armpmu->stop();
@@ -746,7 +755,8 @@ perf_callchain_user(struct perf_callchain_entry *entry, struct pt_regs *regs)
tail = (struct frame_tail __user *)regs->ARM_fp - 1;
- while (tail && !((unsigned long)tail & 0x3))
+ while ((entry->nr < PERF_MAX_STACK_DEPTH) &&
+ tail && !((unsigned long)tail & 0x3))
tail = user_backtrace(tail, entry);
}
diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c
index d8ae7018208..85e68c7ebd4 100644
--- a/arch/arm/kernel/process.c
+++ b/arch/arm/kernel/process.c
@@ -448,6 +448,8 @@ copy_thread(unsigned long clone_flags, unsigned long stack_start,
if (clone_flags & CLONE_SETTLS)
thread->tp_value = regs->ARM_r3;
+ thread_notify(THREAD_NOTIFY_COPY, thread);
+
return 0;
}
diff --git a/arch/arm/kernel/ptrace.c b/arch/arm/kernel/ptrace.c
index 03438e9cc06..7c897e2c4d4 100644
--- a/arch/arm/kernel/ptrace.c
+++ b/arch/arm/kernel/ptrace.c
@@ -25,6 +25,7 @@
#include <linux/marker.h>
#include <linux/kallsyms.h>
#include <trace/syscall.h>
+#include <linux/regset.h>
#include <asm/pgtable.h>
#include <asm/system.h>
@@ -337,58 +338,6 @@ static int ptrace_write_user(struct task_struct *tsk, unsigned long off,
return put_user_reg(tsk, off >> 2, val);
}
-/*
- * Get all user integer registers.
- */
-static int ptrace_getregs(struct task_struct *tsk, void __user *uregs)
-{
- struct pt_regs *regs = task_pt_regs(tsk);
-
- return copy_to_user(uregs, regs, sizeof(struct pt_regs)) ? -EFAULT : 0;
-}
-
-/*
- * Set all user integer registers.
- */
-static int ptrace_setregs(struct task_struct *tsk, void __user *uregs)
-{
- struct pt_regs newregs;
- int ret;
-
- ret = -EFAULT;
- if (copy_from_user(&newregs, uregs, sizeof(struct pt_regs)) == 0) {
- struct pt_regs *regs = task_pt_regs(tsk);
-
- ret = -EINVAL;
- if (valid_user_regs(&newregs)) {
- *regs = newregs;
- ret = 0;
- }
- }
-
- return ret;
-}
-
-/*
- * Get the child FPU state.
- */
-static int ptrace_getfpregs(struct task_struct *tsk, void __user *ufp)
-{
- return copy_to_user(ufp, &task_thread_info(tsk)->fpstate,
- sizeof(struct user_fp)) ? -EFAULT : 0;
-}
-
-/*
- * Set the child FPU state.
- */
-static int ptrace_setfpregs(struct task_struct *tsk, void __user *ufp)
-{
- struct thread_info *thread = task_thread_info(tsk);
- thread->used_cp[1] = thread->used_cp[2] = 1;
- return copy_from_user(&thread->fpstate, ufp,
- sizeof(struct user_fp)) ? -EFAULT : 0;
-}
-
#ifdef CONFIG_IWMMXT
/*
@@ -447,56 +396,6 @@ static int ptrace_setcrunchregs(struct task_struct *tsk, void __user *ufp)
}
#endif
-#ifdef CONFIG_VFP
-/*
- * Get the child VFP state.
- */
-static int ptrace_getvfpregs(struct task_struct *tsk, void __user *data)
-{
- struct thread_info *thread = task_thread_info(tsk);
- union vfp_state *vfp = &thread->vfpstate;
- struct user_vfp __user *ufp = data;
-
- vfp_sync_hwstate(thread);
-
- /* copy the floating point registers */
- if (copy_to_user(&ufp->fpregs, &vfp->hard.fpregs,
- sizeof(vfp->hard.fpregs)))
- return -EFAULT;
-
- /* copy the status and control register */
- if (put_user(vfp->hard.fpscr, &ufp->fpscr))
- return -EFAULT;
-
- return 0;
-}
-
-/*
- * Set the child VFP state.
- */
-static int ptrace_setvfpregs(struct task_struct *tsk, void __user *data)
-{
- struct thread_info *thread = task_thread_info(tsk);
- union vfp_state *vfp = &thread->vfpstate;
- struct user_vfp __user *ufp = data;
-
- vfp_sync_hwstate(thread);
-
- /* copy the floating point registers */
- if (copy_from_user(&vfp->hard.fpregs, &ufp->fpregs,
- sizeof(vfp->hard.fpregs)))
- return -EFAULT;
-
- /* copy the status and control register */
- if (get_user(vfp->hard.fpscr, &ufp->fpscr))
- return -EFAULT;
-
- vfp_flush_hwstate(thread);
-
- return 0;
-}
-#endif
-
#ifdef CONFIG_HAVE_HW_BREAKPOINT
/*
* Convert a virtual register number into an index for a thread_info
@@ -723,6 +622,219 @@ out:
}
#endif
+/* regset get/set implementations */
+
+static int gpr_get(struct task_struct *target,
+ const struct user_regset *regset,
+ unsigned int pos, unsigned int count,
+ void *kbuf, void __user *ubuf)
+{
+ struct pt_regs *regs = task_pt_regs(target);
+
+ return user_regset_copyout(&pos, &count, &kbuf, &ubuf,
+ regs,
+ 0, sizeof(*regs));
+}
+
+static int gpr_set(struct task_struct *target,
+ const struct user_regset *regset,
+ unsigned int pos, unsigned int count,
+ const void *kbuf, const void __user *ubuf)
+{
+ int ret;
+ struct pt_regs newregs;
+
+ ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
+ &newregs,
+ 0, sizeof(newregs));
+ if (ret)
+ return ret;
+
+ if (!valid_user_regs(&newregs))
+ return -EINVAL;
+
+ *task_pt_regs(target) = newregs;
+ return 0;
+}
+
+static int fpa_get(struct task_struct *target,
+ const struct user_regset *regset,
+ unsigned int pos, unsigned int count,
+ void *kbuf, void __user *ubuf)
+{
+ return user_regset_copyout(&pos, &count, &kbuf, &ubuf,
+ &task_thread_info(target)->fpstate,
+ 0, sizeof(struct user_fp));
+}
+
+static int fpa_set(struct task_struct *target,
+ const struct user_regset *regset,
+ unsigned int pos, unsigned int count,
+ const void *kbuf, const void __user *ubuf)
+{
+ struct thread_info *thread = task_thread_info(target);
+
+ thread->used_cp[1] = thread->used_cp[2] = 1;
+
+ return user_regset_copyin(&pos, &count, &kbuf, &ubuf,
+ &thread->fpstate,
+ 0, sizeof(struct user_fp));
+}
+
+#ifdef CONFIG_VFP
+/*
+ * VFP register get/set implementations.
+ *
+ * With respect to the kernel, struct user_fp is divided into three chunks:
+ * 16 or 32 real VFP registers (d0-d15 or d0-31)
+ * These are transferred to/from the real registers in the task's
+ * vfp_hard_struct. The number of registers depends on the kernel
+ * configuration.
+ *
+ * 16 or 0 fake VFP registers (d16-d31 or empty)
+ * i.e., the user_vfp structure has space for 32 registers even if
+ * the kernel doesn't have them all.
+ *
+ * vfp_get() reads this chunk as zero where applicable
+ * vfp_set() ignores this chunk
+ *
+ * 1 word for the FPSCR
+ *
+ * The bounds-checking logic built into user_regset_copyout and friends
+ * means that we can make a simple sequence of calls to map the relevant data
+ * to/from the specified slice of the user regset structure.
+ */
+static int vfp_get(struct task_struct *target,
+ const struct user_regset *regset,
+ unsigned int pos, unsigned int count,
+ void *kbuf, void __user *ubuf)
+{
+ int ret;
+ struct thread_info *thread = task_thread_info(target);
+ struct vfp_hard_struct const *vfp = &thread->vfpstate.hard;
+ const size_t user_fpregs_offset = offsetof(struct user_vfp, fpregs);
+ const size_t user_fpscr_offset = offsetof(struct user_vfp, fpscr);
+
+ vfp_sync_hwstate(thread);
+
+ ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
+ &vfp->fpregs,
+ user_fpregs_offset,
+ user_fpregs_offset + sizeof(vfp->fpregs));
+ if (ret)
+ return ret;
+
+ ret = user_regset_copyout_zero(&pos, &count, &kbuf, &ubuf,
+ user_fpregs_offset + sizeof(vfp->fpregs),
+ user_fpscr_offset);
+ if (ret)
+ return ret;
+
+ return user_regset_copyout(&pos, &count, &kbuf, &ubuf,
+ &vfp->fpscr,
+ user_fpscr_offset,
+ user_fpscr_offset + sizeof(vfp->fpscr));
+}
+
+/*
+ * For vfp_set() a read-modify-write is done on the VFP registers,
+ * in order to avoid writing back a half-modified set of registers on
+ * failure.
+ */
+static int vfp_set(struct task_struct *target,
+ const struct user_regset *regset,
+ unsigned int pos, unsigned int count,
+ const void *kbuf, const void __user *ubuf)
+{
+ int ret;
+ struct thread_info *thread = task_thread_info(target);
+ struct vfp_hard_struct new_vfp = thread->vfpstate.hard;
+ const size_t user_fpregs_offset = offsetof(struct user_vfp, fpregs);
+ const size_t user_fpscr_offset = offsetof(struct user_vfp, fpscr);
+
+ ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
+ &new_vfp.fpregs,
+ user_fpregs_offset,
+ user_fpregs_offset + sizeof(new_vfp.fpregs));
+ if (ret)
+ return ret;
+
+ ret = user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf,
+ user_fpregs_offset + sizeof(new_vfp.fpregs),
+ user_fpscr_offset);
+ if (ret)
+ return ret;
+
+ ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
+ &new_vfp.fpscr,
+ user_fpscr_offset,
+ user_fpscr_offset + sizeof(new_vfp.fpscr));
+ if (ret)
+ return ret;
+
+ vfp_sync_hwstate(thread);
+ thread->vfpstate.hard = new_vfp;
+ vfp_flush_hwstate(thread);
+
+ return 0;
+}
+#endif /* CONFIG_VFP */
+
+enum arm_regset {
+ REGSET_GPR,
+ REGSET_FPR,
+#ifdef CONFIG_VFP
+ REGSET_VFP,
+#endif
+};
+
+static const struct user_regset arm_regsets[] = {
+ [REGSET_GPR] = {
+ .core_note_type = NT_PRSTATUS,
+ .n = ELF_NGREG,
+ .size = sizeof(u32),
+ .align = sizeof(u32),
+ .get = gpr_get,
+ .set = gpr_set
+ },
+ [REGSET_FPR] = {
+ /*
+ * For the FPA regs in fpstate, the real fields are a mixture
+ * of sizes, so pretend that the registers are word-sized:
+ */
+ .core_note_type = NT_PRFPREG,
+ .n = sizeof(struct user_fp) / sizeof(u32),
+ .size = sizeof(u32),
+ .align = sizeof(u32),
+ .get = fpa_get,
+ .set = fpa_set
+ },
+#ifdef CONFIG_VFP
+ [REGSET_VFP] = {
+ /*
+ * Pretend that the VFP regs are word-sized, since the FPSCR is
+ * a single word dangling at the end of struct user_vfp:
+ */
+ .core_note_type = NT_ARM_VFP,
+ .n = ARM_VFPREGS_SIZE / sizeof(u32),
+ .size = sizeof(u32),
+ .align = sizeof(u32),
+ .get = vfp_get,
+ .set = vfp_set
+ },
+#endif /* CONFIG_VFP */
+};
+
+static const struct user_regset_view user_arm_view = {
+ .name = "arm", .e_machine = ELF_ARCH, .ei_osabi = ELF_OSABI,
+ .regsets = arm_regsets, .n = ARRAY_SIZE(arm_regsets)
+};
+
+const struct user_regset_view *task_user_regset_view(struct task_struct *task)
+{
+ return &user_arm_view;
+}
+
long arch_ptrace(struct task_struct *child, long request,
unsigned long addr, unsigned long data)
{
@@ -739,19 +851,31 @@ long arch_ptrace(struct task_struct *child, long request,
break;
case PTRACE_GETREGS:
- ret = ptrace_getregs(child, datap);
+ ret = copy_regset_to_user(child,
+ &user_arm_view, REGSET_GPR,
+ 0, sizeof(struct pt_regs),
+ datap);
break;
case PTRACE_SETREGS:
- ret = ptrace_setregs(child, datap);
+ ret = copy_regset_from_user(child,
+ &user_arm_view, REGSET_GPR,
+ 0, sizeof(struct pt_regs),
+ datap);
break;
case PTRACE_GETFPREGS:
- ret = ptrace_getfpregs(child, datap);
+ ret = copy_regset_to_user(child,
+ &user_arm_view, REGSET_FPR,
+ 0, sizeof(union fp_state),
+ datap);
break;
-
+
case PTRACE_SETFPREGS:
- ret = ptrace_setfpregs(child, datap);
+ ret = copy_regset_from_user(child,
+ &user_arm_view, REGSET_FPR,
+ 0, sizeof(union fp_state),
+ datap);
break;
#ifdef CONFIG_IWMMXT
@@ -786,11 +910,17 @@ long arch_ptrace(struct task_struct *child, long request,
#ifdef CONFIG_VFP
case PTRACE_GETVFPREGS:
- ret = ptrace_getvfpregs(child, datap);
+ ret = copy_regset_to_user(child,
+ &user_arm_view, REGSET_VFP,
+ 0, ARM_VFPREGS_SIZE,
+ datap);
break;
case PTRACE_SETVFPREGS:
- ret = ptrace_setvfpregs(child, datap);
+ ret = copy_regset_from_user(child,
+ &user_arm_view, REGSET_VFP,
+ 0, ARM_VFPREGS_SIZE,
+ datap);
break;
#endif
diff --git a/arch/arm/mach-exynos4/Makefile b/arch/arm/mach-exynos4/Makefile
index 9be104f63c0..de197d6648a 100644
--- a/arch/arm/mach-exynos4/Makefile
+++ b/arch/arm/mach-exynos4/Makefile
@@ -16,6 +16,7 @@ obj-$(CONFIG_CPU_EXYNOS4210) += cpu.o init.o clock.o irq-combiner.o
obj-$(CONFIG_CPU_EXYNOS4210) += setup-i2c0.o gpiolib.o irq-eint.o dma.o
obj-$(CONFIG_PM) += pm.o sleep.o
obj-$(CONFIG_CPU_FREQ) += cpufreq.o
+obj-$(CONFIG_CPU_IDLE) += cpuidle.o
obj-$(CONFIG_SMP) += platsmp.o headsmp.o
diff --git a/arch/arm/mach-exynos4/Makefile.boot b/arch/arm/mach-exynos4/Makefile.boot
index d65956ffb43..fcee6b5384a 100644
--- a/arch/arm/mach-exynos4/Makefile.boot
+++ b/arch/arm/mach-exynos4/Makefile.boot
@@ -1,2 +1,4 @@
zreladdr-y := 0x40008000
params_phys-y := 0x40000100
+
+dtb-$(CONFIG_MACH_SMDKV310) += exynos4-smdkv310.dtb
diff --git a/arch/arm/mach-exynos4/cpuidle.c b/arch/arm/mach-exynos4/cpuidle.c
new file mode 100644
index 00000000000..bf7e96f2793
--- /dev/null
+++ b/arch/arm/mach-exynos4/cpuidle.c
@@ -0,0 +1,86 @@
+/* linux/arch/arm/mach-exynos4/cpuidle.c
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * 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/kernel.h>
+#include <linux/init.h>
+#include <linux/cpuidle.h>
+#include <linux/io.h>
+
+#include <asm/proc-fns.h>
+
+static int exynos4_enter_idle(struct cpuidle_device *dev,
+ struct cpuidle_state *state);
+
+static struct cpuidle_state exynos4_cpuidle_set[] = {
+ [0] = {
+ .enter = exynos4_enter_idle,
+ .exit_latency = 1,
+ .target_residency = 100000,
+ .flags = CPUIDLE_FLAG_TIME_VALID,
+ .name = "IDLE",
+ .desc = "ARM clock gating(WFI)",
+ },
+};
+
+static DEFINE_PER_CPU(struct cpuidle_device, exynos4_cpuidle_device);
+
+static struct cpuidle_driver exynos4_idle_driver = {
+ .name = "exynos4_idle",
+ .owner = THIS_MODULE,
+};
+
+static int exynos4_enter_idle(struct cpuidle_device *dev,
+ struct cpuidle_state *state)
+{
+ struct timeval before, after;
+ int idle_time;
+
+ local_irq_disable();
+ do_gettimeofday(&before);
+
+ cpu_do_idle();
+
+ do_gettimeofday(&after);
+ local_irq_enable();
+ idle_time = (after.tv_sec - before.tv_sec) * USEC_PER_SEC +
+ (after.tv_usec - before.tv_usec);
+
+ return idle_time;
+}
+
+static int __init exynos4_init_cpuidle(void)
+{
+ int i, max_cpuidle_state, cpu_id;
+ struct cpuidle_device *device;
+
+ cpuidle_register_driver(&exynos4_idle_driver);
+
+ for_each_cpu(cpu_id, cpu_online_mask) {
+ device = &per_cpu(exynos4_cpuidle_device, cpu_id);
+ device->cpu = cpu_id;
+
+ device->state_count = (sizeof(exynos4_cpuidle_set) /
+ sizeof(struct cpuidle_state));
+
+ max_cpuidle_state = device->state_count;
+
+ for (i = 0; i < max_cpuidle_state; i++) {
+ memcpy(&device->states[i], &exynos4_cpuidle_set[i],
+ sizeof(struct cpuidle_state));
+ }
+
+ if (cpuidle_register_device(device)) {
+ printk(KERN_ERR "CPUidle register device failed\n,");
+ return -EIO;
+ }
+ }
+ return 0;
+}
+device_initcall(exynos4_init_cpuidle);
diff --git a/arch/arm/mach-exynos4/gpiolib.c b/arch/arm/mach-exynos4/gpiolib.c
index d54ca6adb66..3a47c8e84c9 100644
--- a/arch/arm/mach-exynos4/gpiolib.c
+++ b/arch/arm/mach-exynos4/gpiolib.c
@@ -23,14 +23,14 @@
static struct s3c_gpio_cfg gpio_cfg = {
.set_config = s3c_gpio_setcfg_s3c64xx_4bit,
- .set_pull = s3c_gpio_setpull_updown,
- .get_pull = s3c_gpio_getpull_updown,
+ .set_pull = s3c_gpio_setpull_exynos4,
+ .get_pull = s3c_gpio_getpull_exynos4,
};
static struct s3c_gpio_cfg gpio_cfg_noint = {
.set_config = s3c_gpio_setcfg_s3c64xx_4bit,
- .set_pull = s3c_gpio_setpull_updown,
- .get_pull = s3c_gpio_getpull_updown,
+ .set_pull = s3c_gpio_setpull_exynos4,
+ .get_pull = s3c_gpio_getpull_exynos4,
};
/*
diff --git a/arch/arm/mach-exynos4/mach-smdkv310.c b/arch/arm/mach-exynos4/mach-smdkv310.c
index 08bcc557458..82e0df737c0 100644
--- a/arch/arm/mach-exynos4/mach-smdkv310.c
+++ b/arch/arm/mach-exynos4/mach-smdkv310.c
@@ -78,7 +78,7 @@ static struct s3c2410_uartcfg smdkv310_uartcfgs[] __initdata = {
};
static struct s3c_sdhci_platdata smdkv310_hsmmc0_pdata __initdata = {
- .cd_type = S3C_SDHCI_CD_GPIO,
+ .cd_type = S3C_SDHCI_CD_INTERNAL,
.ext_cd_gpio = EXYNOS4_GPK0(2),
.ext_cd_gpio_invert = 1,
.clk_type = S3C_SDHCI_CLK_DIV_EXTERNAL,
@@ -96,7 +96,7 @@ static struct s3c_sdhci_platdata smdkv310_hsmmc1_pdata __initdata = {
};
static struct s3c_sdhci_platdata smdkv310_hsmmc2_pdata __initdata = {
- .cd_type = S3C_SDHCI_CD_GPIO,
+ .cd_type = S3C_SDHCI_CD_INTERNAL,
.ext_cd_gpio = EXYNOS4_GPK2(2),
.ext_cd_gpio_invert = 1,
.clk_type = S3C_SDHCI_CLK_DIV_EXTERNAL,
@@ -168,9 +168,9 @@ static struct i2c_board_info i2c_devs1[] __initdata = {
};
static struct platform_device *smdkv310_devices[] __initdata = {
+ &s3c_device_hsmmc2,
&s3c_device_hsmmc0,
&s3c_device_hsmmc1,
- &s3c_device_hsmmc2,
&s3c_device_hsmmc3,
&s3c_device_i2c1,
&s3c_device_rtc,
diff --git a/arch/arm/mach-mx5/Makefile.boot b/arch/arm/mach-mx5/Makefile.boot
index e928be1b675..4111462e242 100644
--- a/arch/arm/mach-mx5/Makefile.boot
+++ b/arch/arm/mach-mx5/Makefile.boot
@@ -7,3 +7,8 @@ initrd_phys-$(CONFIG_ARCH_MX51) := 0x90800000
zreladdr-$(CONFIG_ARCH_MX53) := 0x70008000
params_phys-$(CONFIG_ARCH_MX53) := 0x70000100
initrd_phys-$(CONFIG_ARCH_MX53) := 0x70800000
+
+dtb-$(CONFIG_MACH_MX51_BABBAGE) += mx51-babbage.dtb
+dtb-$(CONFIG_MACH_MX51_EFIKAMX) += genesi-efikamx.dtb
+dtb-$(CONFIG_MACH_MX51_EFIKASB) += genesi-efikasb.dtb
+dtb-$(CONFIG_MACH_MX53_LOCO) += mx53-loco.dtb
diff --git a/arch/arm/mach-omap2/Makefile.boot b/arch/arm/mach-omap2/Makefile.boot
index 565aff7f37a..422c1700ccf 100644
--- a/arch/arm/mach-omap2/Makefile.boot
+++ b/arch/arm/mach-omap2/Makefile.boot
@@ -1,3 +1,9 @@
zreladdr-y := 0x80008000
params_phys-y := 0x80000100
initrd_phys-y := 0x80800000
+
+dtb-$(CONFIG_MACH_OMAP3_BEAGLE) += omap3-beagle.dtb
+dtb-$(CONFIG_MACH_OMAP4_PANDA) += omap4-panda.dtb
+dtb-$(CONFIG_MACH_OVERO) += omap3-overo.dtb
+dtb-$(CONFIG_MACH_IGEP0020) += isee-igep-v2.dtb
+dtb-$(CONFIG_MACH_IGEP0030) += isee-igep-v3.dtb
diff --git a/arch/arm/mach-omap2/board-3430sdp.c b/arch/arm/mach-omap2/board-3430sdp.c
index 9afd087cc29..e512b48c936 100644
--- a/arch/arm/mach-omap2/board-3430sdp.c
+++ b/arch/arm/mach-omap2/board-3430sdp.c
@@ -275,6 +275,7 @@ static struct panel_generic_dpi_data dvi_panel = {
.name = "generic",
.platform_enable = sdp3430_panel_enable_dvi,
.platform_disable = sdp3430_panel_disable_dvi,
+ .i2c_bus_num = 3,
};
static struct omap_dss_device sdp3430_dvi_device = {
diff --git a/arch/arm/mach-omap2/board-am3517evm.c b/arch/arm/mach-omap2/board-am3517evm.c
index ce7d5e6e415..ace46665d67 100644
--- a/arch/arm/mach-omap2/board-am3517evm.c
+++ b/arch/arm/mach-omap2/board-am3517evm.c
@@ -311,6 +311,7 @@ static struct panel_generic_dpi_data lcd_panel = {
.name = "sharp_lq",
.platform_enable = am3517_evm_panel_enable_lcd,
.platform_disable = am3517_evm_panel_disable_lcd,
+ .i2c_bus_num = 3,
};
static struct omap_dss_device am3517_evm_lcd_device = {
@@ -359,6 +360,7 @@ static struct panel_generic_dpi_data dvi_panel = {
.name = "generic",
.platform_enable = am3517_evm_panel_enable_dvi,
.platform_disable = am3517_evm_panel_disable_dvi,
+ .i2c_bus_num = 3,
};
static struct omap_dss_device am3517_evm_dvi_device = {
diff --git a/arch/arm/mach-omap2/board-cm-t35.c b/arch/arm/mach-omap2/board-cm-t35.c
index 02a12b41c0f..edd48356c30 100644
--- a/arch/arm/mach-omap2/board-cm-t35.c
+++ b/arch/arm/mach-omap2/board-cm-t35.c
@@ -356,6 +356,7 @@ static struct panel_generic_dpi_data lcd_panel = {
.name = "toppoly_tdo35s",
.platform_enable = cm_t35_panel_enable_lcd,
.platform_disable = cm_t35_panel_disable_lcd,
+ .i2c_bus_num = 3,
};
static struct omap_dss_device cm_t35_lcd_device = {
@@ -370,6 +371,7 @@ static struct panel_generic_dpi_data dvi_panel = {
.name = "generic",
.platform_enable = cm_t35_panel_enable_dvi,
.platform_disable = cm_t35_panel_disable_dvi,
+ .i2c_bus_num = 3,
};
static struct omap_dss_device cm_t35_dvi_device = {
diff --git a/arch/arm/mach-omap2/board-devkit8000.c b/arch/arm/mach-omap2/board-devkit8000.c
index 65f9fde2c56..0a35c3a3ed9 100644
--- a/arch/arm/mach-omap2/board-devkit8000.c
+++ b/arch/arm/mach-omap2/board-devkit8000.c
@@ -151,6 +151,7 @@ static struct panel_generic_dpi_data lcd_panel = {
.name = "generic",
.platform_enable = devkit8000_panel_enable_lcd,
.platform_disable = devkit8000_panel_disable_lcd,
+ .i2c_bus_num = 3,
};
static struct omap_dss_device devkit8000_lcd_device = {
@@ -165,6 +166,7 @@ static struct panel_generic_dpi_data dvi_panel = {
.name = "generic",
.platform_enable = devkit8000_panel_enable_dvi,
.platform_disable = devkit8000_panel_disable_dvi,
+ .i2c_bus_num = 3,
};
static struct omap_dss_device devkit8000_dvi_device = {
diff --git a/arch/arm/mach-omap2/board-igep0020.c b/arch/arm/mach-omap2/board-igep0020.c
index 5f8a2fd0633..8b24d62e8f2 100644
--- a/arch/arm/mach-omap2/board-igep0020.c
+++ b/arch/arm/mach-omap2/board-igep0020.c
@@ -465,6 +465,7 @@ static struct panel_generic_dpi_data dvi_panel = {
.name = "generic",
.platform_enable = igep2_enable_dvi,
.platform_disable = igep2_disable_dvi,
+ .i2c_bus_num = 3,
};
static struct omap_dss_device igep2_dvi_device = {
@@ -703,6 +704,11 @@ static void __init igep2_init(void)
}
+static const char *igep2_dt_compat[] __initdata = {
+ "ISEE,igep-v2",
+ NULL
+};
+
MACHINE_START(IGEP0020, "IGEP v2 board")
.boot_params = 0x80000100,
.reserve = omap_reserve,
@@ -711,4 +717,5 @@ MACHINE_START(IGEP0020, "IGEP v2 board")
.init_irq = omap_init_irq,
.init_machine = igep2_init,
.timer = &omap_timer,
+ .dt_compat = &igep2_dt_compat,
MACHINE_END
diff --git a/arch/arm/mach-omap2/board-igep0030.c b/arch/arm/mach-omap2/board-igep0030.c
index b10db0e6ee6..01762bb6800 100644
--- a/arch/arm/mach-omap2/board-igep0030.c
+++ b/arch/arm/mach-omap2/board-igep0030.c
@@ -447,6 +447,11 @@ static void __init igep3_init(void)
}
+static const char *igep3_dt_compat[] __initdata = {
+ "ISEE,igep-v3",
+ NULL
+};
+
MACHINE_START(IGEP0030, "IGEP OMAP3 module")
.boot_params = 0x80000100,
.reserve = omap_reserve,
@@ -455,4 +460,5 @@ MACHINE_START(IGEP0030, "IGEP OMAP3 module")
.init_irq = omap_init_irq,
.init_machine = igep3_init,
.timer = &omap_timer,
+ .dt_compat = &igep3_dt_compat,
MACHINE_END
diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c
index 4c62a01a379..34b0cb4d189 100644
--- a/arch/arm/mach-omap2/board-omap3beagle.c
+++ b/arch/arm/mach-omap2/board-omap3beagle.c
@@ -202,6 +202,7 @@ static struct panel_generic_dpi_data dvi_panel = {
.name = "generic",
.platform_enable = beagle_enable_dvi,
.platform_disable = beagle_disable_dvi,
+ .i2c_bus_num = 3,
};
static struct omap_dss_device beagle_dvi_device = {
diff --git a/arch/arm/mach-omap2/board-omap3evm.c b/arch/arm/mach-omap2/board-omap3evm.c
index 5a1a916e5cc..792ca7454b8 100644
--- a/arch/arm/mach-omap2/board-omap3evm.c
+++ b/arch/arm/mach-omap2/board-omap3evm.c
@@ -341,6 +341,7 @@ static struct panel_generic_dpi_data dvi_panel = {
.name = "generic",
.platform_enable = omap3_evm_enable_dvi,
.platform_disable = omap3_evm_disable_dvi,
+ .i2c_bus_num = 3,
};
static struct omap_dss_device omap3_evm_dvi_device = {
diff --git a/arch/arm/mach-omap2/board-omap3stalker.c b/arch/arm/mach-omap2/board-omap3stalker.c
index a6e0b9161c9..8491295d650 100644
--- a/arch/arm/mach-omap2/board-omap3stalker.c
+++ b/arch/arm/mach-omap2/board-omap3stalker.c
@@ -165,6 +165,7 @@ static struct panel_generic_dpi_data lcd_panel = {
.name = "generic",
.platform_enable = omap3_stalker_enable_lcd,
.platform_disable = omap3_stalker_disable_lcd,
+ .i2c_bus_num = 3,
};
static struct omap_dss_device omap3_stalker_lcd_device = {
@@ -218,6 +219,7 @@ static struct panel_generic_dpi_data dvi_panel = {
.name = "generic",
.platform_enable = omap3_stalker_enable_dvi,
.platform_disable = omap3_stalker_disable_dvi,
+ .i2c_bus_num = 3,
};
static struct omap_dss_device omap3_stalker_dvi_device = {
diff --git a/arch/arm/mach-omap2/board-overo.c b/arch/arm/mach-omap2/board-overo.c
index da6d2f150d9..bcdffe22d19 100644
--- a/arch/arm/mach-omap2/board-overo.c
+++ b/arch/arm/mach-omap2/board-overo.c
@@ -296,6 +296,7 @@ static struct panel_generic_dpi_data dvi_panel = {
.name = "generic",
.platform_enable = overo_panel_enable_dvi,
.platform_disable = overo_panel_disable_dvi,
+ .i2c_bus_num = 3,
};
static struct omap_dss_device overo_dvi_device = {
diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c
index d478f53f908..f30c1bdaa98 100644
--- a/arch/arm/mach-omap2/devices.c
+++ b/arch/arm/mach-omap2/devices.c
@@ -22,6 +22,7 @@
#include <asm/mach-types.h>
#include <asm/mach/map.h>
#include <asm/pmu.h>
+#include <asm/cti.h>
#include <plat/tc.h>
#include <plat/board.h>
@@ -386,20 +387,95 @@ static struct resource omap3_pmu_resource = {
.flags = IORESOURCE_IRQ,
};
+static struct resource omap4_pmu_resource[] = {
+ {
+ .start = OMAP44XX_IRQ_CTI0,
+ .end = OMAP44XX_IRQ_CTI0,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = OMAP44XX_IRQ_CTI1,
+ .end = OMAP44XX_IRQ_CTI1,
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
static struct platform_device omap_pmu_device = {
.name = "arm-pmu",
.id = ARM_PMU_DEVICE_CPU,
.num_resources = 1,
};
+static struct arm_pmu_platdata omap4_pmu_data;
+static struct cti omap4_cti[2];
+
+static void omap4_enable_cti(int irq)
+{
+ if (irq == OMAP44XX_IRQ_CTI0)
+ cti_enable(&omap4_cti[0]);
+ else if (irq == OMAP44XX_IRQ_CTI1)
+ cti_enable(&omap4_cti[1]);
+}
+
+static void omap4_disable_cti(int irq)
+{
+ if (irq == OMAP44XX_IRQ_CTI0)
+ cti_disable(&omap4_cti[0]);
+ else if (irq == OMAP44XX_IRQ_CTI1)
+ cti_disable(&omap4_cti[1]);
+}
+
+static irqreturn_t omap4_pmu_handler(int irq, void *dev, irq_handler_t handler)
+{
+ if (irq == OMAP44XX_IRQ_CTI0)
+ cti_irq_ack(&omap4_cti[0]);
+ else if (irq == OMAP44XX_IRQ_CTI1)
+ cti_irq_ack(&omap4_cti[1]);
+
+ return handler(irq, dev);
+}
+
+static void omap4_configure_pmu_irq(void)
+{
+ void __iomem *base0;
+ void __iomem *base1;
+
+ base0 = ioremap(OMAP44XX_CTI0_BASE, SZ_4K);
+ base1 = ioremap(OMAP44XX_CTI1_BASE, SZ_4K);
+ if (!base0 && !base1) {
+ pr_err("ioremap for OMAP4 CTI failed\n");
+ return;
+ }
+
+ /*configure CTI0 for pmu irq routing*/
+ cti_init(&omap4_cti[0], base0, OMAP44XX_IRQ_CTI0, 6);
+ cti_unlock(&omap4_cti[0]);
+ cti_map_trigger(&omap4_cti[0], 1, 6, 2);
+
+ /*configure CTI1 for pmu irq routing*/
+ cti_init(&omap4_cti[1], base1, OMAP44XX_IRQ_CTI1, 6);
+ cti_unlock(&omap4_cti[1]);
+ cti_map_trigger(&omap4_cti[1], 1, 6, 2);
+
+ omap4_pmu_data.handle_irq = omap4_pmu_handler;
+ omap4_pmu_data.enable_irq = omap4_enable_cti;
+ omap4_pmu_data.disable_irq = omap4_disable_cti;
+}
+
static void omap_init_pmu(void)
{
- if (cpu_is_omap24xx())
+ if (cpu_is_omap24xx()) {
omap_pmu_device.resource = &omap2_pmu_resource;
- else if (cpu_is_omap34xx())
+ } else if (cpu_is_omap34xx()) {
omap_pmu_device.resource = &omap3_pmu_resource;
- else
+ } else if (cpu_is_omap44xx()) {
+ omap_pmu_device.resource = omap4_pmu_resource;
+ omap_pmu_device.num_resources = 2;
+ omap_pmu_device.dev.platform_data = &omap4_pmu_data;
+ omap4_configure_pmu_irq();
+ } else {
return;
+ }
platform_device_register(&omap_pmu_device);
}
@@ -637,13 +713,21 @@ static inline void omap_hdq_init(void) {}
#if defined(CONFIG_VIDEO_OMAP2_VOUT) || \
defined(CONFIG_VIDEO_OMAP2_VOUT_MODULE)
#if defined(CONFIG_FB_OMAP2) || defined(CONFIG_FB_OMAP2_MODULE)
-static struct resource omap_vout_resource[3 - CONFIG_FB_OMAP2_NUM_FBS] = {
-};
+#define NUM_FB CONFIG_FB_OMAP2_NUM_FBS
+#elif defined(CONFIG_DRM_OMAP) || defined(CONFIG_DRM_OMAP_MODULE)
+#define NUM_FB CONFIG_DRM_OMAP_NUM_CRTCS
#else
-static struct resource omap_vout_resource[2] = {
-};
+#define NUM_FB 1 /* we don't want gfx pipe */
+#endif
+#ifdef CONFIG_ARCH_OMAP4
+#define NUM_PIPES 4
+#else
+#define NUM_PIPES 3
#endif
+static struct resource omap_vout_resource[NUM_PIPES - NUM_FB] = {
+};
+
static struct platform_device omap_vout_device = {
.name = "omap_vout",
.num_resources = ARRAY_SIZE(omap_vout_resource),
@@ -659,6 +743,16 @@ static void omap_init_vout(void)
static inline void omap_init_vout(void) {}
#endif
+static struct platform_device omap_gpu_device = {
+ .name = "omap_gpu",
+ .id = -1,
+};
+
+static void omap_init_gpu(void)
+{
+ platform_device_register(&omap_gpu_device);
+}
+
/*-------------------------------------------------------------------------*/
static int __init omap2_init_devices(void)
@@ -677,6 +771,7 @@ static int __init omap2_init_devices(void)
omap_init_sham();
omap_init_aes();
omap_init_vout();
+ omap_init_gpu();
return 0;
}
diff --git a/arch/arm/mach-tegra/Makefile.boot b/arch/arm/mach-tegra/Makefile.boot
index db52d61a738..c98addfc904 100644
--- a/arch/arm/mach-tegra/Makefile.boot
+++ b/arch/arm/mach-tegra/Makefile.boot
@@ -1,3 +1,5 @@
zreladdr-$(CONFIG_ARCH_TEGRA_2x_SOC) := 0x00008000
params_phys-$(CONFIG_ARCH_TEGRA_2x_SOC) := 0x00000100
initrd_phys-$(CONFIG_ARCH_TEGRA_2x_SOC) := 0x00800000
+
+dtb-$(CONFIG_MACH_HARMONY) += tegra-harmony.dtb
diff --git a/arch/arm/mach-versatile/Makefile.boot b/arch/arm/mach-versatile/Makefile.boot
index c7e75acfe6c..e2227d3c23c 100644
--- a/arch/arm/mach-versatile/Makefile.boot
+++ b/arch/arm/mach-versatile/Makefile.boot
@@ -2,3 +2,5 @@
params_phys-y := 0x00000100
initrd_phys-y := 0x00800000
+dtb-$(CONFIG_ARCH_VERSATILE_PB) += versatile-pb.dtb
+dtb-$(CONFIG_MACH_VERSATILE_AB) += versatile-ab.dtb
diff --git a/arch/arm/mach-vexpress/Makefile.boot b/arch/arm/mach-vexpress/Makefile.boot
index 07c2d9c457e..9920a1053e2 100644
--- a/arch/arm/mach-vexpress/Makefile.boot
+++ b/arch/arm/mach-vexpress/Makefile.boot
@@ -1,3 +1,5 @@
zreladdr-y := 0x60008000
params_phys-y := 0x60000100
initrd_phys-y := 0x60800000
+
+dtb-$(CONFIG_ARCH_VEXPRESS_CA9X4) += vexpress.dtb
diff --git a/arch/arm/mach-vexpress/v2m.c b/arch/arm/mach-vexpress/v2m.c
index ba46e8e0743..e318df39efd 100644
--- a/arch/arm/mach-vexpress/v2m.c
+++ b/arch/arm/mach-vexpress/v2m.c
@@ -437,6 +437,11 @@ static void __init v2m_init(void)
ct_desc->init_tile();
}
+static const char *vexpress_dt_match[] __initdata = {
+ "arm,vexpress",
+ NULL,
+};
+
MACHINE_START(VEXPRESS, "ARM-Versatile Express")
.boot_params = PLAT_PHYS_OFFSET + 0x00000100,
.map_io = v2m_map_io,
@@ -444,4 +449,5 @@ MACHINE_START(VEXPRESS, "ARM-Versatile Express")
.init_irq = v2m_init_irq,
.timer = &v2m_timer,
.init_machine = v2m_init,
+ .dt_compat = vexpress_dt_match,
MACHINE_END
diff --git a/arch/arm/mm/mmap.c b/arch/arm/mm/mmap.c
index afe209e1e1f..74be05f3e03 100644
--- a/arch/arm/mm/mmap.c
+++ b/arch/arm/mm/mmap.c
@@ -7,6 +7,7 @@
#include <linux/shm.h>
#include <linux/sched.h>
#include <linux/io.h>
+#include <linux/personality.h>
#include <linux/random.h>
#include <asm/cputype.h>
#include <asm/system.h>
@@ -82,7 +83,8 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr,
mm->cached_hole_size = 0;
}
/* 8 bits of randomness in 20 address space bits */
- if (current->flags & PF_RANDOMIZE)
+ if ((current->flags & PF_RANDOMIZE) &&
+ !(current->personality & ADDR_NO_RANDOMIZE))
addr += (get_random_int() % (1 << 8)) << PAGE_SHIFT;
full_search:
diff --git a/arch/arm/plat-omap/include/plat/display.h b/arch/arm/plat-omap/include/plat/display.h
index 5e04ddc18fa..9f30ab8d1e1 100644
--- a/arch/arm/plat-omap/include/plat/display.h
+++ b/arch/arm/plat-omap/include/plat/display.h
@@ -23,6 +23,7 @@
#include <linux/list.h>
#include <linux/kobject.h>
#include <linux/device.h>
+#include <linux/notifier.h>
#include <linux/platform_device.h>
#include <asm/atomic.h>
@@ -131,6 +132,10 @@ enum omap_dss_venc_type {
enum omap_display_caps {
OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE = 1 << 0,
OMAP_DSS_DISPLAY_CAP_TEAR_ELIM = 1 << 1,
+ /* set if display supports hotplug detect, and will call
+ * omap_dss_notify(CONNECT/DISCONNECT) at appropriate times
+ */
+ OMAP_DSS_DISPLAY_CAP_HPD = 1 << 2,
};
enum omap_dss_update_mode {
@@ -459,6 +464,7 @@ struct omap_dss_device {
struct omap_overlay_manager *manager;
enum omap_dss_display_state state;
+ struct blocking_notifier_head notifier;
/* platform specific */
int (*platform_enable)(struct omap_dss_device *dssdev);
@@ -514,6 +520,17 @@ struct omap_dss_driver {
int (*set_wss)(struct omap_dss_device *dssdev, u32 wss);
u32 (*get_wss)(struct omap_dss_device *dssdev);
+
+ /* return raw EDID.. len indicates the max number of bytes of the
+ * EDID to read */
+ int (*get_edid)(struct omap_dss_device *dssdev, u8 *edid, int len);
+
+ /* is this display physically present / plugged-in? For hot-plug
+ * type displays (DVI, HDMI), this means is the cable plugged in.
+ * For displays like LCD panels, this means is the display present
+ * on the board.
+ */
+ bool (*is_detected)(struct omap_dss_device *dssdev);
};
int omap_dss_register_driver(struct omap_dss_driver *);
@@ -532,12 +549,34 @@ struct omap_dss_device *omap_dss_find_device(void *data,
int omap_dss_start_device(struct omap_dss_device *dssdev);
void omap_dss_stop_device(struct omap_dss_device *dssdev);
+/* the event id of the event that occurred is passed in as the second arg
+ * to the notifier function, and the dssdev is passed as the third.
+ */
+enum omap_dss_event {
+ OMAP_DSS_SIZE_CHANGE,
+ /* the CONNECT/DISCONNECT events will be sent if OMAP_DSS_DISPLAY_CAP_HPD
+ * flag is set in the dssdev->caps. Otherwise the user will have to poll
+ * for detection when a monitor is plugged/unplugged.
+ */
+ OMAP_DSS_HOTPLUG_CONNECT,
+ OMAP_DSS_HOTPLUG_DISCONNECT,
+};
+
+void omap_dss_notify(struct omap_dss_device *dssdev, enum omap_dss_event evt);
+void omap_dss_add_notify(struct omap_dss_device *dssdev, struct notifier_block *nb);
+void omap_dss_remove_notify(struct omap_dss_device *dssdev, struct notifier_block *nb);
+
int omap_dss_get_num_overlay_managers(void);
struct omap_overlay_manager *omap_dss_get_overlay_manager(int num);
int omap_dss_get_num_overlays(void);
struct omap_overlay *omap_dss_get_overlay(int num);
+void omapdss_default_get_timings(struct omap_dss_device *dssdev,
+ struct omap_video_timings *timings);
+int omapdss_default_check_timings(struct omap_dss_device *dssdev,
+ struct omap_video_timings *timings);
+bool omapdss_default_is_detected(struct omap_dss_device *dssdev);
void omapdss_default_get_resolution(struct omap_dss_device *dssdev,
u16 *xres, u16 *yres);
int omapdss_default_get_recommended_bpp(struct omap_dss_device *dssdev);
diff --git a/arch/arm/plat-omap/include/plat/omap44xx.h b/arch/arm/plat-omap/include/plat/omap44xx.h
index ea2b8a6306e..b127a1641f4 100644
--- a/arch/arm/plat-omap/include/plat/omap44xx.h
+++ b/arch/arm/plat-omap/include/plat/omap44xx.h
@@ -57,5 +57,7 @@
#define OMAP44XX_HSUSB_OHCI_BASE (L4_44XX_BASE + 0x64800)
#define OMAP44XX_HSUSB_EHCI_BASE (L4_44XX_BASE + 0x64C00)
+#define OMAP44XX_CTI0_BASE 0x54148000
+#define OMAP44XX_CTI1_BASE 0x54149000
#endif /* __ASM_ARCH_OMAP44XX_H */
diff --git a/arch/arm/plat-omap/include/plat/panel-generic-dpi.h b/arch/arm/plat-omap/include/plat/panel-generic-dpi.h
index 790619734bc..164d3b9bde5 100644
--- a/arch/arm/plat-omap/include/plat/panel-generic-dpi.h
+++ b/arch/arm/plat-omap/include/plat/panel-generic-dpi.h
@@ -27,11 +27,13 @@
* @name: panel name
* @platform_enable: platform specific panel enable function
* @platform_disable: platform specific panel disable function
+ * @i2c_bus_num: i2c control bus id the eeprom is attached to
*/
struct panel_generic_dpi_data {
const char *name;
int (*platform_enable)(struct omap_dss_device *dssdev);
void (*platform_disable)(struct omap_dss_device *dssdev);
+ u16 i2c_bus_num;
};
#endif /* __ARCH_ARM_PLAT_OMAP_PANEL_GENERIC_DPI_H */
diff --git a/arch/arm/plat-samsung/gpio-config.c b/arch/arm/plat-samsung/gpio-config.c
index 1c0b0401594..2a710b0a6df 100644
--- a/arch/arm/plat-samsung/gpio-config.c
+++ b/arch/arm/plat-samsung/gpio-config.c
@@ -320,6 +320,29 @@ s3c_gpio_pull_t s3c_gpio_getpull_s3c2443(struct s3c_gpio_chip *chip,
return pull;
}
#endif
+
+#ifdef CONFIG_CPU_EXYNOS4210
+int s3c_gpio_setpull_exynos4(struct s3c_gpio_chip *chip,
+ unsigned int off, s3c_gpio_pull_t pull)
+{
+ if (pull == S3C_GPIO_PULL_UP)
+ pull = 3;
+
+ return s3c_gpio_setpull_updown(chip, off, pull);
+}
+
+s3c_gpio_pull_t s3c_gpio_getpull_exynos4(struct s3c_gpio_chip *chip,
+ unsigned int off)
+{
+ s3c_gpio_pull_t pull;
+
+ pull = s3c_gpio_getpull_updown(chip, off);
+ if (pull == 3)
+ pull = S3C_GPIO_PULL_UP;
+
+ return pull;
+}
+#endif /* CONFIG_CPU_EXYNOS4210 */
#endif
#if defined(CONFIG_S3C_GPIO_PULL_UP) || defined(CONFIG_S3C_GPIO_PULL_DOWN)
diff --git a/arch/arm/plat-samsung/include/plat/gpio-cfg-helpers.h b/arch/arm/plat-samsung/include/plat/gpio-cfg-helpers.h
index 5603db0b79b..75c46b9f505 100644
--- a/arch/arm/plat-samsung/include/plat/gpio-cfg-helpers.h
+++ b/arch/arm/plat-samsung/include/plat/gpio-cfg-helpers.h
@@ -247,5 +247,30 @@ extern int s3c_gpio_setpull_s3c2443(struct s3c_gpio_chip *chip,
extern s3c_gpio_pull_t s3c_gpio_getpull_s3c2443(struct s3c_gpio_chip *chip,
unsigned int off);
+/**
+ * s3c_gpio_setpull_exynos4() - Pull configuration for Exynos 4210.
+ * @chip: The gpio chip that is being configured.
+ * @off: The offset for the GPIO being configured.
+ * @param: pull: The pull mode being requested.
+ *
+ * This is a wrapper function for s3c_gpio_setpull_updown() function.
+ * It provides a different mapping of S3C_GPIO_PULL_XXX to actual
+ * register settings.
+ */
+extern int s3c_gpio_setpull_exynos4(struct s3c_gpio_chip *chip,
+ unsigned int off, s3c_gpio_pull_t pull);
+
+/**
+ * s3c_gpio_getpull_exynos4() - Get configuration for Exynos 4210 pull resistors
+ * @chip: The gpio chip that the GPIO pin belongs to
+ * @off: The offset to the pin to get the configuration of.
+ *
+ * This is a wrapper function for s3c_gpio_getpull_updown() function.
+ * It provides a different mapping of S3C_GPIO_PULL_XXX to actual
+ * register settings.
+*/
+extern s3c_gpio_pull_t s3c_gpio_getpull_exynos4(struct s3c_gpio_chip *chip,
+ unsigned int off);
+
#endif /* __PLAT_GPIO_CFG_HELPERS_H */
diff --git a/arch/arm/vfp/vfpmodule.c b/arch/arm/vfp/vfpmodule.c
index bbf3da012af..f74695075e6 100644
--- a/arch/arm/vfp/vfpmodule.c
+++ b/arch/arm/vfp/vfpmodule.c
@@ -78,6 +78,14 @@ static void vfp_thread_exit(struct thread_info *thread)
put_cpu();
}
+static void vfp_thread_copy(struct thread_info *thread)
+{
+ struct thread_info *parent = current_thread_info();
+
+ vfp_sync_hwstate(parent);
+ thread->vfpstate = parent->vfpstate;
+}
+
/*
* When this function is called with the following 'cmd's, the following
* is true while this function is being run:
@@ -104,12 +112,17 @@ static void vfp_thread_exit(struct thread_info *thread)
static int vfp_notifier(struct notifier_block *self, unsigned long cmd, void *v)
{
struct thread_info *thread = v;
+ u32 fpexc;
+#ifdef CONFIG_SMP
+ unsigned int cpu;
+#endif
- if (likely(cmd == THREAD_NOTIFY_SWITCH)) {
- u32 fpexc = fmrx(FPEXC);
+ switch (cmd) {
+ case THREAD_NOTIFY_SWITCH:
+ fpexc = fmrx(FPEXC);
#ifdef CONFIG_SMP
- unsigned int cpu = thread->cpu;
+ cpu = thread->cpu;
/*
* On SMP, if VFP is enabled, save the old state in
@@ -134,13 +147,20 @@ static int vfp_notifier(struct notifier_block *self, unsigned long cmd, void *v)
* old state.
*/
fmxr(FPEXC, fpexc & ~FPEXC_EN);
- return NOTIFY_DONE;
- }
+ break;
- if (cmd == THREAD_NOTIFY_FLUSH)
+ case THREAD_NOTIFY_FLUSH:
vfp_thread_flush(thread);
- else
+ break;
+
+ case THREAD_NOTIFY_EXIT:
vfp_thread_exit(thread);
+ break;
+
+ case THREAD_NOTIFY_COPY:
+ vfp_thread_copy(thread);
+ break;
+ }
return NOTIFY_DONE;
}
diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c
index fcbe3f5c074..59abf59ef6c 100644
--- a/arch/powerpc/kernel/time.c
+++ b/arch/powerpc/kernel/time.c
@@ -357,7 +357,7 @@ void account_system_vtime(struct task_struct *tsk)
}
get_paca()->user_time_scaled += user_scaled;
- if (in_irq() || idle_task(smp_processor_id()) != tsk) {
+ if (in_interrupt() || idle_task(smp_processor_id()) != tsk) {
account_system_time(tsk, 0, delta, sys_scaled);
if (stolen)
account_steal_time(stolen);
diff --git a/arch/x86/crypto/aesni-intel_asm.S b/arch/x86/crypto/aesni-intel_asm.S
index 8fe2a4966b7..4292df78c9d 100644
--- a/arch/x86/crypto/aesni-intel_asm.S
+++ b/arch/x86/crypto/aesni-intel_asm.S
@@ -1612,6 +1612,7 @@ _zero_cipher_left_encrypt:
movdqa SHUF_MASK(%rip), %xmm10
PSHUFB_XMM %xmm10, %xmm0
+
ENCRYPT_SINGLE_BLOCK %xmm0, %xmm1 # Encrypt(K, Yn)
sub $16, %r11
add %r13, %r11
@@ -1634,7 +1635,9 @@ _zero_cipher_left_encrypt:
# GHASH computation for the last <16 byte block
sub %r13, %r11
add $16, %r11
- PSHUFB_XMM %xmm10, %xmm1
+
+ movdqa SHUF_MASK(%rip), %xmm10
+ PSHUFB_XMM %xmm10, %xmm0
# shuffle xmm0 back to output as ciphertext
diff --git a/arch/x86/crypto/aesni-intel_glue.c b/arch/x86/crypto/aesni-intel_glue.c
index e1e60c7d581..b375b2a7a14 100644
--- a/arch/x86/crypto/aesni-intel_glue.c
+++ b/arch/x86/crypto/aesni-intel_glue.c
@@ -828,9 +828,15 @@ static int rfc4106_init(struct crypto_tfm *tfm)
struct cryptd_aead *cryptd_tfm;
struct aesni_rfc4106_gcm_ctx *ctx = (struct aesni_rfc4106_gcm_ctx *)
PTR_ALIGN((u8 *)crypto_tfm_ctx(tfm), AESNI_ALIGN);
+ struct crypto_aead *cryptd_child;
+ struct aesni_rfc4106_gcm_ctx *child_ctx;
cryptd_tfm = cryptd_alloc_aead("__driver-gcm-aes-aesni", 0, 0);
if (IS_ERR(cryptd_tfm))
return PTR_ERR(cryptd_tfm);
+
+ cryptd_child = cryptd_aead_child(cryptd_tfm);
+ child_ctx = aesni_rfc4106_gcm_ctx_get(cryptd_child);
+ memcpy(child_ctx, ctx, sizeof(*ctx));
ctx->cryptd_tfm = cryptd_tfm;
tfm->crt_aead.reqsize = sizeof(struct aead_request)
+ crypto_aead_reqsize(&cryptd_tfm->base);
@@ -925,6 +931,9 @@ static int rfc4106_set_key(struct crypto_aead *parent, const u8 *key,
int ret = 0;
struct crypto_tfm *tfm = crypto_aead_tfm(parent);
struct aesni_rfc4106_gcm_ctx *ctx = aesni_rfc4106_gcm_ctx_get(parent);
+ struct crypto_aead *cryptd_child = cryptd_aead_child(ctx->cryptd_tfm);
+ struct aesni_rfc4106_gcm_ctx *child_ctx =
+ aesni_rfc4106_gcm_ctx_get(cryptd_child);
u8 *new_key_mem = NULL;
if (key_len < 4) {
@@ -968,6 +977,7 @@ static int rfc4106_set_key(struct crypto_aead *parent, const u8 *key,
goto exit;
}
ret = rfc4106_set_hash_subkey(ctx->hash_subkey, key, key_len);
+ memcpy(child_ctx, ctx, sizeof(*ctx));
exit:
kfree(new_key_mem);
return ret;
@@ -999,7 +1009,6 @@ static int rfc4106_encrypt(struct aead_request *req)
int ret;
struct crypto_aead *tfm = crypto_aead_reqtfm(req);
struct aesni_rfc4106_gcm_ctx *ctx = aesni_rfc4106_gcm_ctx_get(tfm);
- struct crypto_aead *cryptd_child = cryptd_aead_child(ctx->cryptd_tfm);
if (!irq_fpu_usable()) {
struct aead_request *cryptd_req =
@@ -1008,6 +1017,7 @@ static int rfc4106_encrypt(struct aead_request *req)
aead_request_set_tfm(cryptd_req, &ctx->cryptd_tfm->base);
return crypto_aead_encrypt(cryptd_req);
} else {
+ struct crypto_aead *cryptd_child = cryptd_aead_child(ctx->cryptd_tfm);
kernel_fpu_begin();
ret = cryptd_child->base.crt_aead.encrypt(req);
kernel_fpu_end();
@@ -1020,7 +1030,6 @@ static int rfc4106_decrypt(struct aead_request *req)
int ret;
struct crypto_aead *tfm = crypto_aead_reqtfm(req);
struct aesni_rfc4106_gcm_ctx *ctx = aesni_rfc4106_gcm_ctx_get(tfm);
- struct crypto_aead *cryptd_child = cryptd_aead_child(ctx->cryptd_tfm);
if (!irq_fpu_usable()) {
struct aead_request *cryptd_req =
@@ -1029,6 +1038,7 @@ static int rfc4106_decrypt(struct aead_request *req)
aead_request_set_tfm(cryptd_req, &ctx->cryptd_tfm->base);
return crypto_aead_decrypt(cryptd_req);
} else {
+ struct crypto_aead *cryptd_child = cryptd_aead_child(ctx->cryptd_tfm);
kernel_fpu_begin();
ret = cryptd_child->base.crt_aead.decrypt(req);
kernel_fpu_end();
diff --git a/arch/x86/kernel/cpu/mtrr/main.c b/arch/x86/kernel/cpu/mtrr/main.c
index bebabec5b44..151787e382c 100644
--- a/arch/x86/kernel/cpu/mtrr/main.c
+++ b/arch/x86/kernel/cpu/mtrr/main.c
@@ -292,14 +292,24 @@ set_mtrr(unsigned int reg, unsigned long base, unsigned long size, mtrr_type typ
/*
* HACK!
- * We use this same function to initialize the mtrrs on boot.
- * The state of the boot cpu's mtrrs has been saved, and we want
- * to replicate across all the APs.
- * If we're doing that @reg is set to something special...
+ *
+ * We use this same function to initialize the mtrrs during boot,
+ * resume, runtime cpu online and on an explicit request to set a
+ * specific MTRR.
+ *
+ * During boot or suspend, the state of the boot cpu's mtrrs has been
+ * saved, and we want to replicate that across all the cpus that come
+ * online (either at the end of boot or resume or during a runtime cpu
+ * online). If we're doing that, @reg is set to something special and on
+ * this cpu we still do mtrr_if->set_all(). During boot/resume, this
+ * is unnecessary if at this point we are still on the cpu that started
+ * the boot/resume sequence. But there is no guarantee that we are still
+ * on the same cpu. So we do mtrr_if->set_all() on this cpu aswell to be
+ * sure that we are in sync with everyone else.
*/
if (reg != ~0U)
mtrr_if->set(reg, base, size, type);
- else if (!mtrr_aps_delayed_init)
+ else
mtrr_if->set_all();
/* Wait for the others */
diff --git a/arch/x86/kernel/head64.c b/arch/x86/kernel/head64.c
index 5655c2272ad..2d2673c28af 100644
--- a/arch/x86/kernel/head64.c
+++ b/arch/x86/kernel/head64.c
@@ -77,6 +77,9 @@ void __init x86_64_start_kernel(char * real_mode_data)
/* Make NULL pointers segfault */
zap_identity_mappings();
+ /* Cleanup the over mapped high alias */
+ cleanup_highmap();
+
max_pfn_mapped = KERNEL_IMAGE_SIZE >> PAGE_SHIFT;
for (i = 0; i < NUM_EXCEPTION_VECTORS; i++) {
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index e543fe9311e..d3cfe26c025 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -297,9 +297,6 @@ static void __init init_gbpages(void)
static inline void init_gbpages(void)
{
}
-static void __init cleanup_highmap(void)
-{
-}
#endif
static void __init reserve_brk(void)
@@ -925,8 +922,6 @@ void __init setup_arch(char **cmdline_p)
*/
reserve_brk();
- cleanup_highmap();
-
memblock.current_limit = get_max_mapped();
memblock_x86_fill();
diff --git a/arch/x86/mm/init.c b/arch/x86/mm/init.c
index f13ff3a2267..947f42abe82 100644
--- a/arch/x86/mm/init.c
+++ b/arch/x86/mm/init.c
@@ -279,6 +279,25 @@ unsigned long __init_refok init_memory_mapping(unsigned long start,
load_cr3(swapper_pg_dir);
#endif
+#ifdef CONFIG_X86_64
+ if (!after_bootmem && !start) {
+ pud_t *pud;
+ pmd_t *pmd;
+
+ mmu_cr4_features = read_cr4();
+
+ /*
+ * _brk_end cannot change anymore, but it and _end may be
+ * located on different 2M pages. cleanup_highmap(), however,
+ * can only consider _end when it runs, so destroy any
+ * mappings beyond _brk_end here.
+ */
+ pud = pud_offset(pgd_offset_k(_brk_end), _brk_end);
+ pmd = pmd_offset(pud, _brk_end - 1);
+ while (++pmd <= pmd_offset(pud, (unsigned long)_end - 1))
+ pmd_clear(pmd);
+ }
+#endif
__flush_tlb_all();
if (!after_bootmem && e820_table_end > e820_table_start)
diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c
index 68f9921ae9c..c14a5422e15 100644
--- a/arch/x86/mm/init_64.c
+++ b/arch/x86/mm/init_64.c
@@ -51,7 +51,6 @@
#include <asm/numa.h>
#include <asm/cacheflush.h>
#include <asm/init.h>
-#include <asm/setup.h>
static int __init parse_direct_gbpages_off(char *arg)
{
@@ -294,18 +293,18 @@ void __init init_extra_mapping_uc(unsigned long phys, unsigned long size)
* to the compile time generated pmds. This results in invalid pmds up
* to the point where we hit the physaddr 0 mapping.
*
- * We limit the mappings to the region from _text to _brk_end. _brk_end
- * is rounded up to the 2MB boundary. This catches the invalid pmds as
+ * We limit the mappings to the region from _text to _end. _end is
+ * rounded up to the 2MB boundary. This catches the invalid pmds as
* well, as they are located before _text:
*/
void __init cleanup_highmap(void)
{
unsigned long vaddr = __START_KERNEL_map;
- unsigned long vaddr_end = __START_KERNEL_map + (max_pfn_mapped << PAGE_SHIFT);
- unsigned long end = roundup((unsigned long)_brk_end, PMD_SIZE) - 1;
+ unsigned long end = roundup((unsigned long)_end, PMD_SIZE) - 1;
pmd_t *pmd = level2_kernel_pgt;
+ pmd_t *last_pmd = pmd + PTRS_PER_PMD;
- for (; vaddr + PMD_SIZE - 1 < vaddr_end; pmd++, vaddr += PMD_SIZE) {
+ for (; pmd < last_pmd; pmd++, vaddr += PMD_SIZE) {
if (pmd_none(*pmd))
continue;
if (vaddr < (unsigned long) _text || vaddr > end)