Commit c6799ade authored by Linus Torvalds's avatar Linus Torvalds

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: (82 commits)
  [ARM] Add comments marking in-use ptrace numbers
  [ARM] Move syscall saving out of the way of utrace
  [ARM] 4360/1: S3C24XX: regs-udc.h remove unused macro
  [ARM] 4358/1: S3C24XX: mach-qt2410.c: remove linux/mmc/protocol.h header
  [ARM] mm 10: allow memory type to be specified with ioremap
  [ARM] mm 9: add additional device memory types
  [ARM] mm 8: define mem_types table L1 bit 4 to be for ARMv6
  [ARM] iop: add missing parens in macro
  [ARM] mm 7: remove duplicated __ioremap() prototypes
  ARM: OMAP: fix OMAP1 mpuio suspend/resume oops
  ARM: OMAP: MPUIO wake updates
  ARM: OMAP: speed up gpio irq handling
  ARM: OMAP: plat-omap changes for 2430 SDP
  ARM: OMAP: gpio object shrinkage, cleanup
  ARM: OMAP: /sys/kernel/debug/omap_gpio
  ARM: OMAP: Implement workaround for GPIO wakeup bug in OMAP2420 silicon
  ARM: OMAP: Enable 24xx GPIO autoidling
  [ARM] 4318/2: DSM-G600 Board Support
  [ARM] 4227/1: minor head.S fixups
  [ARM] 4328/1: Move i.MX UART regs to driver
  ...
