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: (100 commits) ARM: Eliminate decompressor -Dstatic= PIC hack ARM: 5958/1: ARM: U300: fix inverted clk round rate ARM: 5956/1: misplaced parentheses ARM: 5955/1: ep93xx: move timer defines into core.c and document ARM: 5954/1: ep93xx: move gpio interrupt support to gpio.c ARM: 5953/1: ep93xx: fix broken build of clock.c ARM: 5952/1: ARM: MM: Add ARM_L1_CACHE_SHIFT_6 for handle inside each ARCH Kconfig ARM: 5949/1: NUC900 add gpio virtual memory map ARM: 5948/1: Enable timer0 to time4 clock support for nuc910 ARM: 5940/2: ARM: MMCI: remove custom DBG macro and printk ARM: make_coherent(): fix problems with highpte, part 2 MM: Pass a PTE pointer to update_mmu_cache() rather than the PTE itself ARM: 5945/1: ep93xx: include correct irq.h in core.c ARM: 5933/1: amba-pl011: support hardware flow control ARM: 5930/1: Add PKMAP area description to memory.txt. ARM: 5929/1: Add checks to detect overlap of memory regions. ARM: 5928/1: Change type of VMALLOC_END to unsigned long. ARM: 5927/1: Make delimiters of DMA area globally visibly. ARM: 5926/1: Add "Virtual kernel memory..." printout. ARM: 5920/1: OMAP4: Enable L2 Cache ... Fix up trivial conflict in arch/arm/mach-mx25/clock.c
This commit is contained in:
@@ -17,6 +17,7 @@ obj-y := compat.o elf.o entry-armv.o entry-common.o irq.o \
|
||||
process.o ptrace.o return_address.o setup.o signal.o \
|
||||
sys_arm.o stacktrace.o time.o traps.o
|
||||
|
||||
obj-$(CONFIG_LEDS) += leds.o
|
||||
obj-$(CONFIG_OC_ETM) += etm.o
|
||||
|
||||
obj-$(CONFIG_ISA_DMA_API) += dma.o
|
||||
@@ -46,6 +47,8 @@ obj-$(CONFIG_CPU_XSCALE) += xscale-cp0.o
|
||||
obj-$(CONFIG_CPU_XSC3) += xscale-cp0.o
|
||||
obj-$(CONFIG_CPU_MOHAWK) += xscale-cp0.o
|
||||
obj-$(CONFIG_IWMMXT) += iwmmxt.o
|
||||
obj-$(CONFIG_CPU_HAS_PMU) += pmu.o
|
||||
obj-$(CONFIG_HW_PERF_EVENTS) += perf_event.o
|
||||
AFLAGS_iwmmxt.o := -Wa,-mcpu=iwmmxt
|
||||
|
||||
ifneq ($(CONFIG_ARCH_EBSA110),y)
|
||||
|
@@ -12,6 +12,7 @@
|
||||
*/
|
||||
#include <linux/sched.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <asm/mach/arch.h>
|
||||
#include <asm/thread_info.h>
|
||||
#include <asm/memory.h>
|
||||
@@ -112,5 +113,9 @@ int main(void)
|
||||
#ifdef MULTI_PABORT
|
||||
DEFINE(PROCESSOR_PABT_FUNC, offsetof(struct processor, _prefetch_abort));
|
||||
#endif
|
||||
BLANK();
|
||||
DEFINE(DMA_BIDIRECTIONAL, DMA_BIDIRECTIONAL);
|
||||
DEFINE(DMA_TO_DEVICE, DMA_TO_DEVICE);
|
||||
DEFINE(DMA_FROM_DEVICE, DMA_FROM_DEVICE);
|
||||
return 0;
|
||||
}
|
||||
|
@@ -24,7 +24,7 @@
|
||||
|
||||
#if defined(CONFIG_CPU_V6)
|
||||
|
||||
.macro addruart, rx
|
||||
.macro addruart, rx, tmp
|
||||
.endm
|
||||
|
||||
.macro senduart, rd, rx
|
||||
@@ -51,7 +51,7 @@
|
||||
|
||||
#elif defined(CONFIG_CPU_V7)
|
||||
|
||||
.macro addruart, rx
|
||||
.macro addruart, rx, tmp
|
||||
.endm
|
||||
|
||||
.macro senduart, rd, rx
|
||||
@@ -71,7 +71,7 @@ wait: mrc p14, 0, pc, c0, c1, 0
|
||||
|
||||
#elif defined(CONFIG_CPU_XSCALE)
|
||||
|
||||
.macro addruart, rx
|
||||
.macro addruart, rx, tmp
|
||||
.endm
|
||||
|
||||
.macro senduart, rd, rx
|
||||
@@ -98,7 +98,7 @@ wait: mrc p14, 0, pc, c0, c1, 0
|
||||
|
||||
#else
|
||||
|
||||
.macro addruart, rx
|
||||
.macro addruart, rx, tmp
|
||||
.endm
|
||||
|
||||
.macro senduart, rd, rx
|
||||
@@ -164,7 +164,7 @@ ENDPROC(printhex2)
|
||||
.ltorg
|
||||
|
||||
ENTRY(printascii)
|
||||
addruart r3
|
||||
addruart r3, r1
|
||||
b 2f
|
||||
1: waituart r2, r3
|
||||
senduart r1, r3
|
||||
@@ -180,7 +180,7 @@ ENTRY(printascii)
|
||||
ENDPROC(printascii)
|
||||
|
||||
ENTRY(printch)
|
||||
addruart r3
|
||||
addruart r3, r1
|
||||
mov r1, r0
|
||||
mov r0, #0
|
||||
b 1b
|
||||
|
115
arch/arm/kernel/leds.c
Normal file
115
arch/arm/kernel/leds.c
Normal file
@@ -0,0 +1,115 @@
|
||||
/*
|
||||
* LED support code, ripped out of arch/arm/kernel/time.c
|
||||
*
|
||||
* Copyright (C) 1994-2001 Russell King
|
||||
*
|
||||
* 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/module.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/sysdev.h>
|
||||
|
||||
#include <asm/leds.h>
|
||||
|
||||
static void dummy_leds_event(led_event_t evt)
|
||||
{
|
||||
}
|
||||
|
||||
void (*leds_event)(led_event_t) = dummy_leds_event;
|
||||
|
||||
struct leds_evt_name {
|
||||
const char name[8];
|
||||
int on;
|
||||
int off;
|
||||
};
|
||||
|
||||
static const struct leds_evt_name evt_names[] = {
|
||||
{ "amber", led_amber_on, led_amber_off },
|
||||
{ "blue", led_blue_on, led_blue_off },
|
||||
{ "green", led_green_on, led_green_off },
|
||||
{ "red", led_red_on, led_red_off },
|
||||
};
|
||||
|
||||
static ssize_t leds_store(struct sys_device *dev,
|
||||
struct sysdev_attribute *attr,
|
||||
const char *buf, size_t size)
|
||||
{
|
||||
int ret = -EINVAL, len = strcspn(buf, " ");
|
||||
|
||||
if (len > 0 && buf[len] == '\0')
|
||||
len--;
|
||||
|
||||
if (strncmp(buf, "claim", len) == 0) {
|
||||
leds_event(led_claim);
|
||||
ret = size;
|
||||
} else if (strncmp(buf, "release", len) == 0) {
|
||||
leds_event(led_release);
|
||||
ret = size;
|
||||
} else {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(evt_names); i++) {
|
||||
if (strlen(evt_names[i].name) != len ||
|
||||
strncmp(buf, evt_names[i].name, len) != 0)
|
||||
continue;
|
||||
if (strncmp(buf+len, " on", 3) == 0) {
|
||||
leds_event(evt_names[i].on);
|
||||
ret = size;
|
||||
} else if (strncmp(buf+len, " off", 4) == 0) {
|
||||
leds_event(evt_names[i].off);
|
||||
ret = size;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static SYSDEV_ATTR(event, 0200, NULL, leds_store);
|
||||
|
||||
static int leds_suspend(struct sys_device *dev, pm_message_t state)
|
||||
{
|
||||
leds_event(led_stop);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int leds_resume(struct sys_device *dev)
|
||||
{
|
||||
leds_event(led_start);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int leds_shutdown(struct sys_device *dev)
|
||||
{
|
||||
leds_event(led_halted);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct sysdev_class leds_sysclass = {
|
||||
.name = "leds",
|
||||
.shutdown = leds_shutdown,
|
||||
.suspend = leds_suspend,
|
||||
.resume = leds_resume,
|
||||
};
|
||||
|
||||
static struct sys_device leds_device = {
|
||||
.id = 0,
|
||||
.cls = &leds_sysclass,
|
||||
};
|
||||
|
||||
static int __init leds_init(void)
|
||||
{
|
||||
int ret;
|
||||
ret = sysdev_class_register(&leds_sysclass);
|
||||
if (ret == 0)
|
||||
ret = sysdev_register(&leds_device);
|
||||
if (ret == 0)
|
||||
ret = sysdev_create_file(&leds_device, &attr_event);
|
||||
return ret;
|
||||
}
|
||||
|
||||
device_initcall(leds_init);
|
||||
|
||||
EXPORT_SYMBOL(leds_event);
|
2276
arch/arm/kernel/perf_event.c
Normal file
2276
arch/arm/kernel/perf_event.c
Normal file
File diff suppressed because it is too large
Load Diff
103
arch/arm/kernel/pmu.c
Normal file
103
arch/arm/kernel/pmu.c
Normal file
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
* linux/arch/arm/kernel/pmu.c
|
||||
*
|
||||
* Copyright (C) 2009 picoChip Designs Ltd, Jamie Iles
|
||||
*
|
||||
* 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/cpumask.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
#include <asm/pmu.h>
|
||||
|
||||
/*
|
||||
* Define the IRQs for the system. We could use something like a platform
|
||||
* device but that seems fairly heavyweight for this. Also, the performance
|
||||
* counters can't be removed or hotplugged.
|
||||
*
|
||||
* Ordering is important: init_pmu() will use the ordering to set the affinity
|
||||
* to the corresponding core. e.g. the first interrupt will go to cpu 0, the
|
||||
* second goes to cpu 1 etc.
|
||||
*/
|
||||
static const int irqs[] = {
|
||||
#if defined(CONFIG_ARCH_OMAP2)
|
||||
3,
|
||||
#elif defined(CONFIG_ARCH_BCMRING)
|
||||
IRQ_PMUIRQ,
|
||||
#elif defined(CONFIG_MACH_REALVIEW_EB)
|
||||
IRQ_EB11MP_PMU_CPU0,
|
||||
IRQ_EB11MP_PMU_CPU1,
|
||||
IRQ_EB11MP_PMU_CPU2,
|
||||
IRQ_EB11MP_PMU_CPU3,
|
||||
#elif defined(CONFIG_ARCH_OMAP3)
|
||||
INT_34XX_BENCH_MPU_EMUL,
|
||||
#elif defined(CONFIG_ARCH_IOP32X)
|
||||
IRQ_IOP32X_CORE_PMU,
|
||||
#elif defined(CONFIG_ARCH_IOP33X)
|
||||
IRQ_IOP33X_CORE_PMU,
|
||||
#elif defined(CONFIG_ARCH_PXA)
|
||||
IRQ_PMU,
|
||||
#endif
|
||||
};
|
||||
|
||||
static const struct pmu_irqs pmu_irqs = {
|
||||
.irqs = irqs,
|
||||
.num_irqs = ARRAY_SIZE(irqs),
|
||||
};
|
||||
|
||||
static volatile long pmu_lock;
|
||||
|
||||
const struct pmu_irqs *
|
||||
reserve_pmu(void)
|
||||
{
|
||||
return test_and_set_bit_lock(0, &pmu_lock) ? ERR_PTR(-EBUSY) :
|
||||
&pmu_irqs;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(reserve_pmu);
|
||||
|
||||
int
|
||||
release_pmu(const struct pmu_irqs *irqs)
|
||||
{
|
||||
if (WARN_ON(irqs != &pmu_irqs))
|
||||
return -EINVAL;
|
||||
clear_bit_unlock(0, &pmu_lock);
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(release_pmu);
|
||||
|
||||
static int
|
||||
set_irq_affinity(int irq,
|
||||
unsigned int cpu)
|
||||
{
|
||||
#ifdef CONFIG_SMP
|
||||
int err = irq_set_affinity(irq, cpumask_of(cpu));
|
||||
if (err)
|
||||
pr_warning("unable to set irq affinity (irq=%d, cpu=%u)\n",
|
||||
irq, cpu);
|
||||
return err;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
int
|
||||
init_pmu(void)
|
||||
{
|
||||
int i, err = 0;
|
||||
|
||||
for (i = 0; i < pmu_irqs.num_irqs; ++i) {
|
||||
err = set_irq_affinity(pmu_irqs.irqs[i], i);
|
||||
if (err)
|
||||
break;
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(init_pmu);
|
@@ -499,10 +499,41 @@ static struct undef_hook thumb_break_hook = {
|
||||
.fn = break_trap,
|
||||
};
|
||||
|
||||
static int thumb2_break_trap(struct pt_regs *regs, unsigned int instr)
|
||||
{
|
||||
unsigned int instr2;
|
||||
void __user *pc;
|
||||
|
||||
/* Check the second half of the instruction. */
|
||||
pc = (void __user *)(instruction_pointer(regs) + 2);
|
||||
|
||||
if (processor_mode(regs) == SVC_MODE) {
|
||||
instr2 = *(u16 *) pc;
|
||||
} else {
|
||||
get_user(instr2, (u16 __user *)pc);
|
||||
}
|
||||
|
||||
if (instr2 == 0xa000) {
|
||||
ptrace_break(current, regs);
|
||||
return 0;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
static struct undef_hook thumb2_break_hook = {
|
||||
.instr_mask = 0xffff,
|
||||
.instr_val = 0xf7f0,
|
||||
.cpsr_mask = PSR_T_BIT,
|
||||
.cpsr_val = PSR_T_BIT,
|
||||
.fn = thumb2_break_trap,
|
||||
};
|
||||
|
||||
static int __init ptrace_break_init(void)
|
||||
{
|
||||
register_undef_hook(&arm_break_hook);
|
||||
register_undef_hook(&thumb_break_hook);
|
||||
register_undef_hook(&thumb2_break_hook);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -669,7 +700,7 @@ static int ptrace_getvfpregs(struct task_struct *tsk, void __user *data)
|
||||
union vfp_state *vfp = &thread->vfpstate;
|
||||
struct user_vfp __user *ufp = data;
|
||||
|
||||
vfp_sync_state(thread);
|
||||
vfp_sync_hwstate(thread);
|
||||
|
||||
/* copy the floating point registers */
|
||||
if (copy_to_user(&ufp->fpregs, &vfp->hard.fpregs,
|
||||
@@ -692,7 +723,7 @@ static int ptrace_setvfpregs(struct task_struct *tsk, void __user *data)
|
||||
union vfp_state *vfp = &thread->vfpstate;
|
||||
struct user_vfp __user *ufp = data;
|
||||
|
||||
vfp_sync_state(thread);
|
||||
vfp_sync_hwstate(thread);
|
||||
|
||||
/* copy the floating point registers */
|
||||
if (copy_from_user(&vfp->hard.fpregs, &ufp->fpregs,
|
||||
@@ -703,6 +734,8 @@ static int ptrace_setvfpregs(struct task_struct *tsk, void __user *data)
|
||||
if (get_user(vfp->hard.fpscr, &ufp->fpscr))
|
||||
return -EFAULT;
|
||||
|
||||
vfp_flush_hwstate(thread);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
@@ -712,26 +745,10 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
|
||||
int ret;
|
||||
|
||||
switch (request) {
|
||||
/*
|
||||
* read word at location "addr" in the child process.
|
||||
*/
|
||||
case PTRACE_PEEKTEXT:
|
||||
case PTRACE_PEEKDATA:
|
||||
ret = generic_ptrace_peekdata(child, addr, data);
|
||||
break;
|
||||
|
||||
case PTRACE_PEEKUSR:
|
||||
ret = ptrace_read_user(child, addr, (unsigned long __user *)data);
|
||||
break;
|
||||
|
||||
/*
|
||||
* write the word at location addr.
|
||||
*/
|
||||
case PTRACE_POKETEXT:
|
||||
case PTRACE_POKEDATA:
|
||||
ret = generic_ptrace_pokedata(child, addr, data);
|
||||
break;
|
||||
|
||||
case PTRACE_POKEUSR:
|
||||
ret = ptrace_write_user(child, addr, data);
|
||||
break;
|
||||
|
@@ -24,6 +24,7 @@
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/smp.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/proc_fs.h>
|
||||
|
||||
#include <asm/unified.h>
|
||||
#include <asm/cpu.h>
|
||||
@@ -118,7 +119,7 @@ EXPORT_SYMBOL(elf_platform);
|
||||
|
||||
static const char *cpu_name;
|
||||
static const char *machine_name;
|
||||
static char __initdata command_line[COMMAND_LINE_SIZE];
|
||||
static char __initdata cmd_line[COMMAND_LINE_SIZE];
|
||||
|
||||
static char default_command_line[COMMAND_LINE_SIZE] __initdata = CONFIG_CMDLINE;
|
||||
static union { char c[4]; unsigned long l; } endian_test __initdata = { { 'l', '?', '?', 'b' } };
|
||||
@@ -418,10 +419,11 @@ static int __init arm_add_memory(unsigned long start, unsigned long size)
|
||||
* Pick out the memory size. We look for mem=size@start,
|
||||
* where start and size are "size[KkMm]"
|
||||
*/
|
||||
static void __init early_mem(char **p)
|
||||
static int __init early_mem(char *p)
|
||||
{
|
||||
static int usermem __initdata = 0;
|
||||
unsigned long size, start;
|
||||
char *endp;
|
||||
|
||||
/*
|
||||
* If the user specifies memory size, we
|
||||
@@ -434,52 +436,15 @@ static void __init early_mem(char **p)
|
||||
}
|
||||
|
||||
start = PHYS_OFFSET;
|
||||
size = memparse(*p, p);
|
||||
if (**p == '@')
|
||||
start = memparse(*p + 1, p);
|
||||
size = memparse(p, &endp);
|
||||
if (*endp == '@')
|
||||
start = memparse(endp + 1, NULL);
|
||||
|
||||
arm_add_memory(start, size);
|
||||
|
||||
return 0;
|
||||
}
|
||||
__early_param("mem=", early_mem);
|
||||
|
||||
/*
|
||||
* Initial parsing of the command line.
|
||||
*/
|
||||
static void __init parse_cmdline(char **cmdline_p, char *from)
|
||||
{
|
||||
char c = ' ', *to = command_line;
|
||||
int len = 0;
|
||||
|
||||
for (;;) {
|
||||
if (c == ' ') {
|
||||
extern struct early_params __early_begin, __early_end;
|
||||
struct early_params *p;
|
||||
|
||||
for (p = &__early_begin; p < &__early_end; p++) {
|
||||
int arglen = strlen(p->arg);
|
||||
|
||||
if (memcmp(from, p->arg, arglen) == 0) {
|
||||
if (to != command_line)
|
||||
to -= 1;
|
||||
from += arglen;
|
||||
p->fn(&from);
|
||||
|
||||
while (*from != ' ' && *from != '\0')
|
||||
from++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
c = *from++;
|
||||
if (!c)
|
||||
break;
|
||||
if (COMMAND_LINE_SIZE <= ++len)
|
||||
break;
|
||||
*to++ = c;
|
||||
}
|
||||
*to = '\0';
|
||||
*cmdline_p = command_line;
|
||||
}
|
||||
early_param("mem", early_mem);
|
||||
|
||||
static void __init
|
||||
setup_ramdisk(int doload, int prompt, int image_start, unsigned int rd_sz)
|
||||
@@ -740,9 +705,15 @@ void __init setup_arch(char **cmdline_p)
|
||||
init_mm.end_data = (unsigned long) _edata;
|
||||
init_mm.brk = (unsigned long) _end;
|
||||
|
||||
memcpy(boot_command_line, from, COMMAND_LINE_SIZE);
|
||||
boot_command_line[COMMAND_LINE_SIZE-1] = '\0';
|
||||
parse_cmdline(cmdline_p, from);
|
||||
/* parse_early_param needs a boot_command_line */
|
||||
strlcpy(boot_command_line, from, COMMAND_LINE_SIZE);
|
||||
|
||||
/* populate cmd_line too for later use, preserving boot_command_line */
|
||||
strlcpy(cmd_line, boot_command_line, COMMAND_LINE_SIZE);
|
||||
*cmdline_p = cmd_line;
|
||||
|
||||
parse_early_param();
|
||||
|
||||
paging_init(mdesc);
|
||||
request_standard_resources(&meminfo, mdesc);
|
||||
|
||||
@@ -783,9 +754,21 @@ static int __init topology_init(void)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
subsys_initcall(topology_init);
|
||||
|
||||
#ifdef CONFIG_HAVE_PROC_CPU
|
||||
static int __init proc_cpu_init(void)
|
||||
{
|
||||
struct proc_dir_entry *res;
|
||||
|
||||
res = proc_mkdir("cpu", NULL);
|
||||
if (!res)
|
||||
return -ENOMEM;
|
||||
return 0;
|
||||
}
|
||||
fs_initcall(proc_cpu_init);
|
||||
#endif
|
||||
|
||||
static const char *hwcap_str[] = {
|
||||
"swp",
|
||||
"half",
|
||||
|
@@ -10,11 +10,6 @@
|
||||
*
|
||||
* This file contains the ARM-specific time handling details:
|
||||
* reading the RTC at bootup, etc...
|
||||
*
|
||||
* 1994-07-02 Alan Modra
|
||||
* fixed set_rtc_mmss, fixed time.year for >= 2000, new mktime
|
||||
* 1998-12-20 Updated NTP code according to technical memorandum Jan '96
|
||||
* "A Kernel Model for Precision Timekeeping" by Dave Mills
|
||||
*/
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
@@ -77,11 +72,6 @@ unsigned long profile_pc(struct pt_regs *regs)
|
||||
EXPORT_SYMBOL(profile_pc);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* hook for setting the RTC's idea of the current time.
|
||||
*/
|
||||
int (*set_rtc)(void);
|
||||
|
||||
#ifndef CONFIG_GENERIC_TIME
|
||||
static unsigned long dummy_gettimeoffset(void)
|
||||
{
|
||||
@@ -89,140 +79,6 @@ static unsigned long dummy_gettimeoffset(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
static unsigned long next_rtc_update;
|
||||
|
||||
/*
|
||||
* If we have an externally synchronized linux clock, then update
|
||||
* CMOS clock accordingly every ~11 minutes. set_rtc() has to be
|
||||
* called as close as possible to 500 ms before the new second
|
||||
* starts.
|
||||
*/
|
||||
static inline void do_set_rtc(void)
|
||||
{
|
||||
if (!ntp_synced() || set_rtc == NULL)
|
||||
return;
|
||||
|
||||
if (next_rtc_update &&
|
||||
time_before((unsigned long)xtime.tv_sec, next_rtc_update))
|
||||
return;
|
||||
|
||||
if (xtime.tv_nsec < 500000000 - ((unsigned) tick_nsec >> 1) &&
|
||||
xtime.tv_nsec >= 500000000 + ((unsigned) tick_nsec >> 1))
|
||||
return;
|
||||
|
||||
if (set_rtc())
|
||||
/*
|
||||
* rtc update failed. Try again in 60s
|
||||
*/
|
||||
next_rtc_update = xtime.tv_sec + 60;
|
||||
else
|
||||
next_rtc_update = xtime.tv_sec + 660;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_LEDS
|
||||
|
||||
static void dummy_leds_event(led_event_t evt)
|
||||
{
|
||||
}
|
||||
|
||||
void (*leds_event)(led_event_t) = dummy_leds_event;
|
||||
|
||||
struct leds_evt_name {
|
||||
const char name[8];
|
||||
int on;
|
||||
int off;
|
||||
};
|
||||
|
||||
static const struct leds_evt_name evt_names[] = {
|
||||
{ "amber", led_amber_on, led_amber_off },
|
||||
{ "blue", led_blue_on, led_blue_off },
|
||||
{ "green", led_green_on, led_green_off },
|
||||
{ "red", led_red_on, led_red_off },
|
||||
};
|
||||
|
||||
static ssize_t leds_store(struct sys_device *dev,
|
||||
struct sysdev_attribute *attr,
|
||||
const char *buf, size_t size)
|
||||
{
|
||||
int ret = -EINVAL, len = strcspn(buf, " ");
|
||||
|
||||
if (len > 0 && buf[len] == '\0')
|
||||
len--;
|
||||
|
||||
if (strncmp(buf, "claim", len) == 0) {
|
||||
leds_event(led_claim);
|
||||
ret = size;
|
||||
} else if (strncmp(buf, "release", len) == 0) {
|
||||
leds_event(led_release);
|
||||
ret = size;
|
||||
} else {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(evt_names); i++) {
|
||||
if (strlen(evt_names[i].name) != len ||
|
||||
strncmp(buf, evt_names[i].name, len) != 0)
|
||||
continue;
|
||||
if (strncmp(buf+len, " on", 3) == 0) {
|
||||
leds_event(evt_names[i].on);
|
||||
ret = size;
|
||||
} else if (strncmp(buf+len, " off", 4) == 0) {
|
||||
leds_event(evt_names[i].off);
|
||||
ret = size;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static SYSDEV_ATTR(event, 0200, NULL, leds_store);
|
||||
|
||||
static int leds_suspend(struct sys_device *dev, pm_message_t state)
|
||||
{
|
||||
leds_event(led_stop);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int leds_resume(struct sys_device *dev)
|
||||
{
|
||||
leds_event(led_start);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int leds_shutdown(struct sys_device *dev)
|
||||
{
|
||||
leds_event(led_halted);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct sysdev_class leds_sysclass = {
|
||||
.name = "leds",
|
||||
.shutdown = leds_shutdown,
|
||||
.suspend = leds_suspend,
|
||||
.resume = leds_resume,
|
||||
};
|
||||
|
||||
static struct sys_device leds_device = {
|
||||
.id = 0,
|
||||
.cls = &leds_sysclass,
|
||||
};
|
||||
|
||||
static int __init leds_init(void)
|
||||
{
|
||||
int ret;
|
||||
ret = sysdev_class_register(&leds_sysclass);
|
||||
if (ret == 0)
|
||||
ret = sysdev_register(&leds_device);
|
||||
if (ret == 0)
|
||||
ret = sysdev_create_file(&leds_device, &attr_event);
|
||||
return ret;
|
||||
}
|
||||
|
||||
device_initcall(leds_init);
|
||||
|
||||
EXPORT_SYMBOL(leds_event);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_LEDS_TIMER
|
||||
static inline void do_leds(void)
|
||||
{
|
||||
@@ -295,39 +151,6 @@ int do_settimeofday(struct timespec *tv)
|
||||
EXPORT_SYMBOL(do_settimeofday);
|
||||
#endif /* !CONFIG_GENERIC_TIME */
|
||||
|
||||
/**
|
||||
* save_time_delta - Save the offset between system time and RTC time
|
||||
* @delta: pointer to timespec to store delta
|
||||
* @rtc: pointer to timespec for current RTC time
|
||||
*
|
||||
* Return a delta between the system time and the RTC time, such
|
||||
* that system time can be restored later with restore_time_delta()
|
||||
*/
|
||||
void save_time_delta(struct timespec *delta, struct timespec *rtc)
|
||||
{
|
||||
set_normalized_timespec(delta,
|
||||
xtime.tv_sec - rtc->tv_sec,
|
||||
xtime.tv_nsec - rtc->tv_nsec);
|
||||
}
|
||||
EXPORT_SYMBOL(save_time_delta);
|
||||
|
||||
/**
|
||||
* restore_time_delta - Restore the current system time
|
||||
* @delta: delta returned by save_time_delta()
|
||||
* @rtc: pointer to timespec for current RTC time
|
||||
*/
|
||||
void restore_time_delta(struct timespec *delta, struct timespec *rtc)
|
||||
{
|
||||
struct timespec ts;
|
||||
|
||||
set_normalized_timespec(&ts,
|
||||
delta->tv_sec + rtc->tv_sec,
|
||||
delta->tv_nsec + rtc->tv_nsec);
|
||||
|
||||
do_settimeofday(&ts);
|
||||
}
|
||||
EXPORT_SYMBOL(restore_time_delta);
|
||||
|
||||
#ifndef CONFIG_GENERIC_CLOCKEVENTS
|
||||
/*
|
||||
* Kernel system timer support.
|
||||
@@ -336,7 +159,6 @@ void timer_tick(void)
|
||||
{
|
||||
profile_tick(CPU_PROFILING);
|
||||
do_leds();
|
||||
do_set_rtc();
|
||||
write_seqlock(&xtime_lock);
|
||||
do_timer(1);
|
||||
write_sequnlock(&xtime_lock);
|
||||
|
@@ -12,15 +12,17 @@
|
||||
* 'linux/arch/arm/lib/traps.S'. Mostly a debugging aid, but will probably
|
||||
* kill the offending process.
|
||||
*/
|
||||
#include <linux/module.h>
|
||||
#include <linux/signal.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/personality.h>
|
||||
#include <linux/kallsyms.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/hardirq.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/hardirq.h>
|
||||
#include <linux/kdebug.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/kexec.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/init.h>
|
||||
|
||||
#include <asm/atomic.h>
|
||||
#include <asm/cacheflush.h>
|
||||
@@ -224,14 +226,21 @@ void show_stack(struct task_struct *tsk, unsigned long *sp)
|
||||
#define S_SMP ""
|
||||
#endif
|
||||
|
||||
static void __die(const char *str, int err, struct thread_info *thread, struct pt_regs *regs)
|
||||
static int __die(const char *str, int err, struct thread_info *thread, struct pt_regs *regs)
|
||||
{
|
||||
struct task_struct *tsk = thread->task;
|
||||
static int die_counter;
|
||||
int ret;
|
||||
|
||||
printk(KERN_EMERG "Internal error: %s: %x [#%d]" S_PREEMPT S_SMP "\n",
|
||||
str, err, ++die_counter);
|
||||
sysfs_printk_last_file();
|
||||
|
||||
/* trap and error numbers are mostly meaningless on ARM */
|
||||
ret = notify_die(DIE_OOPS, str, regs, err, tsk->thread.trap_no, SIGSEGV);
|
||||
if (ret == NOTIFY_STOP)
|
||||
return ret;
|
||||
|
||||
print_modules();
|
||||
__show_regs(regs);
|
||||
printk(KERN_EMERG "Process %.*s (pid: %d, stack limit = 0x%p)\n",
|
||||
@@ -243,6 +252,8 @@ static void __die(const char *str, int err, struct thread_info *thread, struct p
|
||||
dump_backtrace(regs, tsk);
|
||||
dump_instr(KERN_EMERG, regs);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
DEFINE_SPINLOCK(die_lock);
|
||||
@@ -250,16 +261,21 @@ DEFINE_SPINLOCK(die_lock);
|
||||
/*
|
||||
* This function is protected against re-entrancy.
|
||||
*/
|
||||
NORET_TYPE void die(const char *str, struct pt_regs *regs, int err)
|
||||
void die(const char *str, struct pt_regs *regs, int err)
|
||||
{
|
||||
struct thread_info *thread = current_thread_info();
|
||||
int ret;
|
||||
|
||||
oops_enter();
|
||||
|
||||
spin_lock_irq(&die_lock);
|
||||
console_verbose();
|
||||
bust_spinlocks(1);
|
||||
__die(str, err, thread, regs);
|
||||
ret = __die(str, err, thread, regs);
|
||||
|
||||
if (regs && kexec_should_crash(thread->task))
|
||||
crash_kexec(regs);
|
||||
|
||||
bust_spinlocks(0);
|
||||
add_taint(TAINT_DIE);
|
||||
spin_unlock_irq(&die_lock);
|
||||
@@ -267,11 +283,10 @@ NORET_TYPE void die(const char *str, struct pt_regs *regs, int err)
|
||||
|
||||
if (in_interrupt())
|
||||
panic("Fatal exception in interrupt");
|
||||
|
||||
if (panic_on_oops)
|
||||
panic("Fatal exception");
|
||||
|
||||
do_exit(SIGSEGV);
|
||||
if (ret != NOTIFY_STOP)
|
||||
do_exit(SIGSEGV);
|
||||
}
|
||||
|
||||
void arm_notify_die(const char *str, struct pt_regs *regs,
|
||||
|
@@ -43,10 +43,6 @@ SECTIONS
|
||||
|
||||
INIT_SETUP(16)
|
||||
|
||||
__early_begin = .;
|
||||
*(.early_param.init)
|
||||
__early_end = .;
|
||||
|
||||
INIT_CALLS
|
||||
CON_INITCALL
|
||||
SECURITY_INITCALL
|
||||
|
Reference in New Issue
Block a user