parents b7405e16 5cd47155
......@@ -62,7 +62,7 @@ static struct resource pxa_spi_nssp_resources[] = {
static struct pxa2xx_spi_master pxa_nssp_master_info = {
.ssp_type = PXA25x_NSSP, /* Type of SSP */
.clock_enable = CKEN9_NSSP, /* NSSP Peripheral clock */
.clock_enable = CKEN_NSSP, /* NSSP Peripheral clock */
.num_chipselect = 1, /* Matches the number of chips attached to NSSP */
.enable_dma = 1, /* Enables NSSP DMA */
};
......
......@@ -29,6 +29,10 @@ config GENERIC_TIME
bool
default n
config GENERIC_CLOCKEVENTS
bool
default n
config MMU
bool
default y
......@@ -67,6 +71,14 @@ config GENERIC_HARDIRQS
bool
default y
config STACKTRACE_SUPPORT
bool
default y
config LOCKDEP_SUPPORT
bool
default y
config TRACE_IRQFLAGS_SUPPORT
bool
default y
......@@ -162,6 +174,8 @@ config ARCH_VERSATILE
select ARM_AMBA
select ARM_VIC
select ICST307
select GENERIC_TIME
select GENERIC_CLOCKEVENTS
help
This enables support for ARM Ltd Versatile board.
......@@ -263,6 +277,7 @@ config ARCH_IXP4XX
bool "IXP4xx-based"
depends on MMU
select GENERIC_TIME
select GENERIC_CLOCKEVENTS
help
Support for Intel's IXP4XX (XScale) family of processors.
......@@ -364,6 +379,7 @@ config ARCH_LH7A40X
config ARCH_OMAP
bool "TI OMAP"
select GENERIC_GPIO
select GENERIC_TIME
help
Support for TI's OMAP platform (OMAP1 and OMAP2).
......@@ -514,6 +530,8 @@ endmenu
menu "Kernel Features"
source "kernel/time/Kconfig"
config SMP
bool "Symmetric Multi-Processing (EXPERIMENTAL)"
depends on EXPERIMENTAL && REALVIEW_MPCORE
......@@ -573,6 +591,7 @@ config PREEMPT
config NO_IDLE_HZ
bool "Dynamic tick timer"
depends on !GENERIC_CLOCKEVENTS
help
Select this option if you want to disable continuous timer ticks
and have them programmed to occur as required. This option saves
......@@ -670,6 +689,7 @@ config LEDS_TIMER
bool "Timer LED" if (!ARCH_CDB89712 && !ARCH_OMAP) || \
MACH_OMAP_H2 || MACH_OMAP_PERSEUS2
depends on LEDS
depends on !GENERIC_CLOCKEVENTS
default y if ARCH_EBSA110
help
If you say Y here, one of the system LEDs (the green one on the
......
......@@ -61,6 +61,12 @@
cmp r7, r3
beq 99f
@ picotux 200 : 963
mov r3, #(MACH_TYPE_PICOTUX2XX & 0xff)
orr r3, r3, #(MACH_TYPE_PICOTUX2XX & 0xff00)
cmp r7, r3
beq 99f
@ Ajeco 1ARM : 1075
mov r3, #(MACH_TYPE_ONEARM & 0xff)
orr r3, r3, #(MACH_TYPE_ONEARM & 0xff00)
......
......@@ -18,7 +18,6 @@
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/delay.h>
#include <linux/ptrace.h>
#include <linux/errno.h>
#include <linux/ioport.h>
#include <linux/platform_device.h>
......
#include <linux/kernel.h>
#include <linux/pci.h>
#include <linux/ptrace.h>
#include <linux/interrupt.h>
#include <linux/mm.h>
#include <linux/init.h>
......
......@@ -117,11 +117,13 @@ CONFIG_ARCH_ADI_COYOTE=y
CONFIG_ARCH_IXDP425=y
CONFIG_MACH_IXDPG425=y
CONFIG_MACH_IXDP465=y
CONFIG_MACH_KIXRP435=y
CONFIG_ARCH_IXCDP1100=y
CONFIG_ARCH_PRPMC1100=y
CONFIG_MACH_NAS100D=y
CONFIG_ARCH_IXDP4XX=y
CONFIG_CPU_IXP46X=y
CONFIG_CPU_IXP43X=y
# CONFIG_MACH_GTWX5715 is not set
#
......
This diff is collapsed.
......@@ -7,8 +7,8 @@ AFLAGS_head.o := -DTEXT_OFFSET=$(TEXT_OFFSET)
# Object file lists.
obj-y := compat.o entry-armv.o entry-common.o irq.o \
process.o ptrace.o semaphore.o setup.o signal.o sys_arm.o \
time.o traps.o
process.o ptrace.o semaphore.o setup.o signal.o \
sys_arm.o stacktrace.o time.o traps.o
obj-$(CONFIG_ISA_DMA_API) += dma.o
obj-$(CONFIG_ARCH_ACORN) += ecard.o
......
......@@ -40,6 +40,7 @@
#include <linux/device.h>
#include <linux/init.h>
#include <linux/mutex.h>
#include <linux/kthread.h>
#include <asm/dma.h>
#include <asm/ecard.h>
......@@ -50,6 +51,8 @@
#include <asm/mach/irq.h>
#include <asm/tlbflush.h>
#include "ecard.h"
#ifndef CONFIG_ARCH_RPC
#define HAVE_EXPMASK
#endif
......@@ -123,7 +126,7 @@ static void ecard_task_reset(struct ecard_request *req)
res = ec->slot_no == 8
? &ec->resource[ECARD_RES_MEMC]
: ec->type == ECARD_EASI
: ec->easi
? &ec->resource[ECARD_RES_EASI]
: &ec->resource[ECARD_RES_IOCSYNC];
......@@ -178,7 +181,7 @@ static void ecard_task_readbytes(struct ecard_request *req)
index += 1;
}
} else {
unsigned long base = (ec->type == ECARD_EASI
unsigned long base = (ec->easi
? &ec->resource[ECARD_RES_EASI]
: &ec->resource[ECARD_RES_IOCSYNC])->start;
void __iomem *pbase = (void __iomem *)base;
......@@ -263,8 +266,6 @@ static int ecard_init_mm(void)
static int
ecard_task(void * unused)
{
daemonize("kecardd");
/*
* Allocate a mm. We're not a lazy-TLB kernel task since we need
* to set page table entries where the user space would be. Note
......@@ -727,7 +728,7 @@ static int ecard_prints(char *buffer, ecard_t *ec)
char *start = buffer;
buffer += sprintf(buffer, " %d: %s ", ec->slot_no,
ec->type == ECARD_EASI ? "EASI" : " ");
ec->easi ? "EASI" : " ");
if (ec->cid.id == 0) {
struct in_chunk_dir incd;
......@@ -814,7 +815,7 @@ static struct expansion_card *__init ecard_alloc_card(int type, int slot)
}
ec->slot_no = slot;
ec->type = type;
ec->easi = type == ECARD_EASI;
ec->irq = NO_IRQ;
ec->fiq = NO_IRQ;
ec->dma = NO_DMA;
......@@ -825,6 +826,7 @@ static struct expansion_card *__init ecard_alloc_card(int type, int slot)
ec->dev.bus = &ecard_bus_type;
ec->dev.dma_mask = &ec->dma_mask;
ec->dma_mask = (u64)0xffffffff;
ec->dev.coherent_dma_mask = ec->dma_mask;
if (slot < 4) {
ec_set_resource(ec, ECARD_RES_MEMC,
......@@ -907,7 +909,7 @@ static ssize_t ecard_show_device(struct device *dev, struct device_attribute *at
static ssize_t ecard_show_type(struct device *dev, struct device_attribute *attr, char *buf)
{
struct expansion_card *ec = ECARD_DEV(dev);
return sprintf(buf, "%s\n", ec->type == ECARD_EASI ? "EASI" : "IOC");
return sprintf(buf, "%s\n", ec->easi ? "EASI" : "IOC");
}
static struct device_attribute ecard_dev_attrs[] = {
......@@ -1058,13 +1060,14 @@ ecard_probe(int slot, card_type_t type)
*/
static int __init ecard_init(void)
{
int slot, irqhw, ret;
ret = kernel_thread(ecard_task, NULL, CLONE_KERNEL);
if (ret < 0) {
printk(KERN_ERR "Ecard: unable to create kernel thread: %d\n",
ret);
return ret;
struct task_struct *task;
int slot, irqhw;
task = kthread_run(ecard_task, NULL, "kecardd");
if (IS_ERR(task)) {
printk(KERN_ERR "Ecard: unable to create kernel thread: %ld\n",
PTR_ERR(task));
return PTR_ERR(task);
}
printk("Probing expansion cards\n");
......
/*
* ecard.h
*
* Copyright 2007 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.
*/
/* Definitions internal to ecard.c - for it's use only!!
*
* External expansion card header as read from the card
*/
struct ex_ecid {
unsigned char r_irq:1;
unsigned char r_zero:1;
unsigned char r_fiq:1;
unsigned char r_id:4;
unsigned char r_a:1;
unsigned char r_cd:1;
unsigned char r_is:1;
unsigned char r_w:2;
unsigned char r_r1:4;
unsigned char r_r2:8;
unsigned char r_prod[2];
unsigned char r_manu[2];
unsigned char r_country;
unsigned char r_fiqmask;
unsigned char r_fiqoff[3];
unsigned char r_irqmask;
unsigned char r_irqoff[3];
};
/*
* Chunk directory entry as read from the card
*/
struct ex_chunk_dir {
unsigned char r_id;
unsigned char r_len[3];
unsigned long r_start;
union {
char string[256];
char data[1];
} d;
#define c_id(x) ((x)->r_id)
#define c_len(x) ((x)->r_len[0]|((x)->r_len[1]<<8)|((x)->r_len[2]<<16))
#define c_start(x) ((x)->r_start)
};
......@@ -257,7 +257,9 @@ __create_page_tables:
* Map some ram to cover our .data and .bss areas.
*/
orr r3, r7, #(KERNEL_RAM_PADDR & 0xff000000)
.if (KERNEL_RAM_PADDR & 0x00f00000)
orr r3, r3, #(KERNEL_RAM_PADDR & 0x00f00000)
.endif
add r0, r4, #(KERNEL_RAM_VADDR & 0xff000000) >> 18
str r3, [r0, #(KERNEL_RAM_VADDR & 0x00f00000) >> 18]!
ldr r6, =(_end - 1)
......@@ -274,7 +276,9 @@ __create_page_tables:
*/
add r0, r4, #PAGE_OFFSET >> 18
orr r6, r7, #(PHYS_OFFSET & 0xff000000)
orr r6, r6, #(PHYS_OFFSET & 0x00e00000)
.if (PHYS_OFFSET & 0x00f00000)
orr r6, r6, #(PHYS_OFFSET & 0x00f00000)
.endif
str r6, [r0]
#ifdef CONFIG_DEBUG_LL
......
......@@ -27,7 +27,6 @@
#include <linux/ioport.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/ptrace.h>
#include <linux/slab.h>
#include <linux/random.h>
#include <linux/smp.h>
......@@ -109,7 +108,7 @@ static struct irq_desc bad_irq_desc = {
* come via this function. Instead, they should provide their
* own 'handler'
*/
asmlinkage void asm_do_IRQ(unsigned int irq, struct pt_regs *regs)
asmlinkage void __exception asm_do_IRQ(unsigned int irq, struct pt_regs *regs)
{
struct pt_regs *old_regs = set_irq_regs(regs);
struct irq_desc *desc = irq_desc + irq;
......
......@@ -16,7 +16,6 @@
#include <linux/mm.h>
#include <linux/stddef.h>
#include <linux/unistd.h>
#include <linux/ptrace.h>
#include <linux/slab.h>
#include <linux/user.h>
#include <linux/a.out.h>
......@@ -28,6 +27,7 @@
#include <linux/cpu.h>
#include <linux/elfcore.h>
#include <linux/pm.h>
#include <linux/tick.h>
#include <asm/leds.h>
#include <asm/processor.h>
......@@ -160,9 +160,11 @@ void cpu_idle(void)
if (!idle)
idle = default_idle;
leds_event(led_idle_start);
tick_nohz_stop_sched_tick();
while (!need_resched())
idle();
leds_event(led_idle_end);
tick_nohz_restart_sched_tick();
preempt_enable_no_resched();
schedule();
preempt_disable();
......
......@@ -457,13 +457,10 @@ void ptrace_cancel_bpt(struct task_struct *child)
/*
* Called by kernel/ptrace.c when detaching..
*
* Make sure the single step bit is not set.
*/
void ptrace_disable(struct task_struct *child)
{
child->ptrace &= ~PT_SINGLESTEP;
ptrace_cancel_bpt(child);
single_step_disable(child);
}
/*
......@@ -712,9 +709,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
else
clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
child->exit_code = data;
/* make sure single-step breakpoint is gone. */
child->ptrace &= ~PT_SINGLESTEP;
ptrace_cancel_bpt(child);
single_step_disable(child);
wake_up_process(child);
ret = 0;
break;
......@@ -725,9 +720,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
* exit.
*/
case PTRACE_KILL:
/* make sure single-step breakpoint is gone. */
child->ptrace &= ~PT_SINGLESTEP;
ptrace_cancel_bpt(child);
single_step_disable(child);
if (child->exit_state != EXIT_ZOMBIE) {
child->exit_code = SIGKILL;
wake_up_process(child);
......@@ -742,7 +735,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
ret = -EIO;
if (!valid_signal(data))
break;
child->ptrace |= PT_SINGLESTEP;
single_step_enable(child);
clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
child->exit_code = data;
/* give it a chance to run. */
......@@ -786,8 +779,8 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
break;
case PTRACE_SET_SYSCALL:
task_thread_info(child)->syscall = data;
ret = 0;
child->ptrace_message = data;
break;
#ifdef CONFIG_CRUNCH
......@@ -824,7 +817,7 @@ asmlinkage int syscall_trace(int why, struct pt_regs *regs, int scno)
ip = regs->ARM_ip;
regs->ARM_ip = why;
current->ptrace_message = scno;
current_thread_info()->syscall = scno;
/* the 0x80 provides a way for the tracing parent to distinguish
between a syscall stop and SIGTRAP delivery */
......@@ -841,5 +834,5 @@ asmlinkage int syscall_trace(int why, struct pt_regs *regs, int scno)
}
regs->ARM_ip = ip;
return current->ptrace_message;
return current_thread_info()->syscall;
}
......@@ -7,6 +7,45 @@
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/ptrace.h>
extern void ptrace_cancel_bpt(struct task_struct *);
extern void ptrace_set_bpt(struct task_struct *);
extern void ptrace_break(struct task_struct *, struct pt_regs *);
/*
* make sure single-step breakpoint is gone.
*/
static inline void single_step_disable(struct task_struct *task)
{
task->ptrace &= ~PT_SINGLESTEP;
ptrace_cancel_bpt(task);
}
static inline void single_step_enable(struct task_struct *task)
{
task->ptrace |= PT_SINGLESTEP;
}
/*
* Send SIGTRAP if we're single-stepping
*/
static inline void single_step_trap(struct task_struct *task)
{
if (task->ptrace & PT_SINGLESTEP) {
ptrace_cancel_bpt(task);
send_sig(SIGTRAP, task, 1);
}
}
static inline void single_step_clear(struct task_struct *task)
{
if (task->ptrace & PT_SINGLESTEP)
ptrace_cancel_bpt(task);
}
static inline void single_step_set(struct task_struct *task)
{
if (task->ptrace & PT_SINGLESTEP)
ptrace_set_bpt(task);
}
......@@ -9,7 +9,6 @@
*/
#include <linux/errno.h>
#include <linux/signal.h>
#include <linux/ptrace.h>
#include <linux/personality.h>
#include <linux/freezer.h>
......@@ -285,11 +284,7 @@ asmlinkage int sys_sigreturn(struct pt_regs *regs)
if (restore_sigframe(regs, frame))
goto badframe;
/* Send SIGTRAP if we're single-stepping */
if (current->ptrace & PT_SINGLESTEP) {
ptrace_cancel_bpt(current);
send_sig(SIGTRAP, current, 1);
}
single_step_trap(current);
return regs->ARM_r0;
......@@ -324,11 +319,7 @@ asmlinkage int sys_rt_sigreturn(struct pt_regs *regs)
if (do_sigaltstack(&frame->sig.uc.uc_stack, NULL, regs->ARM_sp) == -EFAULT)
goto badframe;
/* Send SIGTRAP if we're single-stepping */
if (current->ptrace & PT_SINGLESTEP) {
ptrace_cancel_bpt(current);
send_sig(SIGTRAP, current, 1);
}
single_step_trap(current);
return regs->ARM_r0;
......@@ -644,14 +635,12 @@ static int do_signal(sigset_t *oldset, struct pt_regs *regs, int syscall)
if (try_to_freeze())
goto no_signal;
if (current->ptrace & PT_SINGLESTEP)
ptrace_cancel_bpt(current);
single_step_clear(current);
signr = get_signal_to_deliver(&info, &ka, regs, NULL);
if (signr > 0) {
handle_signal(signr, &ka, &info, oldset, regs, syscall);
if (current->ptrace & PT_SINGLESTEP)
ptrace_set_bpt(current);
single_step_set(current);
return 1;
}
......@@ -705,8 +694,7 @@ static int do_signal(sigset_t *oldset, struct pt_regs *regs, int syscall)
restart_syscall(regs);
}
}
if (current->ptrace & PT_SINGLESTEP)
ptrace_set_bpt(current);
single_step_set(current);
return 0;
}
......
#include <linux/sched.h>
#include <linux/stacktrace.h>
#include "stacktrace.h"
int walk_stackframe(unsigned long fp, unsigned long low, unsigned long high,
int (*fn)(struct stackframe *, void *), void *data)
{
struct stackframe *frame;
do {
/*
* Check current frame pointer is within bounds
*/
if ((fp - 12) < low || fp + 4 >= high)
break;
frame = (struct stackframe *)(fp - 12);
if (fn(frame, data))
break;
/*
* Update the low bound - the next frame must always
* be at a higher address than the current frame.
*/
low = fp + 4;
fp = frame->fp;
} while (fp);
return 0;
}
#ifdef CONFIG_STACKTRACE
struct stack_trace_data {
struct stack_trace *trace;
unsigned int skip;
};
static int save_trace(struct stackframe *frame, void *d)
{
struct stack_trace_data *data = d;
struct stack_trace *trace = data->trace;
if (data->skip) {
data->skip--;
return 0;
}
trace->entries[trace->nr_entries++] = frame->lr;
return trace->nr_entries >= trace->max_entries;
}
void save_stack_trace(struct stack_trace *trace, struct task_struct *task)
{
struct stack_trace_data data;
unsigned long fp, base;
data.trace = trace;
data.skip = trace->skip;
if (task) {
base = (unsigned long)task_stack_page(task);
fp = 0; /* FIXME */
} else {
base = (unsigned long)task_stack_page(current);
asm("mov %0, fp" : "=r" (fp));
}
walk_stackframe(fp, base, base + THREAD_SIZE, save_trace, &data);
}
#endif
struct stackframe {
unsigned long fp;
unsigned long sp;
unsigned long lr;
unsigned long pc;
};
int walk_stackframe(unsigned long fp, unsigned long low, unsigned long high,
int (*fn)(struct stackframe *, void *), void *data);
......@@ -327,6 +327,7 @@ void restore_time_delta(struct timespec *delta, struct timespec *rtc)
}
EXPORT_SYMBOL(restore_time_delta);
#ifndef CONFIG_GENERIC_CLOCKEVENTS
/*
* Kernel system timer support.
*/
......@@ -340,8 +341,9 @@ void timer_tick(void)
update_process_times(user_mode(get_irq_regs()));
#endif
}
#endif
#ifdef CONFIG_PM
#if defined(CONFIG_PM) && !defined(CONFIG_GENERIC_CLOCKEVENTS)
static int timer_suspend(struct sys_device *dev, pm_message_t state)
{
struct sys_timer *timer = container_of(dev, struct sys_timer, dev);
......
......@@ -16,7 +16,6 @@
#include <linux/signal.h>
#include <linux/spinlock.h>
#include <linux/personality.h>
#include <linux/ptrace.h>
#include <linux/kallsyms.h>
#include <linux/delay.h>
#include <linux/init.h>
......@@ -45,7 +44,18 @@ static int __init user_debug_setup(char *str)
__setup("user_debug=", user_debug_setup);
#endif
void dump_backtrace_entry(unsigned long where, unsigned long from)
static void dump_mem(const char *str, unsigned long bottom, unsigned long top);
static inline int in_exception_text(unsigned long ptr)
{
extern char __exception_text_start[];
extern char __exception_text_end[];
return ptr >= (unsigned long)&__exception_text_start &&
ptr < (unsigned long)&__exception_text_end;
}
void dump_backtrace_entry(unsigned long where, unsigned long from, unsigned long frame)
{
#ifdef CONFIG_KALLSYMS
printk("[<%08lx>] ", where);
......@@ -55,6 +65,9 @@ void dump_backtrace_entry(unsigned long where, unsigned long from)
#else
printk("Function entered at [<%08lx>] from [<%08lx>]\n", where, from);
#endif
if (in_exception_text(where))
dump_mem("Exception stack", frame + 4, frame + 4 + sizeof(struct pt_regs));
}
/*
......@@ -266,13 +279,14 @@ void unregister_undef_hook(struct undef_hook *hook)
spin_unlock_irqrestore(&undef_lock, flags);
}
asmlinkage void do_undefinstr(struct pt_regs *regs)
asmlinkage void __exception do_undefinstr(struct pt_regs *regs)
{
unsigned int correction = thumb_mode(regs) ? 2 : 4;
unsigned int instr;
struct undef_hook *hook;
siginfo_t info;
void __user *pc;
unsigned long flags;
/*
* According to the ARM ARM, PC is 2 or 4 bytes ahead,
......@@ -291,7 +305,7 @@ asmlinkage void do_undefinstr(struct pt_regs *regs)
get_user(instr, (u32 __user *)pc);
}
spin_lock_irq(&undef_lock);
spin_lock_irqsave(&undef_lock, flags);
list_for_each_entry(hook, &undef_hook, node) {
if ((instr & hook->instr_mask) == hook->instr_val &&
(regs->ARM_cpsr & hook->cpsr_mask) == hook->cpsr_val) {
......@@ -301,7 +315,7 @@ asmlinkage void do_undefinstr(struct pt_regs *regs)
}
}
}
spin_unlock_irq(&undef_lock);
spin_unlock_irqrestore(&undef_lock, flags);
#ifdef CONFIG_DEBUG_USER
if (user_debug & UDBG_UNDEFINED) {
......
......@@ -83,6 +83,9 @@ SECTIONS
.text : { /* Real text segment */
_text = .; /* Text and read-only data */
__exception_text_start = .;
*(.exception.text)
__exception_text_end = .;
*(.text)
SCHED_TEXT
LOCK_TEXT
......
......@@ -17,8 +17,8 @@
@ fp is 0 or stack frame
#define frame r4
#define next r5
#define save r6
#define sv_fp r5
#define sv_pc r6
#define mask r7
#define offset r8
......@@ -31,108 +31,106 @@ ENTRY(c_backtrace)
#if !defined(CONFIG_FRAME_POINTER) || !defined(CONFIG_PRINTK)
mov pc, lr
#else
stmfd sp!, {r4 - r8, lr} @ Save an extra register so we have a location...
tst r1, #0x10 @ 26 or 32-bit?
moveq mask, #0xfc000003
movne mask, #0
tst mask, r0
movne r0, #0
movs frame, r0
1: moveq r0, #-2
ldmeqfd sp!, {r4 - r8, pc}
2: stmfd sp!, {pc} @ calculate offset of PC in STMIA instruction
ldr r0, [sp], #4
adr r1, 2b - 4
movs frame, r0 @ if frame pointer is zero
beq no_frame @ we have no stack frames
tst r1, #0x10 @ 26 or 32-bit mode?
moveq mask, #0xfc000003 @ mask for 26-bit
movne mask, #0 @ mask for 32-bit
1: stmfd sp!, {pc} @ calculate offset of PC stored
ldr r0, [sp], #4 @ by stmfd for this CPU
adr r1, 1b
sub offset, r0, r1
3: tst frame, mask @ Check for address exceptions...
bne 1b
/*
* Stack frame layout:
* optionally saved caller registers (r4 - r10)
* saved fp
* saved sp
* saved lr
* frame => saved pc
* optionally saved arguments (r0 - r3)
* saved sp => <next word>
*
* Functions start with the following code sequence:
* mov ip, sp
* stmfd sp!, {r0 - r3} (optional)
* corrected pc => stmfd sp!, {..., fp, ip, lr, pc}
*/
for_each_frame: tst frame, mask @ Check for address exceptions
bne no_frame
1001: ldr sv_pc, [frame, #0] @ get saved pc
1002: ldr sv_fp, [frame, #-12] @ get saved fp
1001: ldr next, [frame, #-12] @ get fp
1002: ldr r2, [frame, #-4] @ get lr
1003: ldr r3, [frame, #0] @ get pc
sub save, r3, offset @ Correct PC for prefetching
bic save, save, mask
1004: ldr r1, [save, #0] @ get instruction at function
mov r1, r1, lsr #10
ldr r3, .Ldsi+4
teq r1, r3
subeq save, save, #4
mov r0, save
bic r1, r2, mask
sub sv_pc, sv_pc, offset @ Correct PC for prefetching
bic sv_pc, sv_pc, mask @ mask PC/LR for the mode
1003: ldr r2, [sv_pc, #-4] @ if stmfd sp!, {args} exists,
ldr r3, .Ldsi+4 @ adjust saved 'pc' back one
teq r3, r2, lsr #10 @ instruction
subne r0, sv_pc, #4 @ allow for mov
subeq r0, sv_pc, #8 @ allow for mov + stmia
ldr r1, [frame, #-4] @ get saved lr
mov r2, frame
bic r1, r1, mask @ mask PC/LR for the mode
bl dump_backtrace_entry
ldr r0, [frame, #-8] @ get sp
sub r0, r0, #4
1005: ldr r1, [save, #4] @ get instruction at function+4
mov r3, r1, lsr #10
ldr r2, .Ldsi+4
teq r3, r2 @ Check for stmia sp!, {args}
addeq save, save, #4 @ next instruction
bleq .Ldumpstm
sub r0, frame, #16
1006: ldr r1, [save, #4] @ Get 'stmia sp!, {rlist, fp, ip, lr, pc}' instruction
mov r3, r1, lsr #10
ldr r2, .Ldsi
teq r3, r2
bleq .Ldumpstm
/*
* A zero next framepointer means we're done.
*/
teq next, #0
ldmeqfd sp!, {r4 - r8, pc}
/*
* The next framepointer must be above the
* current framepointer.
*/
cmp next, frame
mov frame, next
bhi 3b
b 1007f
ldr r1, [sv_pc, #-4] @ if stmfd sp!, {args} exists,
ldr r3, .Ldsi+4
teq r3, r1, lsr #10
ldreq r0, [frame, #-8] @ get sp
subeq r0, r0, #4 @ point at the last arg
bleq .Ldumpstm @ dump saved registers
/*
* Fixup for LDMDB. Note that this must not be in the fixup section.
*/
1007: ldr r0, =.Lbad
1004: ldr r1, [sv_pc, #0] @ if stmfd sp!, {..., fp, ip, lr, pc}
ldr r3, .Ldsi @ instruction exists,
teq r3, r1, lsr #10
subeq r0, frame, #16
bleq .Ldumpstm @ dump saved registers
teq sv_fp, #0 @ zero saved fp means
beq no_frame @ no further frames
cmp sv_fp, frame @ next frame must be
mov frame, sv_fp @ above the current frame
bhi for_each_frame
1006: adr r0, .Lbad
mov r1, frame
bl printk
ldmfd sp!, {r4 - r8, pc}
.ltorg
no_frame: ldmfd sp!, {r4 - r8, pc}
.section __ex_table,"a"
.align 3
.long 1001b, 1007b
.long 1002b, 1007b
.long 1003b, 1007b
.long 1004b, 1007b
.long 1005b, 1007b
.long 1006b, 1007b
.long 1001b, 1006b
.long 1002b, 1006b
.long 1003b, 1006b
.long 1004b, 1006b
.previous
#define instr r4
#define reg r5
#define stack r6
.Ldumpstm: stmfd sp!, {instr, reg, stack, r7, r8, lr}
.Ldumpstm: stmfd sp!, {instr, reg, stack, r7, lr}
mov stack, r0
mov instr, r1
mov reg, #9
mov reg, #10
mov r7, #0
1: mov r3, #1
tst instr, r3, lsl reg
beq 2f
add r7, r7, #1
teq r7, #4
moveq r7, #0
moveq r3, #'\n'
movne r3, #' '
ldr r2, [stack], #-4
mov r1, reg
teq r7, #6
moveq r7, #1
moveq r1, #'\n'
movne r1, #' '
ldr r3, [stack], #-4
mov r2, reg
adr r0, .Lfp
bl printk
2: subs reg, reg, #1
......@@ -140,14 +138,13 @@ ENTRY(c_backtrace)
teq r7, #0
adrne r0, .Lcr
blne printk
mov r0, stack
ldmfd sp!, {instr, reg, stack, r7, r8, pc}
ldmfd sp!, {instr, reg, stack, r7, pc}
.Lfp: .asciz " r%d = %08X%c"
.Lfp: .asciz "%cr%d:%08x"
.Lcr: .asciz "\n"
.Lbad: .asciz "Backtrace aborted due to bad frame pointer <%p>\n"
.align
.Ldsi: .word 0x00e92dd8 >> 2
.word 0x00e92d00 >> 2
.Ldsi: .word 0xe92dd800 >> 10 @ stmfd sp!, {... fp, ip, lr, pc}
.word 0xe92d0000 >> 10 @ stmfd sp!, {}
#endif
......@@ -26,8 +26,6 @@
* Note that ADDR_LIMIT is either 0 or 0xc0000000.
* Note also that it is intended that __get_user_bad is not global.
*/
#include <asm/asm-offsets.h>
#include <asm/thread_info.h>
#include <asm/errno.h>
.global __get_user_1
......
......@@ -26,8 +26,6 @@
* Note that ADDR_LIMIT is either 0 or 0xc0000000
* Note also that it is intended that __put_user_bad is not global.
*/
#include <asm/asm-offsets.h>
#include <asm/thread_info.h>
#include <asm/errno.h>
.global __put_user_1
......
......@@ -81,6 +81,13 @@ config MACH_KB9200
Select this if you are using KwikByte's KB920x board.
<http://kwikbyte.com/KB9202_description_new.htm>
config MACH_PICOTUX2XX
bool "picotux 200"
depends on ARCH_AT91RM9200
help
Select this if you are using a picotux 200.
<http://www.picotux.com/>
config MACH_KAFA
bool "Sperry-Sun KAFA board"
depends on ARCH_AT91RM9200
......
......@@ -25,6 +25,7 @@ obj-$(CONFIG_MACH_CARMEVA) += board-carmeva.o
obj-$(CONFIG_MACH_KB9200) += board-kb9202.o
obj-$(CONFIG_MACH_ATEB9200) += board-eb9200.o
obj-$(CONFIG_MACH_KAFA) += board-kafa.o
obj-$(CONFIG_MACH_PICOTUX2XX) += board-picotux200.o
# AT91SAM9260 board-specific support
obj-$(CONFIG_MACH_AT91SAM9260EK) += board-sam9260ek.o
......
......@@ -117,6 +117,21 @@ static struct clk pioD_clk = {
.pmc_mask = 1 << AT91RM9200_ID_PIOD,
.type = CLK_TYPE_PERIPHERAL,
};
static struct clk ssc0_clk = {
.name = "ssc0_clk",
.pmc_mask = 1 << AT91RM9200_ID_SSC0,
.type = CLK_TYPE_PERIPHERAL,
};
static struct clk ssc1_clk = {
.name = "ssc1_clk",
.pmc_mask = 1 << AT91RM9200_ID_SSC1,
.type = CLK_TYPE_PERIPHERAL,
};
static struct clk ssc2_clk = {
.name = "ssc2_clk",
.pmc_mask = 1 << AT91RM9200_ID_SSC2,
.type = CLK_TYPE_PERIPHERAL,
};
static struct clk tc0_clk = {
.name = "tc0_clk",
.pmc_mask = 1 << AT91RM9200_ID_TC0,
......@@ -161,7 +176,9 @@ static struct clk *periph_clocks[] __initdata = {
&udc_clk,
&twi_clk,
&spi_clk,
// ssc 0 .. ssc2
&ssc0_clk,
&ssc1_clk,
&ssc2_clk,
&tc0_clk,
&tc1_clk,
&tc2_clk,
......
......@@ -119,6 +119,11 @@ static struct clk spi1_clk = {
.pmc_mask = 1 << AT91SAM9260_ID_SPI1,
.type = CLK_TYPE_PERIPHERAL,
};
static struct clk ssc_clk = {
.name = "ssc_clk",
.pmc_mask = 1 << AT91SAM9260_ID_SSC,
.type = CLK_TYPE_PERIPHERAL,
};
static struct clk tc0_clk = {
.name = "tc0_clk",
.pmc_mask = 1 << AT91SAM9260_ID_TC0,
......@@ -193,7 +198,7 @@ static struct clk *periph_clocks[] __initdata = {
&twi_clk,
&spi0_clk,
&spi1_clk,
// ssc
&ssc_clk,
&tc0_clk,
&tc1_clk,
&tc2_clk,
......
......@@ -97,6 +97,21 @@ static struct clk spi1_clk = {
.pmc_mask = 1 << AT91SAM9261_ID_SPI1,
.type = CLK_TYPE_PERIPHERAL,
};
static struct clk ssc0_clk = {
.name = "ssc0_clk",
.pmc_mask = 1 << AT91SAM9261_ID_SSC0,
.type = CLK_TYPE_PERIPHERAL,
};
static struct clk ssc1_clk = {
.name = "ssc1_clk",
.pmc_mask = 1 << AT91SAM9261_ID_SSC1,
.type = CLK_TYPE_PERIPHERAL,
};
static struct clk ssc2_clk = {
.name = "ssc2_clk",
.pmc_mask = 1 << AT91SAM9261_ID_SSC2,
.type = CLK_TYPE_PERIPHERAL,
};
static struct clk tc0_clk = {
.name = "tc0_clk",
.pmc_mask = 1 << AT91SAM9261_ID_TC0,
......@@ -135,7 +150,9 @@ static struct clk *periph_clocks[] __initdata = {
&twi_clk,
&spi0_clk,
&spi1_clk,
// ssc 0 .. ssc2
&ssc0_clk,
&ssc1_clk,
&ssc2_clk,
&tc0_clk,
&tc1_clk,
&tc2_clk,
......
......@@ -430,9 +430,9 @@ void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices)
* LCD Controller
* -------------------------------------------------------------------- */
#if defined(CONFIG_FB_AT91) || defined(CONFIG_FB_AT91_MODULE)
#if defined(CONFIG_FB_ATMEL) || defined(CONFIG_FB_ATMEL_MODULE)
static u64 lcdc_dmamask = 0xffffffffUL;
static struct at91fb_info lcdc_data;
static struct atmel_lcdfb_info lcdc_data;
static struct resource lcdc_resources[] = {
[0] = {
......@@ -455,7 +455,7 @@ static struct resource lcdc_resources[] = {
};
static struct platform_device at91_lcdc_device = {
.name = "at91-fb",
.name = "atmel_lcdfb",
.id = 0,
.dev = {
.dma_mask = &lcdc_dmamask,
......@@ -466,7 +466,7 @@ static struct platform_device at91_lcdc_device = {
.num_resources = ARRAY_SIZE(lcdc_resources),
};
void __init at91_add_device_lcdc(struct at91fb_info *data)
void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data)
{
if (!data) {
return;
......@@ -499,7 +499,7 @@ void __init at91_add_device_lcdc(struct at91fb_info *data)
platform_device_register(&at91_lcdc_device);
}
#else
void __init at91_add_device_lcdc(struct at91fb_info *data) {}
void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data) {}
#endif
......
......@@ -87,6 +87,11 @@ static struct clk mmc1_clk = {
.pmc_mask = 1 << AT91SAM9263_ID_MCI1,
.type = CLK_TYPE_PERIPHERAL,
};
static struct clk can_clk = {
.name = "can_clk",
.pmc_mask = 1 << AT91SAM9263_ID_CAN,
.type = CLK_TYPE_PERIPHERAL,
};
static struct clk twi_clk = {
.name = "twi_clk",
.pmc_mask = 1 << AT91SAM9263_ID_TWI,
......@@ -102,16 +107,46 @@ static struct clk spi1_clk = {
.pmc_mask = 1 << AT91SAM9263_ID_SPI1,
.type = CLK_TYPE_PERIPHERAL,
};
static struct clk ssc0_clk = {
.name = "ssc0_clk",
.pmc_mask = 1 << AT91SAM9263_ID_SSC0,
.type = CLK_TYPE_PERIPHERAL,
};
static struct clk ssc1_clk = {
.name = "ssc1_clk",
.pmc_mask = 1 << AT91SAM9263_ID_SSC1,
.type = CLK_TYPE_PERIPHERAL,
};
static struct clk ac97_clk = {
.name = "ac97_clk",
.pmc_mask = 1 << AT91SAM9263_ID_AC97C,
.type = CLK_TYPE_PERIPHERAL,
};
static struct clk tcb_clk = {
.name = "tcb_clk",
.pmc_mask = 1 << AT91SAM9263_ID_TCB,
.type = CLK_TYPE_PERIPHERAL,
};
static struct clk pwmc_clk = {
.name = "pwmc_clk",
.pmc_mask = 1 << AT91SAM9263_ID_PWMC,
.type = CLK_TYPE_PERIPHERAL,
};
static struct clk macb_clk = {
.name = "macb_clk",
.pmc_mask = 1 << AT91SAM9263_ID_EMAC,
.type = CLK_TYPE_PERIPHERAL,
};
static struct clk dma_clk = {
.name = "dma_clk",
.pmc_mask = 1 << AT91SAM9263_ID_DMA,
.type = CLK_TYPE_PERIPHERAL,
};
static struct clk twodge_clk = {
.name = "2dge_clk",
.pmc_mask = 1 << AT91SAM9263_ID_2DGE,
.type = CLK_TYPE_PERIPHERAL,
};
static struct clk udc_clk = {
.name = "udc_clk",
.pmc_mask = 1 << AT91SAM9263_ID_UDP,
......@@ -142,20 +177,21 @@ static struct clk *periph_clocks[] __initdata = {
&usart2_clk,
&mmc0_clk,
&mmc1_clk,
// can
&can_clk,
&twi_clk,
&spi0_clk,
&spi1_clk,
// ssc0 .. ssc1
// ac97
&ssc0_clk,
&ssc1_clk,
&ac97_clk,
&tcb_clk,
// pwmc
&pwmc_clk,
&macb_clk,
// 2dge
&twodge_clk,
&udc_clk,
&isi_clk,
&lcdc_clk,
// dma
&dma_clk,
&ohci_clk,
// irq0 .. irq1
};
......
......@@ -572,6 +572,130 @@ void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices)
#endif
/* --------------------------------------------------------------------
* AC97
* -------------------------------------------------------------------- */
#if defined(CONFIG_SND_AT91_AC97) || defined(CONFIG_SND_AT91_AC97_MODULE)
static u64 ac97_dmamask = 0xffffffffUL;
static struct atmel_ac97_data ac97_data;
static struct resource ac97_resources[] = {
[0] = {
.start = AT91SAM9263_BASE_AC97C,
.end = AT91SAM9263_BASE_AC97C + SZ_16K - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = AT91SAM9263_ID_AC97C,
.end = AT91SAM9263_ID_AC97C,
.flags = IORESOURCE_IRQ,
},
};
static struct platform_device at91sam9263_ac97_device = {
.name = "ac97c",
.id = 1,
.dev = {
.dma_mask = &ac97_dmamask,
.coherent_dma_mask = 0xffffffff,
.platform_data = &ac97_data,
},
.resource = ac97_resources,
.num_resources = ARRAY_SIZE(ac97_resources),
};
void __init at91_add_device_ac97(struct atmel_ac97_data *data)
{
if (!data)
return;
at91_set_A_periph(AT91_PIN_PB0, 0); /* AC97FS */
at91_set_A_periph(AT91_PIN_PB1, 0); /* AC97CK */
at91_set_A_periph(AT91_PIN_PB2, 0); /* AC97TX */
at91_set_A_periph(AT91_PIN_PB3, 0); /* AC97RX */
/* reset */
if (data->reset_pin)
at91_set_gpio_output(data->reset_pin, 0);
ac97_data = *ek_data;
platform_device_register(&at91sam9263_ac97_device);
}
#else
void __init at91_add_device_ac97(struct atmel_ac97_data *data) {}
#endif
/* --------------------------------------------------------------------
* LCD Controller
* -------------------------------------------------------------------- */
#if defined(CONFIG_FB_ATMEL) || defined(CONFIG_FB_ATMEL_MODULE)
static u64 lcdc_dmamask = 0xffffffffUL;
static struct atmel_lcdfb_info lcdc_data;
static struct resource lcdc_resources[] = {
[0] = {
.start = AT91SAM9263_LCDC_BASE,
.end = AT91SAM9263_LCDC_BASE + SZ_4K - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = AT91SAM9263_ID_LCDC,
.end = AT91SAM9263_ID_LCDC,
.flags = IORESOURCE_IRQ,
},
};
static struct platform_device at91_lcdc_device = {
.name = "atmel_lcdfb",
.id = 0,
.dev = {
.dma_mask = &lcdc_dmamask,
.coherent_dma_mask = 0xffffffff,
.platform_data = &lcdc_data,
},
.resource = lcdc_resources,
.num_resources = ARRAY_SIZE(lcdc_resources),
};
void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data)
{
if (!data)
return;
at91_set_A_periph(AT91_PIN_PC1, 0); /* LCDHSYNC */
at91_set_A_periph(AT91_PIN_PC2, 0); /* LCDDOTCK */
at91_set_A_periph(AT91_PIN_PC3, 0); /* LCDDEN */
at91_set_B_periph(AT91_PIN_PB9, 0); /* LCDCC */
at91_set_A_periph(AT91_PIN_PC6, 0); /* LCDD2 */
at91_set_A_periph(AT91_PIN_PC7, 0); /* LCDD3 */
at91_set_A_periph(AT91_PIN_PC8, 0); /* LCDD4 */
at91_set_A_periph(AT91_PIN_PC9, 0); /* LCDD5 */
at91_set_A_periph(AT91_PIN_PC10, 0); /* LCDD6 */
at91_set_A_periph(AT91_PIN_PC11, 0); /* LCDD7 */
at91_set_A_periph(AT91_PIN_PC14, 0); /* LCDD10 */
at91_set_A_periph(AT91_PIN_PC15, 0); /* LCDD11 */
at91_set_A_periph(AT91_PIN_PC16, 0); /* LCDD12 */
at91_set_B_periph(AT91_PIN_PC12, 0); /* LCDD13 */
at91_set_A_periph(AT91_PIN_PC18, 0); /* LCDD14 */
at91_set_A_periph(AT91_PIN_PC19, 0); /* LCDD15 */
at91_set_A_periph(AT91_PIN_PC22, 0); /* LCDD18 */
at91_set_A_periph(AT91_PIN_PC23, 0); /* LCDD19 */
at91_set_A_periph(AT91_PIN_PC24, 0); /* LCDD20 */
at91_set_B_periph(AT91_PIN_PC17, 0); /* LCDD21 */
at91_set_A_periph(AT91_PIN_PC26, 0); /* LCDD22 */
at91_set_A_periph(AT91_PIN_PC27, 0); /* LCDD23 */
lcdc_data = *data;
platform_device_register(&at91_lcdc_device);
}
#else
void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data) {}
#endif
/* --------------------------------------------------------------------
* LEDs
* -------------------------------------------------------------------- */
......
/*
* linux/arch/arm/mach-at91/board-picotux200.c
*
* Copyright (C) 2005 SAN People
* Copyright (C) 2007 Kleinhenz Elektronik GmbH
*
* 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
*/
#include <linux/types.h>
#include <linux/init.h>
#include <linux/mm.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/spi/spi.h>
#include <linux/mtd/physmap.h>
#include <asm/hardware.h>
#include <asm/setup.h>
#include <asm/mach-types.h>
#include <asm/irq.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
#include <asm/mach/irq.h>
#include <asm/arch/board.h>
#include <asm/arch/gpio.h>
#include <asm/arch/at91rm9200_mc.h>
#include "generic.h"
/*
* Serial port configuration.
* 0 .. 3 = USART0 .. USART3
* 4 = DBGU
*/
static struct at91_uart_config __initdata picotux200_uart_config = {
.console_tty = 0, /* ttyS0 */
.nr_tty = 2,
.tty_map = { 4, 1, -1, -1, -1 } /* ttyS0, ..., ttyS4 */
};
static void __init picotux200_map_io(void)
{
/* Initialize processor: 18.432 MHz crystal */
at91rm9200_initialize(18432000, AT91RM9200_BGA);
/* Setup the serial ports and console */
at91_init_serial(&picotux200_uart_config);
}
static void __init picotux200_init_irq(void)
{
at91rm9200_init_interrupts(NULL);
}
static struct at91_eth_data __initdata picotux200_eth_data = {
.phy_irq_pin = AT91_PIN_PC4,
.is_rmii = 1,
};
static struct at91_usbh_data __initdata picotux200_usbh_data = {
.ports = 1,
};
// static struct at91_udc_data __initdata picotux200_udc_data = {
// .vbus_pin = AT91_PIN_PD4,
// .pullup_pin = AT91_PIN_PD5,
// };
static struct at91_mmc_data __initdata picotux200_mmc_data = {
.det_pin = AT91_PIN_PB27,
.slot_b = 0,
.wire4 = 1,
.wp_pin = AT91_PIN_PA17,
};
// static struct spi_board_info picotux200_spi_devices[] = {
// { /* DataFlash chip */
// .modalias = "mtd_dataflash",
// .chip_select = 0,
// .max_speed_hz = 15 * 1000 * 1000,
// },
// #ifdef CONFIG_MTD_AT91_DATAFLASH_CARD
// { /* DataFlash card */
// .modalias = "mtd_dataflash",
// .chip_select = 3,
// .max_speed_hz = 15 * 1000 * 1000,
// },
// #endif
// };
#define PICOTUX200_FLASH_BASE AT91_CHIPSELECT_0
#define PICOTUX200_FLASH_SIZE 0x400000
static struct physmap_flash_data picotux200_flash_data = {
.width = 2,
};
static struct resource picotux200_flash_resource = {
.start = PICOTUX200_FLASH_BASE,
.end = PICOTUX200_FLASH_BASE + PICOTUX200_FLASH_SIZE - 1,
.flags = IORESOURCE_MEM,
};
static struct platform_device picotux200_flash = {
.name = "physmap-flash",
.id = 0,
.dev = {
.platform_data = &picotux200_flash_data,
},
.resource = &picotux200_flash_resource,
.num_resources = 1,
};
static void __init picotux200_board_init(void)
{
/* Serial */
at91_add_device_serial();
/* Ethernet */
at91_add_device_eth(&picotux200_eth_data);
/* USB Host */
at91_add_device_usbh(&picotux200_usbh_data);
/* USB Device */
// at91_add_device_udc(&picotux200_udc_data);
// at91_set_multi_drive(picotux200_udc_data.pullup_pin, 1); /* pullup_pin is connected to reset */
/* I2C */
at91_add_device_i2c();
/* SPI */
// at91_add_device_spi(picotux200_spi_devices, ARRAY_SIZE(picotux200_spi_devices));
#ifdef CONFIG_MTD_AT91_DATAFLASH_CARD
/* DataFlash card */
at91_set_gpio_output(AT91_PIN_PB22, 0);
#else
/* MMC */
at91_set_gpio_output(AT91_PIN_PB22, 1); /* this MMC card slot can optionally use SPI signaling (CS3). */
at91_add_device_mmc(0, &picotux200_mmc_data);
#endif
/* NOR Flash */
platform_device_register(&picotux200_flash);
}
MACHINE_START(PICOTUX2XX, "picotux 200")
/* Maintainer: Kleinhenz Elektronik GmbH */
.phys_io = AT91_BASE_SYS,
.io_pg_offst = (AT91_VA_BASE_SYS >> 18) & 0xfffc,
.boot_params = AT91_SDRAM_BASE + 0x100,
.timer = &at91rm9200_timer,
.map_io = picotux200_map_io,
.init_irq = picotux200_init_irq,
.init_machine = picotux200_board_init,
MACHINE_END
......@@ -104,9 +104,9 @@ static struct spi_board_info ek_spi_devices[] = {
},
#endif
#endif
#if defined(CONFIG_SND_AT73C213)
#if defined(CONFIG_SND_AT73C213) || defined(CONFIG_SND_AT73C213_MODULE)
{ /* AT73C213 DAC */
.modalias = "snd_at73c213",
.modalias = "at73c213",
.chip_select = 0,
.max_speed_hz = 10 * 1000 * 1000,
.bus_num = 1,
......@@ -118,7 +118,7 @@ static struct spi_board_info ek_spi_devices[] = {
/*
* MACB Ethernet device
*/
static struct __initdata at91_eth_data ek_macb_data = {
static struct at91_eth_data __initdata ek_macb_data = {
.phy_irq_pin = AT91_PIN_PA7,
.is_rmii = 1,
};
......@@ -140,7 +140,7 @@ static struct mtd_partition __initdata ek_nand_partition[] = {
},
};
static struct mtd_partition *nand_partitions(int size, int *num_partitions)
static struct mtd_partition * __init nand_partitions(int size, int *num_partitions)
{
*num_partitions = ARRAY_SIZE(ek_nand_partition);
return ek_nand_partition;
......@@ -188,6 +188,8 @@ static void __init ek_board_init(void)
at91_add_device_eth(&ek_macb_data);
/* MMC */
at91_add_device_mmc(0, &ek_mmc_data);
/* I2C */
at91_add_device_i2c();
}
MACHINE_START(AT91SAM9260EK, "Atmel AT91SAM9260-EK")
......
......@@ -25,6 +25,7 @@
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/spi/spi.h>
#include <linux/spi/ads7846.h>
#include <linux/dm9000.h>
#include <asm/hardware.h>
......@@ -194,6 +195,41 @@ static struct at91_nand_data __initdata ek_nand_data = {
#endif
};
/*
* ADS7846 Touchscreen
*/
#if defined(CONFIG_TOUCHSCREEN_ADS7846) || defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE)
static int ads7843_pendown_state(void)
{
return !at91_get_gpio_value(AT91_PIN_PC2); /* Touchscreen PENIRQ */
}
static struct ads7846_platform_data ads_info = {
.model = 7843,
.x_min = 150,
.x_max = 3830,
.y_min = 190,
.y_max = 3830,
.vref_delay_usecs = 100,
.x_plate_ohms = 450,
.y_plate_ohms = 250,
.pressure_max = 15000,
.debounce_max = 1,
.debounce_rep = 0,
.debounce_tol = (~0),
.get_pendown_state = ads7843_pendown_state,
};
static void __init ek_add_device_ts(void)
{
at91_set_B_periph(AT91_PIN_PC2, 1); /* External IRQ0, with pullup */
at91_set_gpio_input(AT91_PIN_PA11, 1); /* Touchscreen BUSY signal */
}
#else
static void __init ek_add_device_ts(void) {}
#endif
/*
* SPI devices
*/
......@@ -204,6 +240,16 @@ static struct spi_board_info ek_spi_devices[] = {
.max_speed_hz = 15 * 1000 * 1000,
.bus_num = 0,
},
#if defined(CONFIG_TOUCHSCREEN_ADS7846) || defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE)
{
.modalias = "ads7846",
.chip_select = 2,
.max_speed_hz = 125000 * 26, /* (max sample rate @ 3V) * (cmd + data + overhead) */
.bus_num = 0,
.platform_data = &ads_info,
.irq = AT91SAM9261_ID_IRQ0,
},
#endif
#if defined(CONFIG_MTD_AT91_DATAFLASH_CARD)
{ /* DataFlash card - jumper (J12) configurable to CS3 or CS0 */
.modalias = "mtd_dataflash",
......@@ -211,9 +257,9 @@ static struct spi_board_info ek_spi_devices[] = {
.max_speed_hz = 15 * 1000 * 1000,
.bus_num = 0,
},
#elif defined(CONFIG_SND_AT73C213)
#elif defined(CONFIG_SND_AT73C213) || defined(CONFIG_SND_AT73C213_MODULE)
{ /* AT73C213 DAC */
.modalias = "snd_at73c213",
.modalias = "at73c213",
.chip_select = 3,
.max_speed_hz = 10 * 1000 * 1000,
.bus_num = 0,
......@@ -241,6 +287,8 @@ static void __init ek_board_init(void)
#if defined(CONFIG_SPI_ATMEL) || defined(CONFIG_SPI_ATMEL_MODULE)
/* SPI */
at91_add_device_spi(ek_spi_devices, ARRAY_SIZE(ek_spi_devices));
/* Touchscreen */
ek_add_device_ts();
#else
/* MMC */
at91_add_device_mmc(0, &ek_mmc_data);
......
......@@ -25,6 +25,7 @@
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/spi/spi.h>
#include <linux/spi/ads7846.h>
#include <asm/hardware.h>
#include <asm/setup.h>
......@@ -85,6 +86,40 @@ static struct at91_udc_data __initdata ek_udc_data = {
};
/*
* ADS7846 Touchscreen
*/
#if defined(CONFIG_TOUCHSCREEN_ADS7846) || defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE)
static int ads7843_pendown_state(void)
{
return !at91_get_gpio_value(AT91_PIN_PA15); /* Touchscreen PENIRQ */
}
static struct ads7846_platform_data ads_info = {
.model = 7843,
.x_min = 150,
.x_max = 3830,
.y_min = 190,
.y_max = 3830,
.vref_delay_usecs = 100,
.x_plate_ohms = 450,
.y_plate_ohms = 250,
.pressure_max = 15000,
.debounce_max = 1,
.debounce_rep = 0,
.debounce_tol = (~0),
.get_pendown_state = ads7843_pendown_state,
};
static void __init ek_add_device_ts(void)
{
at91_set_B_periph(AT91_PIN_PA15, 1); /* External IRQ1, with pullup */
at91_set_gpio_input(AT91_PIN_PA31, 1); /* Touchscreen BUSY signal */
}
#else
static void __init ek_add_device_ts(void) {}
#endif
/*
* SPI devices.
*/
......@@ -97,6 +132,16 @@ static struct spi_board_info ek_spi_devices[] = {
.bus_num = 0,
},
#endif
#if defined(CONFIG_TOUCHSCREEN_ADS7846) || defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE)
{
.modalias = "ads7846",
.chip_select = 3,
.max_speed_hz = 125000 * 26, /* (max sample rate @ 3V) * (cmd + data + overhead) */
.bus_num = 0,
.platform_data = &ads_info,
.irq = AT91SAM9263_ID_IRQ1,
},
#endif
};
......@@ -111,6 +156,14 @@ static struct at91_mmc_data __initdata ek_mmc_data = {
};
/*
* MACB Ethernet device
*/
static struct at91_eth_data __initdata ek_macb_data = {
.is_rmii = 1,
};
/*
* NAND flash
*/
......@@ -148,6 +201,14 @@ static struct at91_nand_data __initdata ek_nand_data = {
};
/*
* AC97
*/
static struct atmel_ac97_data ek_ac97_data = {
.reset_pin = AT91_PIN_PA13,
};
static void __init ek_board_init(void)
{
/* Serial */
......@@ -157,11 +218,20 @@ static void __init ek_board_init(void)
/* USB Device */
at91_add_device_udc(&ek_udc_data);
/* SPI */
at91_set_gpio_output(AT91_PIN_PE20, 1); /* select spi0 clock */
at91_add_device_spi(ek_spi_devices, ARRAY_SIZE(ek_spi_devices));
/* Touchscreen */
ek_add_device_ts();
/* MMC */
at91_add_device_mmc(1, &ek_mmc_data);
/* Ethernet */
at91_add_device_eth(&ek_macb_data);
/* NAND */
at91_add_device_nand(&ek_nand_data);
/* I2C */
at91_add_device_i2c();
/* AC97 */
at91_add_device_ac97(&ek_ac97_data);
}
MACHINE_START(AT91SAM9263EK, "Atmel AT91SAM9263-EK")
......
......@@ -102,6 +102,26 @@ EXPORT_SYMBOL(__readb);
EXPORT_SYMBOL(__readw);
EXPORT_SYMBOL(__readl);
void readsw(void __iomem *addr, void *data, int len)
{
void __iomem *a = __isamem_convert_addr(addr);
BUG_ON((unsigned long)addr & 1);
__raw_readsw(a, data, len);
}
EXPORT_SYMBOL(readsw);
void readsl(void __iomem *addr, void *data, int len)
{
void __iomem *a = __isamem_convert_addr(addr);
BUG_ON((unsigned long)addr & 3);
__raw_readsl(a, data, len);
}
EXPORT_SYMBOL(readsl);
void __writeb(u8 val, void __iomem *addr)
{
void __iomem *a = __isamem_convert_addr(addr);
......@@ -137,6 +157,26 @@ EXPORT_SYMBOL(__writeb);
EXPORT_SYMBOL(__writew);
EXPORT_SYMBOL(__writel);
void writesw(void __iomem *addr, void *data, int len)
{
void __iomem *a = __isamem_convert_addr(addr);
BUG_ON((unsigned long)addr & 1);
__raw_writesw(a, data, len);
}
EXPORT_SYMBOL(writesw);
void writesl(void __iomem *addr, void *data, int len)
{
void __iomem *a = __isamem_convert_addr(addr);
BUG_ON((unsigned long)addr & 3);
__raw_writesl(a, data, len);
}
EXPORT_SYMBOL(writesl);
#define SUPERIO_PORT(p) \
(((p) >> 3) == (0x3f8 >> 3) || \
((p) >> 3) == (0x2f8 >> 3) || \
......
......@@ -27,6 +27,10 @@ struct clk {
u32 enable_mask;
};
static struct clk clk_uart = {
.name = "UARTCLK",
.rate = 14745600,
};
static struct clk clk_pll1 = {
.name = "pll1",
};
......@@ -50,6 +54,7 @@ static struct clk clk_usb_host = {
static struct clk *clocks[] = {
&clk_uart,
&clk_pll1,
&clk_f,
&clk_h,
......
......@@ -10,7 +10,6 @@
*/
#include <linux/kernel.h>
#include <linux/pci.h>
#include <linux/ptrace.h>
#include <linux/interrupt.h>
#include <linux/mm.h>
#include <linux/slab.h>
......
......@@ -23,7 +23,6 @@
*/
#include <linux/kernel.h>
#include <linux/pci.h>
#include <linux/ptrace.h>
#include <linux/interrupt.h>
#include <linux/init.h>
......
......@@ -22,7 +22,6 @@
*/
#include <linux/kernel.h>
#include <linux/pci.h>
#include <linux/ptrace.h>
#include <linux/slab.h>
#include <linux/ioport.h>
#include <linux/interrupt.h>
......
......@@ -7,5 +7,6 @@ obj-$(CONFIG_ARCH_IOP13XX) += setup.o
obj-$(CONFIG_ARCH_IOP13XX) += irq.o
obj-$(CONFIG_ARCH_IOP13XX) += pci.o
obj-$(CONFIG_ARCH_IOP13XX) += io.o
obj-$(CONFIG_ARCH_IOP13XX) += tpmi.o
obj-$(CONFIG_MACH_IQ81340SC) += iq81340sc.o
obj-$(CONFIG_MACH_IQ81340MC) += iq81340mc.o
......@@ -41,7 +41,7 @@ void * __iomem __iop13xx_io(unsigned long io_addr)
EXPORT_SYMBOL(__iop13xx_io);
void * __iomem __iop13xx_ioremap(unsigned long cookie, size_t size,
unsigned long flags)
unsigned int mtype)
{
void __iomem * retval;
......@@ -61,9 +61,9 @@ void * __iomem __iop13xx_ioremap(unsigned long cookie, size_t size,
(cookie - IOP13XX_PCIE_LOWER_MEM_RA));
break;
case IOP13XX_PBI_LOWER_MEM_RA ... IOP13XX_PBI_UPPER_MEM_RA:
retval = __ioremap(IOP13XX_PBI_LOWER_MEM_PA +
(cookie - IOP13XX_PBI_LOWER_MEM_RA),
size, flags);
retval = __arm_ioremap(IOP13XX_PBI_LOWER_MEM_PA +
(cookie - IOP13XX_PBI_LOWER_MEM_RA),
size, mtype);
break;
case IOP13XX_PCIE_LOWER_IO_PA ... IOP13XX_PCIE_UPPER_IO_PA:
retval = (void *) IOP13XX_PCIE_IO_PHYS_TO_VIRT(cookie);
......@@ -75,7 +75,7 @@ void * __iomem __iop13xx_ioremap(unsigned long cookie, size_t size,
retval = (void *) IOP13XX_PMMR_PHYS_TO_VIRT(cookie);
break;
default:
retval = __ioremap(cookie, size, flags);
retval = __arm_ioremap(cookie, size, mtype);
}
return retval;
......
......@@ -75,11 +75,14 @@ static void __init iq81340mc_init(void)
{
iop13xx_platform_init();
iq81340mc_pci_init();
iop13xx_add_tpmi_devices();
}
static void __init iq81340mc_timer_init(void)
{
iop_init_time(400000000);
unsigned long bus_freq = iop13xx_core_freq() / iop13xx_xsi_bus_ratio();
printk(KERN_DEBUG "%s: bus frequency: %lu\n", __FUNCTION__, bus_freq);
iop_init_time(bus_freq);
}
static struct sys_timer iq81340mc_timer = {
......
......@@ -77,11 +77,14 @@ static void __init iq81340sc_init(void)
{
iop13xx_platform_init();
iq81340sc_pci_init();
iop13xx_add_tpmi_devices();
}
static void __init iq81340sc_timer_init(void)
{
iop_init_time(400000000);
unsigned long bus_freq = iop13xx_core_freq() / iop13xx_xsi_bus_ratio();
printk(KERN_DEBUG "%s: bus frequency: %lu\n", __FUNCTION__, bus_freq);
iop_init_time(bus_freq);
}
static struct sys_timer iq81340sc_timer = {
......
......@@ -88,9 +88,9 @@ void iop13xx_map_pci_memory(void)
if (end) {
iop13xx_atux_mem_base =
(u32) __ioremap_pfn(
(u32) __arm_ioremap_pfn(
__phys_to_pfn(IOP13XX_PCIX_LOWER_MEM_PA)
, 0, iop13xx_atux_mem_size, 0);
, 0, iop13xx_atux_mem_size, MT_DEVICE);
if (!iop13xx_atux_mem_base) {
printk("%s: atux allocation "
"failed\n", __FUNCTION__);
......@@ -114,9 +114,9 @@ void iop13xx_map_pci_memory(void)
if (end) {
iop13xx_atue_mem_base =
(u32) __ioremap_pfn(
(u32) __arm_ioremap_pfn(
__phys_to_pfn(IOP13XX_PCIE_LOWER_MEM_PA)
, 0, iop13xx_atue_mem_size, 0);
, 0, iop13xx_atue_mem_size, MT_DEVICE);
if (!iop13xx_atue_mem_base) {
printk("%s: atue allocation "
"failed\n", __FUNCTION__);
......@@ -1023,7 +1023,7 @@ int iop13xx_pci_setup(int nr, struct pci_sys_data *sys)
<< IOP13XX_ATUX_PCIXSR_FUNC_NUM;
__raw_writel(pcixsr, IOP13XX_ATUX_PCIXSR);
res[0].start = IOP13XX_PCIX_LOWER_IO_PA;
res[0].start = IOP13XX_PCIX_LOWER_IO_PA + IOP13XX_PCIX_IO_BUS_OFFSET;
res[0].end = IOP13XX_PCIX_UPPER_IO_PA;
res[0].name = "IQ81340 ATUX PCI I/O Space";
res[0].flags = IORESOURCE_IO;
......@@ -1033,7 +1033,7 @@ int iop13xx_pci_setup(int nr, struct pci_sys_data *sys)
res[1].name = "IQ81340 ATUX PCI Memory Space";
res[1].flags = IORESOURCE_MEM;
sys->mem_offset = IOP13XX_PCIX_MEM_OFFSET;
sys->io_offset = IOP13XX_PCIX_IO_OFFSET;
sys->io_offset = IOP13XX_PCIX_LOWER_IO_PA;
break;
case IOP13XX_INIT_ATU_ATUE:
/* Note: the function number field in the PCSR is ro */
......@@ -1044,7 +1044,7 @@ int iop13xx_pci_setup(int nr, struct pci_sys_data *sys)
__raw_writel(pcsr, IOP13XX_ATUE_PCSR);
res[0].start = IOP13XX_PCIE_LOWER_IO_PA;
res[0].start = IOP13XX_PCIE_LOWER_IO_PA + IOP13XX_PCIE_IO_BUS_OFFSET;
res[0].end = IOP13XX_PCIE_UPPER_IO_PA;
res[0].name = "IQ81340 ATUE PCI I/O Space";
res[0].flags = IORESOURCE_IO;
......@@ -1054,7 +1054,7 @@ int iop13xx_pci_setup(int nr, struct pci_sys_data *sys)
res[1].name = "IQ81340 ATUE PCI Memory Space";
res[1].flags = IORESOURCE_MEM;
sys->mem_offset = IOP13XX_PCIE_MEM_OFFSET;
sys->io_offset = IOP13XX_PCIE_IO_OFFSET;
sys->io_offset = IOP13XX_PCIE_LOWER_IO_PA;
sys->map_irq = iop13xx_pcie_map_irq;
break;
default:
......
......@@ -258,15 +258,11 @@ void __init iop13xx_platform_init(void)
if (init_uart == IOP13XX_INIT_UART_DEFAULT) {
switch (iop13xx_dev_id()) {
/* enable both uarts on iop341 and iop342 */
/* enable both uarts on iop341 */
case 0x3380:
case 0x3384:
case 0x3388:
case 0x338c:
case 0x3382:
case 0x3386:
case 0x338a:
case 0x338e:
init_uart |= IOP13XX_INIT_UART_0;
init_uart |= IOP13XX_INIT_UART_1;
break;
......
/*
* iop13xx tpmi device resources
* Copyright (c) 2005-2006, Intel Corporation.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope 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.
*
*/
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/dma-mapping.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/sizes.h>
/* assumes CONTROLLER_ONLY# is never asserted in the ESSR register */
#define IOP13XX_TPMI_MMR(dev) IOP13XX_REG_ADDR32_PHYS(0x48000 + (dev << 12))
#define IOP13XX_TPMI_MEM(dev) IOP13XX_REG_ADDR32_PHYS(0x60000 + (dev << 13))
#define IOP13XX_TPMI_CTRL(dev) IOP13XX_REG_ADDR32_PHYS(0x50000 + (dev << 10))
#define IOP13XX_TPMI_MMR_SIZE (SZ_4K - 1)
#define IOP13XX_TPMI_MEM_SIZE (255)
#define IOP13XX_TPMI_MEM_CTRL (SZ_1K - 1)
#define IOP13XX_TPMI_RESOURCE_MMR 0
#define IOP13XX_TPMI_RESOURCE_MEM 1
#define IOP13XX_TPMI_RESOURCE_CTRL 2
#define IOP13XX_TPMI_RESOURCE_IRQ 3
static struct resource iop13xx_tpmi_0_resources[] = {
[IOP13XX_TPMI_RESOURCE_MMR] = {
.start = IOP13XX_TPMI_MMR(4), /* tpmi0 starts at dev == 4 */
.end = IOP13XX_TPMI_MMR(4) + IOP13XX_TPMI_MMR_SIZE,
.flags = IORESOURCE_MEM,
},
[IOP13XX_TPMI_RESOURCE_MEM] = {
.start = IOP13XX_TPMI_MEM(0),
.end = IOP13XX_TPMI_MEM(0) + IOP13XX_TPMI_MEM_SIZE,
.flags = IORESOURCE_MEM,
},
[IOP13XX_TPMI_RESOURCE_CTRL] = {
.start = IOP13XX_TPMI_CTRL(0),
.end = IOP13XX_TPMI_CTRL(0) + IOP13XX_TPMI_MEM_CTRL,
.flags = IORESOURCE_MEM,
},
[IOP13XX_TPMI_RESOURCE_IRQ] = {
.start = IRQ_IOP13XX_TPMI0_OUT,
.end = IRQ_IOP13XX_TPMI0_OUT,
.flags = IORESOURCE_IRQ
}
};
static struct resource iop13xx_tpmi_1_resources[] = {
[IOP13XX_TPMI_RESOURCE_MMR] = {
.start = IOP13XX_TPMI_MMR(1),
.end = IOP13XX_TPMI_MMR(1) + IOP13XX_TPMI_MMR_SIZE,
.flags = IORESOURCE_MEM,
},
[IOP13XX_TPMI_RESOURCE_MEM] = {
.start = IOP13XX_TPMI_MEM(1),
.end = IOP13XX_TPMI_MEM(1) + IOP13XX_TPMI_MEM_SIZE,
.flags = IORESOURCE_MEM,
},
[IOP13XX_TPMI_RESOURCE_CTRL] = {
.start = IOP13XX_TPMI_CTRL(1),
.end = IOP13XX_TPMI_CTRL(1) + IOP13XX_TPMI_MEM_CTRL,
.flags = IORESOURCE_MEM,
},
[IOP13XX_TPMI_RESOURCE_IRQ] = {
.start = IRQ_IOP13XX_TPMI1_OUT,
.end = IRQ_IOP13XX_TPMI1_OUT,
.flags = IORESOURCE_IRQ
}
};
static struct resource iop13xx_tpmi_2_resources[] = {
[IOP13XX_TPMI_RESOURCE_MMR] = {
.start = IOP13XX_TPMI_MMR(2),
.end = IOP13XX_TPMI_MMR(2) + IOP13XX_TPMI_MMR_SIZE,
.flags = IORESOURCE_MEM,
},
[IOP13XX_TPMI_RESOURCE_MEM] = {
.start = IOP13XX_TPMI_MEM(2),
.end = IOP13XX_TPMI_MEM(2) + IOP13XX_TPMI_MEM_SIZE,
.flags = IORESOURCE_MEM,
},
[IOP13XX_TPMI_RESOURCE_CTRL] = {
.start = IOP13XX_TPMI_CTRL(2),
.end = IOP13XX_TPMI_CTRL(2) + IOP13XX_TPMI_MEM_CTRL,
.flags = IORESOURCE_MEM,
},
[IOP13XX_TPMI_RESOURCE_IRQ] = {
.start = IRQ_IOP13XX_TPMI2_OUT,
.end = IRQ_IOP13XX_TPMI2_OUT,
.flags = IORESOURCE_IRQ
}
};
static struct resource iop13xx_tpmi_3_resources[] = {
[IOP13XX_TPMI_RESOURCE_MMR] = {
.start = IOP13XX_TPMI_MMR(3),
.end = IOP13XX_TPMI_MMR(3) + IOP13XX_TPMI_MMR_SIZE,
.flags = IORESOURCE_MEM,
},
[IOP13XX_TPMI_RESOURCE_MEM] = {
.start = IOP13XX_TPMI_MEM(3),
.end = IOP13XX_TPMI_MEM(3) + IOP13XX_TPMI_MEM_SIZE,
.flags = IORESOURCE_MEM,
},
[IOP13XX_TPMI_RESOURCE_CTRL] = {
.start = IOP13XX_TPMI_CTRL(3),
.end = IOP13XX_TPMI_CTRL(3) + IOP13XX_TPMI_MEM_CTRL,
.flags = IORESOURCE_MEM,
},
[IOP13XX_TPMI_RESOURCE_IRQ] = {
.start = IRQ_IOP13XX_TPMI3_OUT,
.end = IRQ_IOP13XX_TPMI3_OUT,
.flags = IORESOURCE_IRQ
}
};
u64 iop13xx_tpmi_mask = DMA_64BIT_MASK;
static struct platform_device iop13xx_tpmi_0_device = {
.name = "iop-tpmi",
.id = 0,
.num_resources = 4,
.resource = iop13xx_tpmi_0_resources,
.dev = {
.dma_mask = &iop13xx_tpmi_mask,
.coherent_dma_mask = DMA_64BIT_MASK,
},
};
static struct platform_device iop13xx_tpmi_1_device = {
.name = "iop-tpmi",
.id = 1,
.num_resources = 4,
.resource = iop13xx_tpmi_1_resources,
.dev = {
.dma_mask = &iop13xx_tpmi_mask,
.coherent_dma_mask = DMA_64BIT_MASK,
},
};
static struct platform_device iop13xx_tpmi_2_device = {
.name = "iop-tpmi",
.id = 2,
.num_resources = 4,
.resource = iop13xx_tpmi_2_resources,
.dev = {
.dma_mask = &iop13xx_tpmi_mask,
.coherent_dma_mask = DMA_64BIT_MASK,
},
};
static struct platform_device iop13xx_tpmi_3_device = {
.name = "iop-tpmi",
.id = 3,
.num_resources = 4,
.resource = iop13xx_tpmi_3_resources,
.dev = {
.dma_mask = &iop13xx_tpmi_mask,
.coherent_dma_mask = DMA_64BIT_MASK,
},
};
__init void iop13xx_add_tpmi_devices(void)
{
unsigned short device_id;
/* tpmi's not present on iop341 or iop342 */
if (__raw_readl(IOP13XX_ESSR0) & IOP13XX_INTERFACE_SEL_PCIX)
/* ATUE must be present */
device_id = __raw_readw(IOP13XX_ATUE_DID);
else
/* ATUX must be present */
device_id = __raw_readw(IOP13XX_ATUX_DID);
switch (device_id) {
/* iop34[1|2] 0-tpmi */
case 0x3380:
case 0x3384:
case 0x3388:
case 0x338c:
case 0x3382:
case 0x3386:
case 0x338a:
case 0x338e:
return;
/* iop348 1-tpmi */
case 0x3310:
case 0x3312:
case 0x3314:
case 0x3318:
case 0x331a:
case 0x331c:
case 0x33c0:
case 0x33c2:
case 0x33c4:
case 0x33c8:
case 0x33ca:
case 0x33cc:
case 0x33b0:
case 0x33b2:
case 0x33b4:
case 0x33b8:
case 0x33ba:
case 0x33bc:
case 0x3320:
case 0x3322:
case 0x3324:
case 0x3328:
case 0x332a:
case 0x332c:
platform_device_register(&iop13xx_tpmi_0_device);
return;
default:
platform_device_register(&iop13xx_tpmi_0_device);
platform_device_register(&iop13xx_tpmi_1_device);
platform_device_register(&iop13xx_tpmi_2_device);
platform_device_register(&iop13xx_tpmi_3_device);
return;
}
}
......@@ -34,6 +34,14 @@ config MACH_N2100
Say Y here if you want to run your kernel on the Thecus n2100
NAS appliance.
config IOP3XX_ATU
bool "Enable the PCI Controller"
default y
help
Say Y here if you want the IOP to initialize its PCI Controller.
Say N if the IOP is an add in card, the host system owns the PCI
bus in this case.
endmenu
endif
......@@ -178,9 +178,10 @@ static struct hw_pci iq31244_pci __initdata = {
static int __init iq31244_pci_init(void)
{
if (is_ep80219())
pci_common_init(&ep80219_pci);
else if (machine_is_iq31244()) {
if (is_ep80219()) {
if (iop3xx_get_init_atu() == IOP3XX_INIT_ATU_ENABLE)
pci_common_init(&ep80219_pci);
} else if (machine_is_iq31244()) {
if (is_80219()) {
printk("note: iq31244 board type has been selected\n");
printk("note: to select ep80219 operation:\n");
......@@ -189,7 +190,9 @@ static int __init iq31244_pci_init(void)
printk("\t2/ update boot loader to pass"
" the ep80219 id: %d\n", MACH_TYPE_EP80219);
}
pci_common_init(&iq31244_pci);
if (iop3xx_get_init_atu() == IOP3XX_INIT_ATU_ENABLE)
pci_common_init(&iq31244_pci);
}
return 0;
......
......@@ -113,7 +113,8 @@ static struct hw_pci iq80321_pci __initdata = {
static int __init iq80321_pci_init(void)
{
if (machine_is_iq80321())
if ((iop3xx_get_init_atu() == IOP3XX_INIT_ATU_ENABLE) &&
machine_is_iq80321())
pci_common_init(&iq80321_pci);
return 0;
......
......@@ -16,6 +16,14 @@ config MACH_IQ80332
Say Y here if you want to run your kernel on the Intel IQ80332
evaluation kit for the IOP332 chipset.
config IOP3XX_ATU
bool "Enable the PCI Controller"
default y
help
Say Y here if you want the IOP to initialize its PCI Controller.
Say N if the IOP is an add in card, the host system owns the PCI
bus in this case.
endmenu
endif
......@@ -96,7 +96,8 @@ static struct hw_pci iq80331_pci __initdata = {
static int __init iq80331_pci_init(void)
{
if (machine_is_iq80331())
if ((iop3xx_get_init_atu() == IOP3XX_INIT_ATU_ENABLE) &&
machine_is_iq80331())
pci_common_init(&iq80331_pci);
return 0;
......
......@@ -96,7 +96,8 @@ static struct hw_pci iq80332_pci __initdata = {
static int __init iq80332_pci_init(void)
{
if (machine_is_iq80332())
if ((iop3xx_get_init_atu() == IOP3XX_INIT_ATU_ENABLE) &&
machine_is_iq80332())
pci_common_init(&iq80332_pci);
return 0;
......
......@@ -84,59 +84,59 @@ static struct map_desc ixp2000_io_desc[] __initdata = {
.virtual = IXP2000_CAP_VIRT_BASE,
.pfn = __phys_to_pfn(IXP2000_CAP_PHYS_BASE),
.length = IXP2000_CAP_SIZE,
.type = MT_IXP2000_DEVICE,
.type = MT_DEVICE_IXP2000,
}, {
.virtual = IXP2000_INTCTL_VIRT_BASE,
.pfn = __phys_to_pfn(IXP2000_INTCTL_PHYS_BASE),
.length = IXP2000_INTCTL_SIZE,
.type = MT_IXP2000_DEVICE,
.type = MT_DEVICE_IXP2000,
}, {
.virtual = IXP2000_PCI_CREG_VIRT_BASE,
.pfn = __phys_to_pfn(IXP2000_PCI_CREG_PHYS_BASE),
.length = IXP2000_PCI_CREG_SIZE,
.type = MT_IXP2000_DEVICE,
.type = MT_DEVICE_IXP2000,
}, {
.virtual = IXP2000_PCI_CSR_VIRT_BASE,
.pfn = __phys_to_pfn(IXP2000_PCI_CSR_PHYS_BASE),
.length = IXP2000_PCI_CSR_SIZE,
.type = MT_IXP2000_DEVICE,
.type = MT_DEVICE_IXP2000,
}, {
.virtual = IXP2000_MSF_VIRT_BASE,
.pfn = __phys_to_pfn(IXP2000_MSF_PHYS_BASE),
.length = IXP2000_MSF_SIZE,
.type = MT_IXP2000_DEVICE,
.type = MT_DEVICE_IXP2000,
}, {
.virtual = IXP2000_SCRATCH_RING_VIRT_BASE,
.pfn = __phys_to_pfn(IXP2000_SCRATCH_RING_PHYS_BASE),
.length = IXP2000_SCRATCH_RING_SIZE,
.type = MT_IXP2000_DEVICE,
.type = MT_DEVICE_IXP2000,
}, {
.virtual = IXP2000_SRAM0_VIRT_BASE,
.pfn = __phys_to_pfn(IXP2000_SRAM0_PHYS_BASE),
.length = IXP2000_SRAM0_SIZE,
.type = MT_IXP2000_DEVICE,
.type = MT_DEVICE_IXP2000,
}, {
.virtual = IXP2000_PCI_IO_VIRT_BASE,
.pfn = __phys_to_pfn(IXP2000_PCI_IO_PHYS_BASE),
.length = IXP2000_PCI_IO_SIZE,
.type = MT_IXP2000_DEVICE,
.type = MT_DEVICE_IXP2000,
}, {
.virtual = IXP2000_PCI_CFG0_VIRT_BASE,
.pfn = __phys_to_pfn(IXP2000_PCI_CFG0_PHYS_BASE),
.length = IXP2000_PCI_CFG0_SIZE,
.type = MT_IXP2000_DEVICE,
.type = MT_DEVICE_IXP2000,
}, {
.virtual = IXP2000_PCI_CFG1_VIRT_BASE,
.pfn = __phys_to_pfn(IXP2000_PCI_CFG1_PHYS_BASE),
.length = IXP2000_PCI_CFG1_SIZE,
.type = MT_IXP2000_DEVICE,
.type = MT_DEVICE_IXP2000,
}
};
void __init ixp2000_map_io(void)
{
/*
* On IXP2400 CPUs we need to use MT_IXP2000_DEVICE so that
* On IXP2400 CPUs we need to use MT_DEVICE_IXP2000 so that
* XCB=101 (to avoid triggering erratum #66), and given that
* this mode speeds up I/O accesses and we have write buffer
* flushes in the right places anyway, it doesn't hurt to use
......
......@@ -70,17 +70,17 @@ static struct map_desc enp2611_io_desc[] __initdata = {
.virtual = ENP2611_CALEB_VIRT_BASE,
.pfn = __phys_to_pfn(ENP2611_CALEB_PHYS_BASE),
.length = ENP2611_CALEB_SIZE,
.type = MT_IXP2000_DEVICE,
.type = MT_DEVICE_IXP2000,
}, {
.virtual = ENP2611_PM3386_0_VIRT_BASE,
.pfn = __phys_to_pfn(ENP2611_PM3386_0_PHYS_BASE),
.length = ENP2611_PM3386_0_SIZE,
.type = MT_IXP2000_DEVICE,
.type = MT_DEVICE_IXP2000,
}, {
.virtual = ENP2611_PM3386_1_VIRT_BASE,
.pfn = __phys_to_pfn(ENP2611_PM3386_1_PHYS_BASE),
.length = ENP2611_PM3386_1_SIZE,
.type = MT_IXP2000_DEVICE,
.type = MT_DEVICE_IXP2000,
}
};
......
......@@ -62,6 +62,12 @@ config MACH_IXDP465
IXDP465 Development Platform (Also known as BMP).
For more information on this platform, see <file:Documentation/arm/IXP4xx>.
config MACH_KIXRP435
bool "KIXRP435"
help
Say 'Y' here if you want your kernel to support Intel's
KIXRP435 Reference Platform.
For more information on this platform, see <file:Documentation/arm/IXP4xx>.
#
# IXCDP1100 is the exact same HW as IXDP425, but with a different machine
......@@ -89,12 +95,21 @@ config MACH_NAS100D
NAS 100d device. For more information on this platform,
see http://www.nslu2-linux.org/wiki/NAS100d/HomePage
config MACH_DSMG600
bool
prompt "D-Link DSM-G600 RevA"
select PCI
help
Say 'Y' here if you want your kernel to support D-Link's
DSM-G600 RevA device. For more information on this platform,
see http://www.nslu2-linux.org/wiki/DSMG600/HomePage
#
# Avila and IXDP share the same source for now. Will change in future
#
config ARCH_IXDP4XX
bool
depends on ARCH_IXDP425 || MACH_IXDP465
depends on ARCH_IXDP425 || MACH_IXDP465 || MACH_KIXRP435
default y
#
......@@ -105,6 +120,11 @@ config CPU_IXP46X
depends on MACH_IXDP465
default y
config CPU_IXP43X
bool
depends on MACH_KIXRP435
default y
config MACH_GTWX5715
bool "Gemtek WX5715 (Linksys WRV54G)"
depends on ARCH_IXP4XX
......
......@@ -12,6 +12,7 @@ obj-pci-$(CONFIG_ARCH_ADI_COYOTE) += coyote-pci.o
obj-pci-$(CONFIG_MACH_GTWX5715) += gtwx5715-pci.o
obj-pci-$(CONFIG_MACH_NSLU2) += nslu2-pci.o
obj-pci-$(CONFIG_MACH_NAS100D) += nas100d-pci.o
obj-pci-$(CONFIG_MACH_DSMG600) += dsmg600-pci.o
obj-y += common.o
......@@ -22,5 +23,6 @@ obj-$(CONFIG_ARCH_ADI_COYOTE) += coyote-setup.o
obj-$(CONFIG_MACH_GTWX5715) += gtwx5715-setup.o
obj-$(CONFIG_MACH_NSLU2) += nslu2-setup.o nslu2-power.o
obj-$(CONFIG_MACH_NAS100D) += nas100d-setup.o nas100d-power.o
obj-$(CONFIG_MACH_DSMG600) += dsmg600-setup.o dsmg600-power.o
obj-$(CONFIG_PCI) += $(obj-pci-$(CONFIG_PCI)) common-pci.o
......@@ -374,7 +374,7 @@ void __init ixp4xx_pci_preinit(void)
* Determine which PCI read method to use.
* Rev 0 IXP425 requires workaround.
*/
if (!(processor_id & 0xf) && !cpu_is_ixp46x()) {
if (!(processor_id & 0xf) && cpu_is_ixp42x()) {
printk("PCI: IXP42x A0 silicon detected - "
"PCI Non-Prefetch Workaround Enabled\n");
ixp4xx_pci_read = ixp4xx_pci_read_errata;
......@@ -480,7 +480,7 @@ int ixp4xx_setup(int nr, struct pci_sys_data *sys)
res[0].flags = IORESOURCE_IO;
res[1].name = "PCI Memory Space";
res[1].start = 0x48000000;
res[1].start = PCIBIOS_MIN_MEM;
#ifndef CONFIG_IXP4XX_INDIRECT_PCI
res[1].end = 0x4bffffff;
#else
......
......@@ -27,6 +27,7 @@
#include <linux/time.h>
#include <linux/timex.h>
#include <linux/clocksource.h>
#include <linux/clockchips.h>
#include <asm/arch/udc.h>
#include <asm/hardware.h>
......@@ -41,6 +42,8 @@
#include <asm/mach/time.h>
static int __init ixp4xx_clocksource_init(void);
static int __init ixp4xx_clockevent_init(void);
static struct clock_event_device clockevent_ixp4xx;
/*************************************************************************
* IXP4xx chipset I/O mapping
......@@ -102,6 +105,29 @@ static signed char irq2gpio[32] = {
7, 8, 9, 10, 11, 12, -1, -1,
};
int gpio_to_irq(int gpio)
{
int irq;
for (irq = 0; irq < 32; irq++) {
if (irq2gpio[irq] == gpio)
return irq;
}
return -EINVAL;
}
EXPORT_SYMBOL(gpio_to_irq);
int irq_to_gpio(int irq)
{
int gpio = (irq < 32) ? irq2gpio[irq] : -EINVAL;
if (gpio == -1)
return -EINVAL;
return gpio;
}
EXPORT_SYMBOL(irq_to_gpio);
static int ixp4xx_set_irq_type(unsigned int irq, unsigned int type)
{
int line = irq2gpio[irq];
......@@ -169,7 +195,7 @@ static int ixp4xx_set_irq_type(unsigned int irq, unsigned int type)
static void ixp4xx_irq_mask(unsigned int irq)
{
if (cpu_is_ixp46x() && irq >= 32)
if ((cpu_is_ixp46x() || cpu_is_ixp43x()) && irq >= 32)
*IXP4XX_ICMR2 &= ~(1 << (irq - 32));
else
*IXP4XX_ICMR &= ~(1 << irq);
......@@ -192,7 +218,7 @@ static void ixp4xx_irq_unmask(unsigned int irq)
if (!(ixp4xx_irq_edge & (1 << irq)))
ixp4xx_irq_ack(irq);
if (cpu_is_ixp46x() && irq >= 32)
if ((cpu_is_ixp46x() || cpu_is_ixp43x()) && irq >= 32)
*IXP4XX_ICMR2 |= (1 << (irq - 32));
else
*IXP4XX_ICMR |= (1 << irq);
......@@ -216,7 +242,7 @@ void __init ixp4xx_init_irq(void)
/* Disable all interrupt */
*IXP4XX_ICMR = 0x0;
if (cpu_is_ixp46x()) {
if (cpu_is_ixp46x() || cpu_is_ixp43x()) {
/* Route upper 32 sources to IRQ instead of FIQ */
*IXP4XX_ICLR2 = 0x00;
......@@ -239,52 +265,40 @@ void __init ixp4xx_init_irq(void)
* counter as a source of real clock ticks to account for missed jiffies.
*************************************************************************/
static unsigned volatile last_jiffy_time;
#define CLOCK_TICKS_PER_USEC ((CLOCK_TICK_RATE + USEC_PER_SEC/2) / USEC_PER_SEC)
static irqreturn_t ixp4xx_timer_interrupt(int irq, void *dev_id)
{
write_seqlock(&xtime_lock);
struct clock_event_device *evt = &clockevent_ixp4xx;
/* Clear Pending Interrupt by writing '1' to it */
*IXP4XX_OSST = IXP4XX_OSST_TIMER_1_PEND;
/*
* Catch up with the real idea of time
*/
while ((signed long)(*IXP4XX_OSTS - last_jiffy_time) >= LATCH) {
timer_tick();
last_jiffy_time += LATCH;
}
write_sequnlock(&xtime_lock);
evt->event_handler(evt);
return IRQ_HANDLED;
}
static struct irqaction ixp4xx_timer_irq = {
.name = "IXP4xx Timer Tick",
.name = "timer1",
.flags = IRQF_DISABLED | IRQF_TIMER,
.handler = ixp4xx_timer_interrupt,
};
static void __init ixp4xx_timer_init(void)
{
/* Reset/disable counter */
*IXP4XX_OSRT1 = 0;
/* Clear Pending Interrupt by writing '1' to it */
*IXP4XX_OSST = IXP4XX_OSST_TIMER_1_PEND;
/* Setup the Timer counter value */
*IXP4XX_OSRT1 = (LATCH & ~IXP4XX_OST_RELOAD_MASK) | IXP4XX_OST_ENABLE;
/* Reset time-stamp counter */
*IXP4XX_OSTS = 0;
last_jiffy_time = 0;
/* Connect the interrupt handler and enable the interrupt */
setup_irq(IRQ_IXP4XX_TIMER1, &ixp4xx_timer_irq);
ixp4xx_clocksource_init();
ixp4xx_clockevent_init();
}
struct sys_timer ixp4xx_timer = {
......@@ -384,6 +398,9 @@ void __init ixp4xx_sys_init(void)
ixp4xx_exp_bus_size >> 20);
}
/*
* clocksource
*/
cycle_t ixp4xx_get_cycles(void)
{
return *IXP4XX_OSTS;
......@@ -408,3 +425,64 @@ static int __init ixp4xx_clocksource_init(void)
return 0;
}
/*
* clockevents
*/
static int ixp4xx_set_next_event(unsigned long evt,
struct clock_event_device *unused)
{
unsigned long opts = *IXP4XX_OSRT1 & IXP4XX_OST_RELOAD_MASK;
*IXP4XX_OSRT1 = (evt & ~IXP4XX_OST_RELOAD_MASK) | opts;
return 0;
}
static void ixp4xx_set_mode(enum clock_event_mode mode,
struct clock_event_device *evt)
{
unsigned long opts, osrt = *IXP4XX_OSRT1 & ~IXP4XX_OST_RELOAD_MASK;
switch (mode) {
case CLOCK_EVT_MODE_PERIODIC:
osrt = LATCH & ~IXP4XX_OST_RELOAD_MASK;
opts = IXP4XX_OST_ENABLE;
break;
case CLOCK_EVT_MODE_ONESHOT:
/* period set by 'set next_event' */
osrt = 0;
opts = IXP4XX_OST_ENABLE | IXP4XX_OST_ONE_SHOT;
break;
case CLOCK_EVT_MODE_SHUTDOWN:
case CLOCK_EVT_MODE_UNUSED:
default:
osrt = opts = 0;
break;
}
*IXP4XX_OSRT1 = osrt | opts;
}
static struct clock_event_device clockevent_ixp4xx = {
.name = "ixp4xx timer1",
.features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
.rating = 200,
.shift = 24,
.set_mode = ixp4xx_set_mode,
.set_next_event = ixp4xx_set_next_event,
};
static int __init ixp4xx_clockevent_init(void)
{
clockevent_ixp4xx.mult = div_sc(FREQ, NSEC_PER_SEC,
clockevent_ixp4xx.shift);
clockevent_ixp4xx.max_delta_ns =
clockevent_delta2ns(0xfffffffe, &clockevent_ixp4xx);
clockevent_ixp4xx.min_delta_ns =
clockevent_delta2ns(0xf, &clockevent_ixp4xx);
clockevent_ixp4xx.cpumask = cpumask_of_cpu(0);
clockevents_register_device(&clockevent_ixp4xx);
return 0;
}
/*
* DSM-G600 board-level PCI initialization
*
* Copyright (C) 2006 Tower Technologies
* Author: Alessandro Zummo <a.zummo@towertech.it>
*
* based on ixdp425-pci.c:
* Copyright (C) 2002 Intel Corporation.
* Copyright (C) 2003-2004 MontaVista Software, Inc.
*
* Maintainer: http://www.nslu2-linux.org/
*
* 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/pci.h>
#include <linux/init.h>
#include <linux/irq.h>
#include <asm/mach/pci.h>
#include <asm/mach-types.h>
void __init dsmg600_pci_preinit(void)
{
set_irq_type(IRQ_DSMG600_PCI_INTA, IRQT_LOW);
set_irq_type(IRQ_DSMG600_PCI_INTB, IRQT_LOW);
set_irq_type(IRQ_DSMG600_PCI_INTC, IRQT_LOW);
set_irq_type(IRQ_DSMG600_PCI_INTD, IRQT_LOW);
set_irq_type(IRQ_DSMG600_PCI_INTE, IRQT_LOW);
set_irq_type(IRQ_DSMG600_PCI_INTF, IRQT_LOW);
ixp4xx_pci_preinit();
}
static int __init dsmg600_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
{
static int pci_irq_table[DSMG600_PCI_MAX_DEV][DSMG600_PCI_IRQ_LINES] =
{
{ IRQ_DSMG600_PCI_INTE, -1, -1 },
{ IRQ_DSMG600_PCI_INTA, -1, -1 },
{ IRQ_DSMG600_PCI_INTB, IRQ_DSMG600_PCI_INTC, IRQ_DSMG600_PCI_INTD },
{ IRQ_DSMG600_PCI_INTF, -1, -1 },
};
int irq = -1;
if (slot >= 1 && slot <= DSMG600_PCI_MAX_DEV &&
pin >= 1 && pin <= DSMG600_PCI_IRQ_LINES)
irq = pci_irq_table[slot-1][pin-1];
return irq;
}
struct hw_pci __initdata dsmg600_pci = {
.nr_controllers = 1,
.preinit = dsmg600_pci_preinit,
.swizzle = pci_std_swizzle,
.setup = ixp4xx_setup,
.scan = ixp4xx_scan_bus,
.map_irq = dsmg600_map_irq,
};
int __init dsmg600_pci_init(void)
{
if (machine_is_dsmg600())
pci_common_init(&dsmg600_pci);
return 0;
}
subsys_initcall(dsmg600_pci_init);
/*
* arch/arm/mach-ixp4xx/dsmg600-power.c
*
* DSM-G600 Power/Reset driver
* Author: Michael Westerhof <mwester@dls.net>
*
* Based on nslu2-power.c
* Copyright (C) 2005 Tower Technologies
* Author: Alessandro Zummo <a.zummo@towertech.it>
*
* which was based on nslu2-io.c
* Copyright (C) 2004 Karen Spearel
*
* Maintainers: http://www.nslu2-linux.org/
*
* 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/reboot.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/jiffies.h>
#include <linux/timer.h>
#include <asm/mach-types.h>
extern void ctrl_alt_del(void);
/* This is used to make sure the power-button pusher is serious. The button
* must be held until the value of this counter reaches zero.
*/
static volatile int power_button_countdown;
/* Must hold the button down for at least this many counts to be processed */
#define PBUTTON_HOLDDOWN_COUNT 4 /* 2 secs */
static void dsmg600_power_handler(unsigned long data);
static DEFINE_TIMER(dsmg600_power_timer, dsmg600_power_handler, 0, 0);
static void dsmg600_power_handler(unsigned long data)
{
/* This routine is called twice per second to check the
* state of the power button.
*/
if (*IXP4XX_GPIO_GPINR & DSMG600_PB_BM) {
/* IO Pin is 1 (button pushed) */
if (power_button_countdown == 0) {
/* Signal init to do the ctrlaltdel action, this will bypass
* init if it hasn't started and do a kernel_restart.
*/
ctrl_alt_del();
/* Change the state of the power LED to "blink" */
gpio_line_set(DSMG600_LED_PWR_GPIO, IXP4XX_GPIO_LOW);
}
power_button_countdown--;
} else {
power_button_countdown = PBUTTON_HOLDDOWN_COUNT;
}
mod_timer(&dsmg600_power_timer, jiffies + msecs_to_jiffies(500));
}
static irqreturn_t dsmg600_reset_handler(int irq, void *dev_id)
{
/* This is the paper-clip reset, it shuts the machine down directly. */
machine_power_off();
return IRQ_HANDLED;
}
static int __init dsmg600_power_init(void)
{
if (!(machine_is_dsmg600()))
return 0;
if (request_irq(DSMG600_RB_IRQ, &dsmg600_reset_handler,
IRQF_DISABLED | IRQF_TRIGGER_LOW, "DSM-G600 reset button",
NULL) < 0) {
printk(KERN_DEBUG "Reset Button IRQ %d not available\n",
DSMG600_RB_IRQ);
return -EIO;
}
/* The power button on the D-Link DSM-G600 is on GPIO 15, but
* it cannot handle interrupts on that GPIO line. So we'll
* have to poll it with a kernel timer.
*/
/* Make sure that the power button GPIO is set up as an input */
gpio_line_config(DSMG600_PB_GPIO, IXP4XX_GPIO_IN);
/* Set the initial value for the power button IRQ handler */
power_button_countdown = PBUTTON_HOLDDOWN_COUNT;
mod_timer(&dsmg600_power_timer, jiffies + msecs_to_jiffies(500));
return 0;
}
static void __exit dsmg600_power_exit(void)
{
if (!(machine_is_dsmg600()))
return;
del_timer_sync(&dsmg600_power_timer);
free_irq(DSMG600_RB_IRQ, NULL);
}
module_init(dsmg600_power_init);
module_exit(dsmg600_power_exit);
MODULE_AUTHOR("Michael Westerhof <mwester@dls.net>");
MODULE_DESCRIPTION("DSM-G600 Power/Reset driver");
MODULE_LICENSE("GPL");
/*
* DSM-G600 board-setup
*
* Copyright (C) 2006 Tower Technologies
* Author: Alessandro Zummo <a.zummo@towertech.it>
*
* based ixdp425-setup.c:
* Copyright (C) 2003-2004 MontaVista Software, Inc.
*
* Author: Alessandro Zummo <a.zummo@towertech.it>
* Maintainers: http://www.nslu2-linux.org/
*/
#include <linux/kernel.h>
#include <linux/serial.h>
#include <linux/serial_8250.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <asm/mach/flash.h>
static struct flash_platform_data dsmg600_flash_data = {
.map_name = "cfi_probe",
.width = 2,
};
static struct resource dsmg600_flash_resource = {
.flags = IORESOURCE_MEM,
};
static struct platform_device dsmg600_flash = {
.name = "IXP4XX-Flash",
.id = 0,
.dev.platform_data = &dsmg600_flash_data,
.num_resources = 1,
.resource = &dsmg600_flash_resource,
};
static struct ixp4xx_i2c_pins dsmg600_i2c_gpio_pins = {
.sda_pin = DSMG600_SDA_PIN,
.scl_pin = DSMG600_SCL_PIN,
};
static struct platform_device dsmg600_i2c_controller = {
.name = "IXP4XX-I2C",
.id = 0,
.dev.platform_data = &dsmg600_i2c_gpio_pins,
};
#ifdef CONFIG_LEDS_CLASS
static struct resource dsmg600_led_resources[] = {
{
.name = "power",
.start = DSMG600_LED_PWR_GPIO,
.end = DSMG600_LED_PWR_GPIO,
.flags = IXP4XX_GPIO_HIGH,
},
{
.name = "wlan",
.start = DSMG600_LED_WLAN_GPIO,
.end = DSMG600_LED_WLAN_GPIO,
.flags = IXP4XX_GPIO_LOW,
},
};
static struct platform_device dsmg600_leds = {
.name = "IXP4XX-GPIO-LED",
.id = -1,
.num_resources = ARRAY_SIZE(dsmg600_led_resources),
.resource = dsmg600_led_resources,
};
#endif
static struct resource dsmg600_uart_resources[] = {
{
.start = IXP4XX_UART1_BASE_PHYS,
.end = IXP4XX_UART1_BASE_PHYS + 0x0fff,
.flags = IORESOURCE_MEM,
},
{
.start = IXP4XX_UART2_BASE_PHYS,
.end = IXP4XX_UART2_BASE_PHYS + 0x0fff,
.flags = IORESOURCE_MEM,
}
};
static struct plat_serial8250_port dsmg600_uart_data[] = {
{
.mapbase = IXP4XX_UART1_BASE_PHYS,
.membase = (char *)IXP4XX_UART1_BASE_VIRT + REG_OFFSET,
.irq = IRQ_IXP4XX_UART1,
.flags = UPF_BOOT_AUTOCONF,
.iotype = UPIO_MEM,
.regshift = 2,
.uartclk = IXP4XX_UART_XTAL,
},
{
.mapbase = IXP4XX_UART2_BASE_PHYS,
.membase = (char *)IXP4XX_UART2_BASE_VIRT + REG_OFFSET,
.irq = IRQ_IXP4XX_UART2,
.flags = UPF_BOOT_AUTOCONF,
.iotype = UPIO_MEM,
.regshift = 2,
.uartclk = IXP4XX_UART_XTAL,
},
{ }
};
static struct platform_device dsmg600_uart = {
.name = "serial8250",
.id = PLAT8250_DEV_PLATFORM,
.dev.platform_data = dsmg600_uart_data,
.num_resources = ARRAY_SIZE(dsmg600_uart_resources),
.resource = dsmg600_uart_resources,
};
static struct platform_device *dsmg600_devices[] __initdata = {
&dsmg600_i2c_controller,
&dsmg600_flash,
};
static void dsmg600_power_off(void)
{
/* enable the pwr cntl gpio */
gpio_line_config(DSMG600_PO_GPIO, IXP4XX_GPIO_OUT);
/* poweroff */
gpio_line_set(DSMG600_PO_GPIO, IXP4XX_GPIO_HIGH);
}
static void __init dsmg600_init(void)
{
ixp4xx_sys_init();
/* Make sure that GPIO14 and GPIO15 are not used as clocks */
*IXP4XX_GPIO_GPCLKR = 0;
dsmg600_flash_resource.start = IXP4XX_EXP_BUS_BASE(0);
dsmg600_flash_resource.end =
IXP4XX_EXP_BUS_BASE(0) + ixp4xx_exp_bus_size - 1;
pm_power_off = dsmg600_power_off;
/* The UART is required on the DSM-G600 (Redboot cannot use the
* NIC) -- do it here so that it does *not* get removed if
* platform_add_devices fails!
*/
(void)platform_device_register(&dsmg600_uart);
platform_add_devices(dsmg600_devices, ARRAY_SIZE(dsmg600_devices));
#ifdef CONFIG_LEDS_CLASS
/* We don't care whether or not this works. */
(void)platform_device_register(&dsmg600_leds);
#endif
}
static void __init dsmg600_fixup(struct machine_desc *desc,
struct tag *tags, char **cmdline, struct meminfo *mi)
{
/* The xtal on this machine is non-standard. */
ixp4xx_timer_freq = DSMG600_FREQ;
}
MACHINE_START(DSMG600, "D-Link DSM-G600 RevA")
/* Maintainer: www.nslu2-linux.org */
.phys_io = IXP4XX_PERIPHERAL_BASE_PHYS,
.io_pg_offst = ((IXP4XX_PERIPHERAL_BASE_VIRT) >> 18) & 0xFFFC,
.boot_params = 0x00000100,
.fixup = dsmg600_fixup,
.map_io = ixp4xx_map_io,
.init_irq = ixp4xx_init_irq,
.timer = &ixp4xx_timer,
.init_machine = dsmg600_init,
MACHINE_END
......@@ -66,7 +66,7 @@ struct hw_pci ixdp425_pci __initdata = {
int __init ixdp425_pci_init(void)
{
if (machine_is_ixdp425() || machine_is_ixcdp1100() ||
machine_is_ixdp465())
machine_is_ixdp465() || machine_is_kixrp435())
pci_common_init(&ixdp425_pci);
return 0;
}
......
......@@ -115,6 +115,11 @@ static void __init ixdp425_init(void)
ixdp425_flash_resource.end =
IXP4XX_EXP_BUS_BASE(0) + ixp4xx_exp_bus_size - 1;
if (cpu_is_ixp43x()) {
ixdp425_uart.num_resources = 1;
ixdp425_uart_data[1].flags = 0;
}
platform_add_devices(ixdp425_devices, ARRAY_SIZE(ixdp425_devices));
}
......@@ -156,3 +161,16 @@ MACHINE_START(IXCDP1100, "Intel IXCDP1100 Development Platform")
.init_machine = ixdp425_init,
MACHINE_END
#endif
#ifdef CONFIG_MACH_KIXRP435
MACHINE_START(KIXRP435, "Intel KIXRP435 Reference Platform")
/* Maintainer: MontaVista Software, Inc. */
.phys_io = IXP4XX_PERIPHERAL_BASE_PHYS,
.io_pg_offst = ((IXP4XX_PERIPHERAL_BASE_VIRT) >> 18) & 0xfffc,
.map_io = ixp4xx_map_io,
.init_irq = ixp4xx_init_irq,
.timer = &ixp4xx_timer,
.boot_params = 0x0100,
.init_machine = ixdp425_init,
MACHINE_END
#endif
......@@ -11,7 +11,6 @@
#include <linux/init.h>
#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/ptrace.h>
#include <asm/hardware.h>
#include <asm/irq.h>
......
......@@ -11,7 +11,6 @@
#include <linux/init.h>
#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/ptrace.h>
#include <asm/hardware.h>
#include <asm/irq.h>
......
......@@ -12,7 +12,6 @@
#include <linux/init.h>
#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/ptrace.h>
#include <asm/hardware.h>
#include <asm/irq.h>
......
......@@ -3,19 +3,30 @@ if ARCH_NS9XXX
menu "NS9xxx Implementations"
config MACH_CC9P9360DEV
bool "Connect Core 9P 9360 on an A9M9750 Devboard"
bool "ConnectCore 9P 9360 on an A9M9750 Devboard"
select PROCESSOR_NS9360
select BOARD_A9M9750DEV
help
Say Y here if you are using the Digi Connect Core 9P 9360
Say Y here if you are using the Digi ConnectCore 9P 9360
on an A9M9750 Development Board.
config MACH_CC9P9360JS
bool "ConnectCore 9P 9360 on a JSCC9P9360 Devboard"
select PROCESSOR_NS9360
select BOARD_JSCC9P9360
help
Say Y here if you are using the Digi ConnectCore 9P 9360
on an JSCC9P9360 Development Board.
config PROCESSOR_NS9360
bool
config BOARD_A9M9750DEV
bool
config BOARD_JSCC9P9360
bool
endmenu
endif
......@@ -3,3 +3,4 @@ obj-y := irq.o time.o generic.o
obj-$(CONFIG_MACH_CC9P9360DEV) += mach-cc9p9360dev.o
obj-$(CONFIG_BOARD_A9M9750DEV) += board-a9m9750dev.o
obj-$(CONFIG_BOARD_JSCC9P9360) += board-jscc9p9360.o
/*
* arch/arm/mach-ns9xxx/board-jscc9p9360.c
*
* Copyright (C) 2006,2007 by Digi International Inc.
* All rights reserved.
*
* 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 "board-jscc9p9360.h"
void __init board_jscc9p9360_init_machine(void)
{
/* TODO: reserve GPIOs for push buttons, etc pp */
}
/*
* arch/arm/mach-ns9xxx/board-jscc9p9360.h
*
* Copyright (C) 2006 by Digi International Inc.
* All rights reserved.
*
* 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>
void __init board_jscc9p9360_init_machine(void);
/*
* arch/arm/mach-ns9xxx/mach-cc9p9360js.c
*
* Copyright (C) 2006 by Digi International Inc.
* All rights reserved.
*
* 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 <asm/mach/arch.h>
#include <asm/mach-types.h>
#include "board-jscc9p9360.h"
#include "generic.h"
static void __init mach_cc9p9360js_init_machine(void)
{
ns9xxx_init_machine();
board_jscc9p9360_init_machine();
}
MACHINE_START(CC9P9360DEV, "Digi ConnectCore 9P 9360 on an JSCC9P9360 Devboard")
.map_io = ns9xxx_map_io,
.init_irq = ns9xxx_init_irq,
.init_machine = mach_cc9p9360js_init_machine,
.timer = &ns9xxx_timer,
.boot_params = 0x100,
MACHINE_END
......@@ -40,7 +40,6 @@
#include <linux/module.h>
#include <linux/sched.h>
#include <linux/interrupt.h>
#include <linux/ptrace.h>
#include <asm/hardware.h>
#include <asm/irq.h>
......
......@@ -39,6 +39,10 @@
#include <linux/interrupt.h>
#include <linux/sched.h>
#include <linux/spinlock.h>
#include <linux/clk.h>
#include <linux/err.h>
#include <linux/clocksource.h>
#include <linux/clockchips.h>
#include <asm/system.h>
#include <asm/hardware.h>
......@@ -48,13 +52,7 @@
#include <asm/mach/irq.h>
#include <asm/mach/time.h>
struct sys_timer omap_timer;
/*
* ---------------------------------------------------------------------------
* MPU timer
* ---------------------------------------------------------------------------
*/
#define OMAP_MPU_TIMER_BASE OMAP_MPU_TIMER1_BASE
#define OMAP_MPU_TIMER_OFFSET 0x100
......@@ -88,21 +86,6 @@ static inline unsigned long long cycles_2_ns(unsigned long long cyc)
return (cyc * cyc2ns_scale) >> CYC2NS_SCALE_FACTOR;
}
/*
* MPU_TICKS_PER_SEC must be an even number, otherwise machinecycles_to_usecs
* will break. On P2, the timer count rate is 6.5 MHz after programming PTV
* with 0. This divides the 13MHz input by 2, and is undocumented.
*/
#if defined(CONFIG_MACH_OMAP_PERSEUS2) || defined(CONFIG_MACH_OMAP_FSAMPLE)
/* REVISIT: This ifdef construct should be replaced by a query to clock
* framework to see if timer base frequency is 12.0, 13.0 or 19.2 MHz.
*/
#define MPU_TICKS_PER_SEC (13000000 / 2)
#else
#define MPU_TICKS_PER_SEC (12000000 / 2)
#endif
#define MPU_TIMER_TICK_PERIOD ((MPU_TICKS_PER_SEC / HZ) - 1)
typedef struct {
u32 cntl; /* CNTL_TIMER, R/W */
......@@ -120,98 +103,164 @@ static inline unsigned long omap_mpu_timer_read(int nr)
return timer->read_tim;
}
static inline void omap_mpu_timer_start(int nr, unsigned long load_val)
static inline void omap_mpu_set_autoreset(int nr)
{
volatile omap_mpu_timer_regs_t* timer = omap_mpu_timer_base(nr);
timer->cntl = MPU_TIMER_CLOCK_ENABLE;
udelay(1);
timer->load_tim = load_val;
udelay(1);
timer->cntl = (MPU_TIMER_CLOCK_ENABLE | MPU_TIMER_AR | MPU_TIMER_ST);
timer->cntl = timer->cntl | MPU_TIMER_AR;
}
unsigned long omap_mpu_timer_ticks_to_usecs(unsigned long nr_ticks)
static inline void omap_mpu_remove_autoreset(int nr)
{
unsigned long long nsec;
volatile omap_mpu_timer_regs_t* timer = omap_mpu_timer_base(nr);
nsec = cycles_2_ns((unsigned long long)nr_ticks);
return (unsigned long)nsec / 1000;
timer->cntl = timer->cntl & ~MPU_TIMER_AR;
}
/*
* Last processed system timer interrupt
*/
static unsigned long omap_mpu_timer_last = 0;
static inline void omap_mpu_timer_start(int nr, unsigned long load_val,
int autoreset)
{
volatile omap_mpu_timer_regs_t* timer = omap_mpu_timer_base(nr);
unsigned int timerflags = (MPU_TIMER_CLOCK_ENABLE | MPU_TIMER_ST);
if (autoreset) timerflags |= MPU_TIMER_AR;
timer->cntl = MPU_TIMER_CLOCK_ENABLE;
udelay(1);
timer->load_tim = load_val;
udelay(1);
timer->cntl = timerflags;
}
/*
* Returns elapsed usecs since last system timer interrupt
* ---------------------------------------------------------------------------
* MPU timer 1 ... count down to zero, interrupt, reload
* ---------------------------------------------------------------------------
*/
static unsigned long omap_mpu_timer_gettimeoffset(void)
static int omap_mpu_set_next_event(unsigned long cycles,
struct clock_event_device *evt)
{
unsigned long now = 0 - omap_mpu_timer_read(0);
unsigned long elapsed = now - omap_mpu_timer_last;
omap_mpu_timer_start(0, cycles, 0);
return 0;
}
return omap_mpu_timer_ticks_to_usecs(elapsed);
static void omap_mpu_set_mode(enum clock_event_mode mode,
struct clock_event_device *evt)
{
switch (mode) {
case CLOCK_EVT_MODE_PERIODIC:
omap_mpu_set_autoreset(0);
break;
case CLOCK_EVT_MODE_ONESHOT:
omap_mpu_remove_autoreset(0);
break;
case CLOCK_EVT_MODE_UNUSED:
case CLOCK_EVT_MODE_SHUTDOWN:
break;
}
}
/*
* Elapsed time between interrupts is calculated using timer0.
* Latency during the interrupt is calculated using timer1.
* Both timer0 and timer1 are counting at 6MHz (P2 6.5MHz).
*/
static irqreturn_t omap_mpu_timer_interrupt(int irq, void *dev_id)
static struct clock_event_device clockevent_mpu_timer1 = {
.name = "mpu_timer1",
.features = CLOCK_EVT_FEAT_PERIODIC, CLOCK_EVT_FEAT_ONESHOT,
.shift = 32,
.set_next_event = omap_mpu_set_next_event,
.set_mode = omap_mpu_set_mode,
};
static irqreturn_t omap_mpu_timer1_interrupt(int irq, void *dev_id)
{
unsigned long now, latency;
struct clock_event_device *evt = &clockevent_mpu_timer1;
write_seqlock(&xtime_lock);
now = 0 - omap_mpu_timer_read(0);
latency = MPU_TICKS_PER_SEC / HZ - omap_mpu_timer_read(1);
omap_mpu_timer_last = now - latency;
timer_tick();
write_sequnlock(&xtime_lock);
evt->event_handler(evt);
return IRQ_HANDLED;
}
static struct irqaction omap_mpu_timer_irq = {
.name = "mpu timer",
static struct irqaction omap_mpu_timer1_irq = {
.name = "mpu_timer1",
.flags = IRQF_DISABLED | IRQF_TIMER,
.handler = omap_mpu_timer_interrupt,
.handler = omap_mpu_timer1_interrupt,
};
static unsigned long omap_mpu_timer1_overflows;
static irqreturn_t omap_mpu_timer1_interrupt(int irq, void *dev_id)
static __init void omap_init_mpu_timer(unsigned long rate)
{
set_cyc2ns_scale(rate / 1000);
setup_irq(INT_TIMER1, &omap_mpu_timer1_irq);
omap_mpu_timer_start(0, (rate / HZ) - 1, 1);
clockevent_mpu_timer1.mult = div_sc(rate, NSEC_PER_SEC,
clockevent_mpu_timer1.shift);
clockevent_mpu_timer1.max_delta_ns =
clockevent_delta2ns(-1, &clockevent_mpu_timer1);
clockevent_mpu_timer1.min_delta_ns =
clockevent_delta2ns(1, &clockevent_mpu_timer1);
clockevent_mpu_timer1.cpumask = cpumask_of_cpu(0);
clockevents_register_device(&clockevent_mpu_timer1);
}
/*
* ---------------------------------------------------------------------------
* MPU timer 2 ... free running 32-bit clock source and scheduler clock
* ---------------------------------------------------------------------------
*/
static unsigned long omap_mpu_timer2_overflows;
static irqreturn_t omap_mpu_timer2_interrupt(int irq, void *dev_id)
{
omap_mpu_timer1_overflows++;
omap_mpu_timer2_overflows++;
return IRQ_HANDLED;
}
static struct irqaction omap_mpu_timer1_irq = {
.name = "mpu timer1 overflow",
static struct irqaction omap_mpu_timer2_irq = {
.name = "mpu_timer2",
.flags = IRQF_DISABLED,
.handler = omap_mpu_timer1_interrupt,
.handler = omap_mpu_timer2_interrupt,
};
static __init void omap_init_mpu_timer(void)
static cycle_t mpu_read(void)
{
set_cyc2ns_scale(MPU_TICKS_PER_SEC / 1000);
omap_timer.offset = omap_mpu_timer_gettimeoffset;
setup_irq(INT_TIMER1, &omap_mpu_timer1_irq);
setup_irq(INT_TIMER2, &omap_mpu_timer_irq);
omap_mpu_timer_start(0, 0xffffffff);
omap_mpu_timer_start(1, MPU_TIMER_TICK_PERIOD);
return ~omap_mpu_timer_read(1);
}
static struct clocksource clocksource_mpu = {
.name = "mpu_timer2",
.rating = 300,
.read = mpu_read,
.mask = CLOCKSOURCE_MASK(32),
.shift = 24,
.flags = CLOCK_SOURCE_IS_CONTINUOUS,
};
static void __init omap_init_clocksource(unsigned long rate)
{
static char err[] __initdata = KERN_ERR
"%s: can't register clocksource!\n";
clocksource_mpu.mult
= clocksource_khz2mult(rate/1000, clocksource_mpu.shift);
setup_irq(INT_TIMER2, &omap_mpu_timer2_irq);
omap_mpu_timer_start(1, ~0, 1);
if (clocksource_register(&clocksource_mpu))
printk(err, clocksource_mpu.name);
}
/*
* Scheduler clock - returns current time in nanosec units.
*/
unsigned long long sched_clock(void)
{
unsigned long ticks = 0 - omap_mpu_timer_read(0);
unsigned long ticks = 0 - omap_mpu_timer_read(1);
unsigned long long ticks64;
ticks64 = omap_mpu_timer1_overflows;
ticks64 = omap_mpu_timer2_overflows;
ticks64 <<= 32;
ticks64 |= ticks;
......@@ -225,10 +274,21 @@ unsigned long long sched_clock(void)
*/
static void __init omap_timer_init(void)
{
omap_init_mpu_timer();
struct clk *ck_ref = clk_get(NULL, "ck_ref");
unsigned long rate;
BUG_ON(IS_ERR(ck_ref));
rate = clk_get_rate(ck_ref);
clk_put(ck_ref);
/* PTV = 0 */
rate /= 2;
omap_init_mpu_timer(rate);
omap_init_clocksource(rate);
}
struct sys_timer omap_timer = {
.init = omap_timer_init,
.offset = NULL, /* Initialized later */
};
......@@ -164,9 +164,9 @@ void pxa_set_cken(int clock, int enable)
local_irq_save(flags);
if (enable)
CKEN |= clock;
CKEN |= (1 << clock);
else
CKEN &= ~clock;
CKEN &= ~(1 << clock);
local_irq_restore(flags);
}
......
......@@ -15,7 +15,6 @@
#include <linux/init.h>
#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/ptrace.h>
#include <asm/hardware.h>
#include <asm/irq.h>
......@@ -39,11 +38,33 @@ static void pxa_unmask_low_irq(unsigned int irq)
ICMR |= (1 << (irq + PXA_IRQ_SKIP));
}
static int pxa_set_wake(unsigned int irq, unsigned int on)
{
u32 mask;
switch (irq) {
case IRQ_RTCAlrm:
mask = PWER_RTC;
break;
#ifdef CONFIG_PXA27x
/* REVISIT can handle USBH1, USBH2, USB, MSL, USIM, ... */
#endif
default:
return -EINVAL;
}
if (on)
PWER |= mask;
else
PWER &= ~mask;
return 0;
}
static struct irq_chip pxa_internal_chip_low = {
.name = "SC",
.ack = pxa_mask_low_irq,
.mask = pxa_mask_low_irq,
.unmask = pxa_unmask_low_irq,
.set_wake = pxa_set_wake,
};
#if PXA_INTERNAL_IRQS > 32
......@@ -71,6 +92,26 @@ static struct irq_chip pxa_internal_chip_high = {
#endif
/* Note that if an input/irq line ever gets changed to an output during
* suspend, the relevant PWER, PRER, and PFER bits should be cleared.
*/
#ifdef CONFIG_PXA27x
/* PXA27x: Various gpios can issue wakeup events. This logic only
* handles the simple cases, not the WEMUX2 and WEMUX3 options
*/
#define PXA27x_GPIO_NOWAKE_MASK \
((1 << 8) | (1 << 7) | (1 << 6) | (1 << 5) | (1 << 2))
#define WAKEMASK(gpio) \
(((gpio) <= 15) \
? ((1 << (gpio)) & ~PXA27x_GPIO_NOWAKE_MASK) \
: ((gpio == 35) ? (1 << 24) : 0))
#else
/* pxa 210, 250, 255, 26x: gpios 0..15 can issue wakeups */
#define WAKEMASK(gpio) (((gpio) <= 15) ? (1 << (gpio)) : 0)
#endif
/*
* PXA GPIO edge detection for IRQs:
* IRQs are generated on Falling-Edge, Rising-Edge, or both.
......@@ -84,9 +125,11 @@ static long GPIO_IRQ_mask[4];
static int pxa_gpio_irq_type(unsigned int irq, unsigned int type)
{
int gpio, idx;
u32 mask;
gpio = IRQ_TO_GPIO(irq);
idx = gpio >> 5;
mask = WAKEMASK(gpio);
if (type == IRQT_PROBE) {
/* Don't mess with enabled GPIOs using preconfigured edges or
......@@ -106,14 +149,20 @@ static int pxa_gpio_irq_type(unsigned int irq, unsigned int type)
if (type & __IRQT_RISEDGE) {
/* printk("rising "); */
__set_bit (gpio, GPIO_IRQ_rising_edge);
} else
PRER |= mask;
} else {
__clear_bit (gpio, GPIO_IRQ_rising_edge);
PRER &= ~mask;
}
if (type & __IRQT_FALEDGE) {
/* printk("falling "); */
__set_bit (gpio, GPIO_IRQ_falling_edge);
} else
PFER |= mask;
} else {
__clear_bit (gpio, GPIO_IRQ_falling_edge);
PFER &= ~mask;
}
/* printk("edges\n"); */
......@@ -131,12 +180,29 @@ static void pxa_ack_low_gpio(unsigned int irq)
GEDR0 = (1 << (irq - IRQ_GPIO0));
}
static int pxa_set_gpio_wake(unsigned int irq, unsigned int on)
{
int gpio = IRQ_TO_GPIO(irq);
u32 mask = WAKEMASK(gpio);
if (!mask)
return -EINVAL;
if (on)
PWER |= mask;
else
PWER &= ~mask;
return 0;
}
static struct irq_chip pxa_low_gpio_chip = {
.name = "GPIO-l",
.ack = pxa_ack_low_gpio,
.mask = pxa_mask_low_irq,
.unmask = pxa_unmask_low_irq,
.set_type = pxa_gpio_irq_type,
.set_wake = pxa_set_gpio_wake,
};
/*
......@@ -245,6 +311,7 @@ static struct irq_chip pxa_muxed_gpio_chip = {
.mask = pxa_mask_muxed_gpio,
.unmask = pxa_unmask_muxed_gpio,
.set_type = pxa_gpio_irq_type,
.set_wake = pxa_set_gpio_wake,
};
......
......@@ -234,7 +234,7 @@ static void lpd270_backlight_power(int on)
{
if (on) {
pxa_gpio_mode(GPIO16_PWM0_MD);
pxa_set_cken(CKEN0_PWM0, 1);
pxa_set_cken(CKEN_PWM0, 1);
PWM_CTRL0 = 0;
PWM_PWDUTY0 = 0x3ff;
PWM_PERVAL0 = 0x3ff;
......@@ -242,7 +242,7 @@ static void lpd270_backlight_power(int on)
PWM_CTRL0 = 0;
PWM_PWDUTY0 = 0x0;
PWM_PERVAL0 = 0x3FF;
pxa_set_cken(CKEN0_PWM0, 0);
pxa_set_cken(CKEN_PWM0, 0);
}
}
......
......@@ -220,7 +220,7 @@ static struct resource pxa_ssp_resources[] = {
static struct pxa2xx_spi_master pxa_ssp_master_info = {
.ssp_type = PXA25x_SSP,
.clock_enable = CKEN3_SSP,
.clock_enable = CKEN_SSP,
.num_chipselect = 0,
};
......
......@@ -266,7 +266,7 @@ static void mainstone_backlight_power(int on)
{
if (on) {
pxa_gpio_mode(GPIO16_PWM0_MD);
pxa_set_cken(CKEN0_PWM0, 1);
pxa_set_cken(CKEN_PWM0, 1);
PWM_CTRL0 = 0;
PWM_PWDUTY0 = 0x3ff;
PWM_PERVAL0 = 0x3ff;
......@@ -274,7 +274,7 @@ static void mainstone_backlight_power(int on)
PWM_CTRL0 = 0;
PWM_PWDUTY0 = 0x0;
PWM_PERVAL0 = 0x3FF;
pxa_set_cken(CKEN0_PWM0, 0);
pxa_set_cken(CKEN_PWM0, 0);
}
}
......
......@@ -140,9 +140,9 @@ void pxa_cpu_pm_enter(suspend_state_t state)
extern void pxa_cpu_resume(void);
if (state == PM_SUSPEND_STANDBY)
CKEN = CKEN22_MEMC | CKEN9_OSTIMER | CKEN16_LCD |CKEN0_PWM0;
CKEN = CKEN_MEMC | CKEN_OSTIMER | CKEN_LCD | CKEN_PWM0;
else
CKEN = CKEN22_MEMC | CKEN9_OSTIMER;
CKEN = CKEN_MEMC | CKEN_OSTIMER;
/* ensure voltage-change sequencer not initiated, which hangs */
PCFR &= ~PCFR_FVC;
......
......@@ -52,13 +52,13 @@ struct ssp_info_ {
*/
static const struct ssp_info_ ssp_info[PXA_SSP_PORTS] = {
#if defined (CONFIG_PXA27x)
{IRQ_SSP, CKEN23_SSP1},
{IRQ_SSP2, CKEN3_SSP2},
{IRQ_SSP3, CKEN4_SSP3},
{IRQ_SSP, CKEN_SSP1},
{IRQ_SSP2, CKEN_SSP2},
{IRQ_SSP3, CKEN_SSP3},
#else
{IRQ_SSP, CKEN3_SSP},
{IRQ_NSSP, CKEN9_NSSP},
{IRQ_ASSP, CKEN10_ASSP},
{IRQ_SSP, CKEN_SSP},
{IRQ_NSSP, CKEN_NSSP},
{IRQ_ASSP, CKEN_ASSP},
#endif
};
......
This diff is collapsed.
......@@ -24,7 +24,6 @@
#include <linux/init.h>
#include <linux/module.h>
#include <linux/ioport.h>
#include <linux/ptrace.h>
#include <linux/sysdev.h>
#include <asm/mach-types.h>
......
......@@ -23,7 +23,6 @@
#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/ioport.h>
#include <linux/ptrace.h>
#include <linux/sysdev.h>
#include <asm/plat-s3c24xx/cpu.h>
......
......@@ -160,17 +160,11 @@ static struct platform_device *amlm5900_devices[] __initdata = {
#endif
};
static struct s3c24xx_board amlm5900_board __initdata = {
.devices = amlm5900_devices,
.devices_count = ARRAY_SIZE(amlm5900_devices)
};
void __init amlm5900_map_io(void)
{
s3c24xx_init_io(amlm5900_iodesc, ARRAY_SIZE(amlm5900_iodesc));
s3c24xx_init_clocks(0);
s3c24xx_init_uarts(amlm5900_uartcfgs, ARRAY_SIZE(amlm5900_uartcfgs));
s3c24xx_set_board(&amlm5900_board);
}
#ifdef CONFIG_FB_S3C2410
......@@ -247,6 +241,7 @@ static void __init amlm5900_init(void)
#ifdef CONFIG_FB_S3C2410
s3c24xx_fb_set_platdata(&amlm5900_lcd_info);
#endif
platform_add_devices(amlm5900_devices, ARRAY_SIZE(amlm5900_devices));
}
MACHINE_START(AML_M5900, "AML_M5900")
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment