提交 6f95416e 编写于 作者: R Russell King 提交者: Russell King

Merge branches 'arm-mm', 'at91', 'clkevts', 'imx', 'iop', 'misc', 'netx',...

Merge branches 'arm-mm', 'at91', 'clkevts', 'imx', 'iop', 'misc', 'netx', 'ns9xxx', 'omap', 'pxa', 'rpc', 's3c' and 'sa1100' into devel
......@@ -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.
......@@ -262,6 +276,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.
......@@ -363,6 +378,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).
......@@ -513,6 +529,8 @@ endmenu
menu "Kernel Features"
source "kernel/time/Kconfig"
config SMP
bool "Symmetric Multi-Processing (EXPERIMENTAL)"
depends on EXPERIMENTAL && REALVIEW_MPCORE
......@@ -572,6 +590,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
......@@ -669,6 +688,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)
......
此差异已折叠。
......@@ -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,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>
......@@ -159,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();
......
......@@ -779,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
......@@ -817,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 */
......@@ -834,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;
}
#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);
......
......@@ -286,6 +286,7 @@ asmlinkage void __exception do_undefinstr(struct pt_regs *regs)
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,
......@@ -304,7 +305,7 @@ asmlinkage void __exception 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) {
......@@ -314,7 +315,7 @@ asmlinkage void __exception 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) {
......
......@@ -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")
......
......@@ -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,
......
......@@ -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
......@@ -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 = {
......
......@@ -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;
......
......@@ -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
......@@ -239,52 +242,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 +375,9 @@ void __init ixp4xx_sys_init(void)
ixp4xx_exp_bus_size >> 20);
}
/*
* clocksource
*/
cycle_t ixp4xx_get_cycles(void)
{
return *IXP4XX_OSTS;
......@@ -408,3 +402,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;
}
......@@ -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
......@@ -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);
}
......
......@@ -38,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
......@@ -70,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.
......@@ -83,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
......@@ -105,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"); */
......@@ -130,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,
};
/*
......@@ -244,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
};
......
......@@ -17,6 +17,7 @@
#include <linux/sched.h>
#include <linux/device.h>
#include <linux/serial_8250.h>
#include <linux/pata_platform.h>
#include <asm/elf.h>
#include <asm/io.h>
......@@ -159,11 +160,45 @@ static struct platform_device serial_device = {
},
};
static struct pata_platform_info pata_platform_data = {
.ioport_shift = 2,
};
static struct resource pata_resources[] = {
[0] = {
.start = 0x030107c0,
.end = 0x030107df,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = 0x03010fd8,
.end = 0x03010fdb,
.flags = IORESOURCE_MEM,
},
[2] = {
.start = IRQ_HARDDISK,
.end = IRQ_HARDDISK,
.flags = IORESOURCE_IRQ,
},
};
static struct platform_device pata_device = {
.name = "pata_platform",
.id = -1,
.num_resources = ARRAY_SIZE(pata_resources),
.resource = pata_resources,
.dev = {
.platform_data = &pata_platform_data,
.coherent_dma_mask = ~0, /* grumble */
},
};
static struct platform_device *devs[] __initdata = {
&iomd_device,
&kbd_device,
&serial_device,
&acornfb_device,
&pata_device,
};
static int __init rpc_init(void)
......
......@@ -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")
......
......@@ -464,13 +464,6 @@ static struct clk *bast_clocks[] = {
&s3c24xx_uclk,
};
static struct s3c24xx_board bast_board __initdata = {
.devices = bast_devices,
.devices_count = ARRAY_SIZE(bast_devices),
.clocks = bast_clocks,
.clocks_count = ARRAY_SIZE(bast_clocks),
};
static void __init bast_map_io(void)
{
/* initialise the clocks */
......@@ -486,19 +479,22 @@ static void __init bast_map_io(void)
s3c24xx_uclk.parent = &s3c24xx_clkout1;
s3c24xx_register_clocks(bast_clocks, ARRAY_SIZE(bast_clocks));
s3c_device_nand.dev.platform_data = &bast_nand_info;
s3c_device_i2c.dev.platform_data = &bast_i2c_info;
s3c24xx_init_io(bast_iodesc, ARRAY_SIZE(bast_iodesc));
s3c24xx_init_clocks(0);
s3c24xx_init_uarts(bast_uartcfgs, ARRAY_SIZE(bast_uartcfgs));
s3c24xx_set_board(&bast_board);
usb_simtec_init();
}
static void __init bast_init(void)
{
s3c24xx_fb_set_platdata(&bast_lcd_info);
platform_add_devices(bast_devices, ARRAY_SIZE(bast_devices));
}
MACHINE_START(BAST, "Simtec-BAST")
......
......@@ -129,7 +129,6 @@ static struct s3c2410_udc_mach_info h1940_udc_cfg __initdata = {
};
/**
* Set lcd on or off
**/
......@@ -188,17 +187,11 @@ static struct platform_device *h1940_devices[] __initdata = {
&s3c_device_leds,
};
static struct s3c24xx_board h1940_board __initdata = {
.devices = h1940_devices,
.devices_count = ARRAY_SIZE(h1940_devices)
};
static void __init h1940_map_io(void)
{
s3c24xx_init_io(h1940_iodesc, ARRAY_SIZE(h1940_iodesc));
s3c24xx_init_clocks(0);
s3c24xx_init_uarts(h1940_uartcfgs, ARRAY_SIZE(h1940_uartcfgs));
s3c24xx_set_board(&h1940_board);
/* setup PM */
......@@ -232,6 +225,8 @@ static void __init h1940_init(void)
| (0x02 << S3C2410_PLLCON_PDIVSHIFT)
| (0x03 << S3C2410_PLLCON_SDIVSHIFT);
writel(tmp, S3C2410_UPLLCON);
platform_add_devices(h1940_devices, ARRAY_SIZE(h1940_devices));
}
MACHINE_START(H1940, "IPAQ-H1940")
......
......@@ -90,17 +90,11 @@ static struct s3c2410_platform_i2c n30_i2ccfg = {
.max_freq = 10*1000,
};
static struct s3c24xx_board n30_board __initdata = {
.devices = n30_devices,
.devices_count = ARRAY_SIZE(n30_devices)
};
static void __init n30_map_io(void)
{
s3c24xx_init_io(n30_iodesc, ARRAY_SIZE(n30_iodesc));
s3c24xx_init_clocks(0);
s3c24xx_init_uarts(n30_uartcfgs, ARRAY_SIZE(n30_uartcfgs));
s3c24xx_set_board(&n30_board);
}
static void __init n30_init_irq(void)
......@@ -120,6 +114,8 @@ static void __init n30_init(void)
s3c2410_modify_misccr(S3C2410_MISCCR_USBHOST |
S3C2410_MISCCR_USBSUSPND0 |
S3C2410_MISCCR_USBSUSPND1, 0x0);
platform_add_devices(n30_devices, ARRAY_SIZE(n30_devices));
}
MACHINE_START(N30, "Acer-N30")
......
......@@ -100,20 +100,17 @@ static struct platform_device *otom11_devices[] __initdata = {
&otom_device_nor,
};
static struct s3c24xx_board otom11_board __initdata = {
.devices = otom11_devices,
.devices_count = ARRAY_SIZE(otom11_devices)
};
static void __init otom11_map_io(void)
{
s3c24xx_init_io(otom11_iodesc, ARRAY_SIZE(otom11_iodesc));
s3c24xx_init_clocks(0);
s3c24xx_init_uarts(otom11_uartcfgs, ARRAY_SIZE(otom11_uartcfgs));
s3c24xx_set_board(&otom11_board);
}
static void __init otom11_init(void)
{
platform_add_devices(otom11_devices, ARRAY_SIZE(otom11_devices));
}
MACHINE_START(OTOM, "Nex Vision - Otom 1.1")
/* Maintainer: Guillaume GOURAT <guillaume.gourat@nexvision.tv> */
......@@ -121,6 +118,7 @@ MACHINE_START(OTOM, "Nex Vision - Otom 1.1")
.io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
.boot_params = S3C2410_SDRAM_PA + 0x100,
.map_io = otom11_map_io,
.init_machine = otom11_init,
.init_irq = s3c24xx_init_irq,
.timer = &s3c24xx_timer,
MACHINE_END
......@@ -29,7 +29,6 @@
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/serial_core.h>
#include <linux/mmc/protocol.h>
#include <linux/spi/spi.h>
#include <linux/spi/spi_bitbang.h>
......@@ -331,11 +330,6 @@ static struct platform_device *qt2410_devices[] __initdata = {
&qt2410_led,
};
static struct s3c24xx_board qt2410_board __initdata = {
.devices = qt2410_devices,
.devices_count = ARRAY_SIZE(qt2410_devices)
};
static struct mtd_partition qt2410_nand_part[] = {
[0] = {
.name = "U-Boot",
......@@ -405,7 +399,6 @@ static void __init qt2410_map_io(void)
s3c24xx_init_io(qt2410_iodesc, ARRAY_SIZE(qt2410_iodesc));
s3c24xx_init_clocks(12*1000*1000);
s3c24xx_init_uarts(smdk2410_uartcfgs, ARRAY_SIZE(smdk2410_uartcfgs));
s3c24xx_set_board(&qt2410_board);
}
static void __init qt2410_machine_init(void)
......@@ -432,6 +425,7 @@ static void __init qt2410_machine_init(void)
s3c2410_gpio_cfgpin(S3C2410_GPB5, S3C2410_GPIO_OUTPUT);
platform_add_devices(qt2410_devices, ARRAY_SIZE(qt2410_devices));
s3c2410_pm_init();
}
......
......@@ -94,17 +94,17 @@ static struct platform_device *smdk2410_devices[] __initdata = {
&s3c_device_iis,
};
static struct s3c24xx_board smdk2410_board __initdata = {
.devices = smdk2410_devices,
.devices_count = ARRAY_SIZE(smdk2410_devices)
};
static void __init smdk2410_map_io(void)
{
s3c24xx_init_io(smdk2410_iodesc, ARRAY_SIZE(smdk2410_iodesc));
s3c24xx_init_clocks(0);
s3c24xx_init_uarts(smdk2410_uartcfgs, ARRAY_SIZE(smdk2410_uartcfgs));
s3c24xx_set_board(&smdk2410_board);
}
static void __init smdk2410_init(void)
{
platform_add_devices(smdk2410_devices, ARRAY_SIZE(smdk2410_devices));
smdk_machine_init();
}
MACHINE_START(SMDK2410, "SMDK2410") /* @TODO: request a new identifier and switch
......@@ -115,7 +115,7 @@ MACHINE_START(SMDK2410, "SMDK2410") /* @TODO: request a new identifier and switc
.boot_params = S3C2410_SDRAM_PA + 0x100,
.map_io = smdk2410_map_io,
.init_irq = s3c24xx_init_irq,
.init_machine = smdk_machine_init,
.init_machine = smdk2410_init,
.timer = &s3c24xx_timer,
MACHINE_END
......
......@@ -384,13 +384,6 @@ static struct clk *vr1000_clocks[] = {
&s3c24xx_uclk,
};
static struct s3c24xx_board vr1000_board __initdata = {
.devices = vr1000_devices,
.devices_count = ARRAY_SIZE(vr1000_devices),
.clocks = vr1000_clocks,
.clocks_count = ARRAY_SIZE(vr1000_clocks),
};
static void vr1000_power_off(void)
{
s3c2410_gpio_cfgpin(S3C2410_GPB9, S3C2410_GPB9_OUTP);
......@@ -412,15 +405,19 @@ static void __init vr1000_map_io(void)
s3c24xx_uclk.parent = &s3c24xx_clkout1;
s3c24xx_register_clocks(vr1000_clocks, ARRAY_SIZE(vr1000_clocks));
pm_power_off = vr1000_power_off;
s3c24xx_init_io(vr1000_iodesc, ARRAY_SIZE(vr1000_iodesc));
s3c24xx_init_clocks(0);
s3c24xx_init_uarts(vr1000_uartcfgs, ARRAY_SIZE(vr1000_uartcfgs));
s3c24xx_set_board(&vr1000_board);
usb_simtec_init();
}
static void __init vr1000_init(void)
{
platform_add_devices(vr1000_devices, ARRAY_SIZE(vr1000_devices));
}
MACHINE_START(VR1000, "Thorcom-VR1000")
/* Maintainer: Ben Dooks <ben@simtec.co.uk> */
......@@ -428,6 +425,7 @@ MACHINE_START(VR1000, "Thorcom-VR1000")
.io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
.boot_params = S3C2410_SDRAM_PA + 0x100,
.map_io = vr1000_map_io,
.init_machine = vr1000_init,
.init_irq = s3c24xx_init_irq,
.timer = &s3c24xx_timer,
MACHINE_END
......@@ -47,6 +47,15 @@ config MACH_S3C2413
machine_is_s3c2413() will work when MACH_SMDK2413 is
selected
config MACH_SMDK2412
bool "SMDK2412"
select MACH_SMDK2413
help
Say Y here if you are using an SMDK2412
Note, this shares support with SMDK2413, so will automatically
select MACH_SMDK2413.
config MACH_VSTMS
bool "VMSTMS"
select CPU_S3C2412
......
......@@ -110,11 +110,6 @@ static struct platform_device *smdk2413_devices[] __initdata = {
&s3c_device_usbgadget,
};
static struct s3c24xx_board smdk2413_board __initdata = {
.devices = smdk2413_devices,
.devices_count = ARRAY_SIZE(smdk2413_devices)
};
static void __init smdk2413_fixup(struct machine_desc *desc,
struct tag *tags, char **cmdline,
struct meminfo *mi)
......@@ -132,7 +127,6 @@ static void __init smdk2413_map_io(void)
s3c24xx_init_io(smdk2413_iodesc, ARRAY_SIZE(smdk2413_iodesc));
s3c24xx_init_clocks(12000000);
s3c24xx_init_uarts(smdk2413_uartcfgs, ARRAY_SIZE(smdk2413_uartcfgs));
s3c24xx_set_board(&smdk2413_board);
}
static void __init smdk2413_machine_init(void)
......@@ -149,6 +143,7 @@ static void __init smdk2413_machine_init(void)
s3c24xx_udc_set_platdata(&smdk2413_udc_cfg);
platform_add_devices(smdk2413_devices, ARRAY_SIZE(smdk2413_devices));
smdk_machine_init();
}
......
......@@ -129,11 +129,6 @@ static struct platform_device *vstms_devices[] __initdata = {
&s3c_device_nand,
};
static struct s3c24xx_board vstms_board __initdata = {
.devices = vstms_devices,
.devices_count = ARRAY_SIZE(vstms_devices)
};
static void __init vstms_fixup(struct machine_desc *desc,
struct tag *tags, char **cmdline,
struct meminfo *mi)
......@@ -153,7 +148,11 @@ static void __init vstms_map_io(void)
s3c24xx_init_io(vstms_iodesc, ARRAY_SIZE(vstms_iodesc));
s3c24xx_init_clocks(12000000);
s3c24xx_init_uarts(vstms_uartcfgs, ARRAY_SIZE(vstms_uartcfgs));
s3c24xx_set_board(&vstms_board);
}
static void __init vstms_init(void)
{
platform_add_devices(vstms_devices, ARRAY_SIZE(vstms_devices));
}
MACHINE_START(VSTMS, "VSTMS")
......@@ -163,6 +162,7 @@ MACHINE_START(VSTMS, "VSTMS")
.fixup = vstms_fixup,
.init_irq = s3c24xx_init_irq,
.init_machine = vstms_init,
.map_io = vstms_map_io,
.timer = &s3c24xx_timer,
MACHINE_END
......@@ -281,13 +281,6 @@ static struct clk *anubis_clocks[] = {
&s3c24xx_uclk,
};
static struct s3c24xx_board anubis_board __initdata = {
.devices = anubis_devices,
.devices_count = ARRAY_SIZE(anubis_devices),
.clocks = anubis_clocks,
.clocks_count = ARRAY_SIZE(anubis_clocks),
};
static void __init anubis_map_io(void)
{
/* initialise the clocks */
......@@ -303,23 +296,31 @@ static void __init anubis_map_io(void)
s3c24xx_uclk.parent = &s3c24xx_clkout1;
s3c24xx_register_clocks(anubis_clocks, ARRAY_SIZE(anubis_clocks));
s3c_device_nand.dev.platform_data = &anubis_nand_info;
s3c24xx_init_io(anubis_iodesc, ARRAY_SIZE(anubis_iodesc));
s3c24xx_init_clocks(0);
s3c24xx_init_uarts(anubis_uartcfgs, ARRAY_SIZE(anubis_uartcfgs));
s3c24xx_set_board(&anubis_board);
/* ensure that the GPIO is setup */
s3c2410_gpio_setpin(S3C2410_GPA0, 1);
}
static void __init anubis_init(void)
{
platform_add_devices(anubis_devices, ARRAY_SIZE(anubis_devices));
}
MACHINE_START(ANUBIS, "Simtec-Anubis")
/* Maintainer: Ben Dooks <ben@simtec.co.uk> */
.phys_io = S3C2410_PA_UART,
.io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
.boot_params = S3C2410_SDRAM_PA + 0x100,
.map_io = anubis_map_io,
.init_machine = anubis_init,
.init_irq = s3c24xx_init_irq,
.timer = &s3c24xx_timer,
MACHINE_END
......@@ -116,12 +116,6 @@ static struct platform_device *nexcoder_devices[] __initdata = {
&nexcoder_device_nor,
};
static struct s3c24xx_board nexcoder_board __initdata = {
.devices = nexcoder_devices,
.devices_count = ARRAY_SIZE(nexcoder_devices),
};
static void __init nexcoder_sensorboard_init(void)
{
// Initialize SCCB bus
......@@ -142,10 +136,14 @@ static void __init nexcoder_map_io(void)
s3c24xx_init_io(nexcoder_iodesc, ARRAY_SIZE(nexcoder_iodesc));
s3c24xx_init_clocks(0);
s3c24xx_init_uarts(nexcoder_uartcfgs, ARRAY_SIZE(nexcoder_uartcfgs));
s3c24xx_set_board(&nexcoder_board);
nexcoder_sensorboard_init();
}
static void __init nexcoder_init(void)
{
platform_add_devices(nexcoder_devices, ARRAY_SIZE(nexcoder_devices));
};
MACHINE_START(NEXCODER_2440, "NexVision - Nexcoder 2440")
/* Maintainer: Guillaume GOURAT <guillaume.gourat@nexvision.tv> */
......@@ -153,6 +151,7 @@ MACHINE_START(NEXCODER_2440, "NexVision - Nexcoder 2440")
.io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
.boot_params = S3C2410_SDRAM_PA + 0x100,
.map_io = nexcoder_map_io,
.init_machine = nexcoder_init,
.init_irq = s3c24xx_init_irq,
.timer = &s3c24xx_timer,
MACHINE_END
......@@ -251,13 +251,6 @@ static struct clk *osiris_clocks[] = {
&s3c24xx_uclk,
};
static struct s3c24xx_board osiris_board __initdata = {
.devices = osiris_devices,
.devices_count = ARRAY_SIZE(osiris_devices),
.clocks = osiris_clocks,
.clocks_count = ARRAY_SIZE(osiris_clocks),
};
static void __init osiris_map_io(void)
{
unsigned long flags;
......@@ -275,12 +268,13 @@ static void __init osiris_map_io(void)
s3c24xx_uclk.parent = &s3c24xx_clkout1;
s3c24xx_register_clocks(osiris_clocks, ARRAY_SIZE(osiris_clocks));
s3c_device_nand.dev.platform_data = &osiris_nand_info;
s3c24xx_init_io(osiris_iodesc, ARRAY_SIZE(osiris_iodesc));
s3c24xx_init_clocks(0);
s3c24xx_init_uarts(osiris_uartcfgs, ARRAY_SIZE(osiris_uartcfgs));
s3c24xx_set_board(&osiris_board);
/* fix bus configuration (nBE settings wrong on ABLE pre v2.20) */
......@@ -292,12 +286,18 @@ static void __init osiris_map_io(void)
s3c2410_gpio_setpin(S3C2410_GPA0, 1);
}
static void __init osiris_init(void)
{
platform_add_devices(osiris_devices, ARRAY_SIZE(osiris_devices));
};
MACHINE_START(OSIRIS, "Simtec-OSIRIS")
/* Maintainer: Ben Dooks <ben@simtec.co.uk> */
.phys_io = S3C2410_PA_UART,
.io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
.boot_params = S3C2410_SDRAM_PA + 0x100,
.map_io = osiris_map_io,
.init_machine = osiris_init,
.init_irq = s3c24xx_init_irq,
.timer = &s3c24xx_timer,
MACHINE_END
......@@ -202,11 +202,6 @@ static struct platform_device *rx3715_devices[] __initdata = {
&s3c_device_nand,
};
static struct s3c24xx_board rx3715_board __initdata = {
.devices = rx3715_devices,
.devices_count = ARRAY_SIZE(rx3715_devices)
};
static void __init rx3715_map_io(void)
{
s3c_device_nand.dev.platform_data = &rx3715_nand_info;
......@@ -214,7 +209,6 @@ static void __init rx3715_map_io(void)
s3c24xx_init_io(rx3715_iodesc, ARRAY_SIZE(rx3715_iodesc));
s3c24xx_init_clocks(16934000);
s3c24xx_init_uarts(rx3715_uartcfgs, ARRAY_SIZE(rx3715_uartcfgs));
s3c24xx_set_board(&rx3715_board);
}
static void __init rx3715_init_irq(void)
......@@ -230,9 +224,9 @@ static void __init rx3715_init_machine(void)
s3c2410_pm_init();
s3c24xx_fb_set_platdata(&rx3715_lcdcfg);
platform_add_devices(rx3715_devices, ARRAY_SIZE(rx3715_devices));
}
MACHINE_START(RX3715, "IPAQ-RX3715")
/* Maintainer: Ben Dooks <ben@fluff.org> */
.phys_io = S3C2410_PA_UART,
......
......@@ -174,23 +174,18 @@ static struct platform_device *smdk2440_devices[] __initdata = {
&s3c_device_iis,
};
static struct s3c24xx_board smdk2440_board __initdata = {
.devices = smdk2440_devices,
.devices_count = ARRAY_SIZE(smdk2440_devices)
};
static void __init smdk2440_map_io(void)
{
s3c24xx_init_io(smdk2440_iodesc, ARRAY_SIZE(smdk2440_iodesc));
s3c24xx_init_clocks(16934400);
s3c24xx_init_uarts(smdk2440_uartcfgs, ARRAY_SIZE(smdk2440_uartcfgs));
s3c24xx_set_board(&smdk2440_board);
}
static void __init smdk2440_machine_init(void)
{
s3c24xx_fb_set_platdata(&smdk2440_lcd_cfg);
platform_add_devices(smdk2440_devices, ARRAY_SIZE(smdk2440_devices));
smdk_machine_init();
}
......
......@@ -106,21 +106,16 @@ static struct platform_device *smdk2443_devices[] __initdata = {
&s3c_device_i2c,
};
static struct s3c24xx_board smdk2443_board __initdata = {
.devices = smdk2443_devices,
.devices_count = ARRAY_SIZE(smdk2443_devices)
};
static void __init smdk2443_map_io(void)
{
s3c24xx_init_io(smdk2443_iodesc, ARRAY_SIZE(smdk2443_iodesc));
s3c24xx_init_clocks(12000000);
s3c24xx_init_uarts(smdk2443_uartcfgs, ARRAY_SIZE(smdk2443_uartcfgs));
s3c24xx_set_board(&smdk2443_board);
}
static void __init smdk2443_machine_init(void)
{
platform_add_devices(smdk2443_devices, ARRAY_SIZE(smdk2443_devices));
smdk_machine_init();
}
......
......@@ -9,14 +9,17 @@
#include <linux/string.h>
#include <linux/clk.h>
#include <linux/spinlock.h>
#include <linux/mutex.h>
#include <asm/hardware.h>
#include <asm/semaphore.h>
/*
* Very simple clock implementation - we only have one clock to
* deal with at the moment, so we only match using the "name".
*/
struct clk {
struct list_head node;
unsigned long rate;
struct module *owner;
const char *name;
unsigned int enabled;
void (*enable)(void);
......@@ -24,21 +27,21 @@ struct clk {
};
static LIST_HEAD(clocks);
static DECLARE_MUTEX(clocks_sem);
static DEFINE_MUTEX(clocks_mutex);
static DEFINE_SPINLOCK(clocks_lock);
struct clk *clk_get(struct device *dev, const char *id)
{
struct clk *p, *clk = ERR_PTR(-ENOENT);
down(&clocks_sem);
mutex_lock(&clocks_mutex);
list_for_each_entry(p, &clocks, node) {
if (strcmp(id, p->name) == 0 && try_module_get(p->owner)) {
if (strcmp(id, p->name) == 0) {
clk = p;
break;
}
}
up(&clocks_sem);
mutex_unlock(&clocks_mutex);
return clk;
}
......@@ -46,7 +49,6 @@ EXPORT_SYMBOL(clk_get);
void clk_put(struct clk *clk)
{
module_put(clk->owner);
}
EXPORT_SYMBOL(clk_put);
......@@ -109,18 +111,18 @@ static struct clk clk_gpio27 = {
int clk_register(struct clk *clk)
{
down(&clocks_sem);
mutex_lock(&clocks_mutex);
list_add(&clk->node, &clocks);
up(&clocks_sem);
mutex_unlock(&clocks_mutex);
return 0;
}
EXPORT_SYMBOL(clk_register);
void clk_unregister(struct clk *clk)
{
down(&clocks_sem);
mutex_lock(&clocks_mutex);
list_del(&clk->node);
up(&clocks_sem);
mutex_unlock(&clocks_mutex);
}
EXPORT_SYMBOL(clk_unregister);
......
......@@ -26,6 +26,8 @@
#include <linux/interrupt.h>
#include <linux/amba/bus.h>
#include <linux/amba/clcd.h>
#include <linux/clocksource.h>
#include <linux/clockchips.h>
#include <asm/cnt32_to_63.h>
#include <asm/system.h>
......@@ -828,59 +830,61 @@ void __init versatile_init(void)
#define TICKS2USECS(x) ((x) / TICKS_PER_uSEC)
#endif
/*
* Returns number of ms since last clock interrupt. Note that interrupts
* will have been disabled by do_gettimeoffset()
*/
static unsigned long versatile_gettimeoffset(void)
static void timer_set_mode(enum clock_event_mode mode,
struct clock_event_device *clk)
{
unsigned long ticks1, ticks2, status;
unsigned long ctrl;
/*
* Get the current number of ticks. Note that there is a race
* condition between us reading the timer and checking for
* an interrupt. We get around this by ensuring that the
* counter has not reloaded between our two reads.
*/
ticks2 = readl(TIMER0_VA_BASE + TIMER_VALUE) & 0xffff;
do {
ticks1 = ticks2;
status = __raw_readl(VA_IC_BASE + VIC_RAW_STATUS);
ticks2 = readl(TIMER0_VA_BASE + TIMER_VALUE) & 0xffff;
} while (ticks2 > ticks1);
switch(mode) {
case CLOCK_EVT_MODE_PERIODIC:
writel(TIMER_RELOAD, TIMER0_VA_BASE + TIMER_LOAD);
/*
* Number of ticks since last interrupt.
*/
ticks1 = TIMER_RELOAD - ticks2;
ctrl = TIMER_CTRL_PERIODIC;
ctrl |= TIMER_CTRL_32BIT | TIMER_CTRL_IE | TIMER_CTRL_ENABLE;
break;
case CLOCK_EVT_MODE_ONESHOT:
/* period set, and timer enabled in 'next_event' hook */
ctrl = TIMER_CTRL_ONESHOT;
ctrl |= TIMER_CTRL_32BIT | TIMER_CTRL_IE;
break;
case CLOCK_EVT_MODE_UNUSED:
case CLOCK_EVT_MODE_SHUTDOWN:
default:
ctrl = 0;
}
/*
* Interrupt pending? If so, we've reloaded once already.
*
* FIXME: Need to check this is effectively timer 0 that expires
*/
if (status & IRQMASK_TIMERINT0_1)
ticks1 += TIMER_RELOAD;
writel(ctrl, TIMER0_VA_BASE + TIMER_CTRL);
}
/*
* Convert the ticks to usecs
*/
return TICKS2USECS(ticks1);
static int timer_set_next_event(unsigned long evt,
struct clock_event_device *unused)
{
unsigned long ctrl = readl(TIMER0_VA_BASE + TIMER_CTRL);
writel(evt, TIMER0_VA_BASE + TIMER_LOAD);
writel(ctrl | TIMER_CTRL_ENABLE, TIMER0_VA_BASE + TIMER_CTRL);
return 0;
}
static struct clock_event_device timer0_clockevent = {
.name = "timer0",
.shift = 32,
.features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
.set_mode = timer_set_mode,
.set_next_event = timer_set_next_event,
};
/*
* IRQ handler for the timer
*/
static irqreturn_t versatile_timer_interrupt(int irq, void *dev_id)
{
write_seqlock(&xtime_lock);
struct clock_event_device *evt = &timer0_clockevent;
// ...clear the interrupt
writel(1, TIMER0_VA_BASE + TIMER_INTCLR);
timer_tick();
write_sequnlock(&xtime_lock);
evt->event_handler(evt);
return IRQ_HANDLED;
}
......@@ -891,6 +895,36 @@ static struct irqaction versatile_timer_irq = {
.handler = versatile_timer_interrupt,
};
static cycle_t versatile_get_cycles(void)
{
return ~readl(TIMER3_VA_BASE + TIMER_VALUE);
}
static struct clocksource clocksource_versatile = {
.name = "timer3",
.rating = 200,
.read = versatile_get_cycles,
.mask = CLOCKSOURCE_MASK(32),
.shift = 20,
.flags = CLOCK_SOURCE_IS_CONTINUOUS,
};
static int __init versatile_clocksource_init(void)
{
/* setup timer3 as free-running clocksource */
writel(0, TIMER3_VA_BASE + TIMER_CTRL);
writel(0xffffffff, TIMER3_VA_BASE + TIMER_LOAD);
writel(0xffffffff, TIMER3_VA_BASE + TIMER_VALUE);
writel(TIMER_CTRL_32BIT | TIMER_CTRL_ENABLE | TIMER_CTRL_PERIODIC,
TIMER3_VA_BASE + TIMER_CTRL);
clocksource_versatile.mult =
clocksource_khz2mult(1000, clocksource_versatile.shift);
clocksource_register(&clocksource_versatile);
return 0;
}
/*
* Set up timer interrupt, and return the current time in seconds.
*/
......@@ -918,18 +952,25 @@ static void __init versatile_timer_init(void)
writel(0, TIMER2_VA_BASE + TIMER_CTRL);
writel(0, TIMER3_VA_BASE + TIMER_CTRL);
writel(TIMER_RELOAD, TIMER0_VA_BASE + TIMER_LOAD);
writel(TIMER_RELOAD, TIMER0_VA_BASE + TIMER_VALUE);
writel(TIMER_DIVISOR | TIMER_CTRL_ENABLE | TIMER_CTRL_PERIODIC |
TIMER_CTRL_IE, TIMER0_VA_BASE + TIMER_CTRL);
/*
* Make irqs happen for the system timer
*/
setup_irq(IRQ_TIMERINT0_1, &versatile_timer_irq);
versatile_clocksource_init();
timer0_clockevent.mult =
div_sc(1000000, NSEC_PER_SEC, timer0_clockevent.shift);
timer0_clockevent.max_delta_ns =
clockevent_delta2ns(0xffffffff, &timer0_clockevent);
timer0_clockevent.min_delta_ns =
clockevent_delta2ns(0xf, &timer0_clockevent);
timer0_clockevent.cpumask = cpumask_of_cpu(0);
clockevents_register_device(&timer0_clockevent);
}
struct sys_timer versatile_timer = {
.init = versatile_timer_init,
.offset = versatile_gettimeoffset,
};
......@@ -19,6 +19,19 @@
#include <asm/ptrace.h>
#include <asm/uaccess.h>
#include "../kernel/stacktrace.h"
static int report_trace(struct stackframe *frame, void *d)
{
unsigned int *depth = d;
if (*depth) {
oprofile_add_trace(frame->lr);
(*depth)--;
}
return *depth == 0;
}
/*
* The registers we're interested in are at the end of the variable
......@@ -32,21 +45,6 @@ struct frame_tail {
unsigned long lr;
} __attribute__((packed));
#ifdef CONFIG_FRAME_POINTER
static struct frame_tail* kernel_backtrace(struct frame_tail *tail)
{
oprofile_add_trace(tail->lr);
/* frame pointers should strictly progress back up the stack
* (towards higher addresses) */
if (tail >= tail->fp)
return NULL;
return tail->fp-1;
}
#endif
static struct frame_tail* user_backtrace(struct frame_tail *tail)
{
struct frame_tail buftail[2];
......@@ -67,47 +65,14 @@ static struct frame_tail* user_backtrace(struct frame_tail *tail)
return buftail[0].fp-1;
}
/*
* | | /\ Higher addresses
* | |
* --------------- stack base (address of current_thread_info)
* | thread info |
* . .
* | stack |
* --------------- saved regs->ARM_fp value if valid (frame_tail address)
* . .
* --------------- struct pt_regs stored on stack (struct pt_regs *)
* | |
* . .
* | |
* --------------- %esp
* | |
* | | \/ Lower addresses
*
* Thus, &pt_regs <-> stack base restricts the valid(ish) fp values
*/
static int valid_kernel_stack(struct frame_tail *tail, struct pt_regs *regs)
{
unsigned long tailaddr = (unsigned long)tail;
unsigned long stack = (unsigned long)regs;
unsigned long stack_base = (stack & ~(THREAD_SIZE - 1)) + THREAD_SIZE;
return (tailaddr > stack) && (tailaddr < stack_base);
}
void arm_backtrace(struct pt_regs * const regs, unsigned int depth)
{
struct frame_tail *tail;
tail = ((struct frame_tail *) regs->ARM_fp) - 1;
struct frame_tail *tail = ((struct frame_tail *) regs->ARM_fp) - 1;
if (!user_mode(regs)) {
#ifdef CONFIG_FRAME_POINTER
while (depth-- && tail && valid_kernel_stack(tail, regs)) {
tail = kernel_backtrace(tail);
}
#endif
unsigned long base = ((unsigned long)regs) & ~(THREAD_SIZE - 1);
walk_stackframe(regs->ARM_fp, base, base + THREAD_SIZE,
report_trace, &depth);
return;
}
......
......@@ -55,7 +55,7 @@ static u32 iop3xx_cfg_address(struct pci_bus *bus, int devfn, int where)
* This routine checks the status of the last configuration cycle. If an error
* was detected it returns a 1, else it returns a 0. The errors being checked
* are parity, master abort, target abort (master and target). These types of
* errors occure during a config cycle where there is no device, like during
* errors occur during a config cycle where there is no device, like during
* the discovery stage.
*/
static int iop3xx_pci_status(void)
......@@ -223,8 +223,111 @@ struct pci_bus *iop3xx_pci_scan_bus(int nr, struct pci_sys_data *sys)
return pci_scan_bus(sys->busnr, &iop3xx_ops, sys);
}
void __init iop3xx_atu_setup(void)
{
/* BAR 0 ( Disabled ) */
*IOP3XX_IAUBAR0 = 0x0;
*IOP3XX_IABAR0 = 0x0;
*IOP3XX_IATVR0 = 0x0;
*IOP3XX_IALR0 = 0x0;
/* BAR 1 ( Disabled ) */
*IOP3XX_IAUBAR1 = 0x0;
*IOP3XX_IABAR1 = 0x0;
*IOP3XX_IALR1 = 0x0;
/* BAR 2 (1:1 mapping with Physical RAM) */
/* Set limit and enable */
*IOP3XX_IALR2 = ~((u32)IOP3XX_MAX_RAM_SIZE - 1) & ~0x1;
*IOP3XX_IAUBAR2 = 0x0;
/* Align the inbound bar with the base of memory */
*IOP3XX_IABAR2 = PHYS_OFFSET |
PCI_BASE_ADDRESS_MEM_TYPE_64 |
PCI_BASE_ADDRESS_MEM_PREFETCH;
*IOP3XX_IATVR2 = PHYS_OFFSET;
/* Outbound window 0 */
*IOP3XX_OMWTVR0 = IOP3XX_PCI_LOWER_MEM_PA;
*IOP3XX_OUMWTVR0 = 0;
/* Outbound window 1 */
*IOP3XX_OMWTVR1 = IOP3XX_PCI_LOWER_MEM_PA + IOP3XX_PCI_MEM_WINDOW_SIZE;
*IOP3XX_OUMWTVR1 = 0;
/* BAR 3 ( Disabled ) */
*IOP3XX_IAUBAR3 = 0x0;
*IOP3XX_IABAR3 = 0x0;
*IOP3XX_IATVR3 = 0x0;
*IOP3XX_IALR3 = 0x0;
/* Setup the I/O Bar
*/
*IOP3XX_OIOWTVR = IOP3XX_PCI_LOWER_IO_PA;;
/* Enable inbound and outbound cycles
*/
*IOP3XX_ATUCMD |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER |
PCI_COMMAND_PARITY | PCI_COMMAND_SERR;
*IOP3XX_ATUCR |= IOP3XX_ATUCR_OUT_EN;
}
void __init iop3xx_atu_disable(void)
{
*IOP3XX_ATUCMD = 0;
*IOP3XX_ATUCR = 0;
/* wait for cycles to quiesce */
while (*IOP3XX_PCSR & (IOP3XX_PCSR_OUT_Q_BUSY |
IOP3XX_PCSR_IN_Q_BUSY))
cpu_relax();
/* BAR 0 ( Disabled ) */
*IOP3XX_IAUBAR0 = 0x0;
*IOP3XX_IABAR0 = 0x0;
*IOP3XX_IATVR0 = 0x0;
*IOP3XX_IALR0 = 0x0;
/* BAR 1 ( Disabled ) */
*IOP3XX_IAUBAR1 = 0x0;
*IOP3XX_IABAR1 = 0x0;
*IOP3XX_IALR1 = 0x0;
/* BAR 2 ( Disabled ) */
*IOP3XX_IAUBAR2 = 0x0;
*IOP3XX_IABAR2 = 0x0;
*IOP3XX_IATVR2 = 0x0;
*IOP3XX_IALR2 = 0x0;
/* BAR 3 ( Disabled ) */
*IOP3XX_IAUBAR3 = 0x0;
*IOP3XX_IABAR3 = 0x0;
*IOP3XX_IATVR3 = 0x0;
*IOP3XX_IALR3 = 0x0;
/* Clear the outbound windows */
*IOP3XX_OIOWTVR = 0;
/* Outbound window 0 */
*IOP3XX_OMWTVR0 = 0;
*IOP3XX_OUMWTVR0 = 0;
/* Outbound window 1 */
*IOP3XX_OMWTVR1 = 0;
*IOP3XX_OUMWTVR1 = 0;
}
/* Flag to determine whether the ATU is initialized and the PCI bus scanned */
int init_atu;
void iop3xx_pci_preinit(void)
{
if (iop3xx_get_init_atu() == IOP3XX_INIT_ATU_ENABLE) {
iop3xx_atu_disable();
iop3xx_atu_setup();
}
DBG("PCI: Intel 803xx PCI init code.\n");
DBG("ATU: IOP3XX_ATUCMD=0x%04x\n", *IOP3XX_ATUCMD);
DBG("ATU: IOP3XX_OMWTVR0=0x%04x, IOP3XX_OIOWTVR=0x%04x\n",
......@@ -245,3 +348,38 @@ void iop3xx_pci_preinit(void)
hook_fault_code(16+6, iop3xx_pci_abort, SIGBUS, "imprecise external abort");
}
/* allow init_atu to be user overridden */
static int __init iop3xx_init_atu_setup(char *str)
{
init_atu = IOP3XX_INIT_ATU_DEFAULT;
if (str) {
while (*str != '\0') {
switch (*str) {
case 'y':
case 'Y':
init_atu = IOP3XX_INIT_ATU_ENABLE;
break;
case 'n':
case 'N':
init_atu = IOP3XX_INIT_ATU_DISABLE;
break;
case ',':
case '=':
break;
default:
printk(KERN_DEBUG "\"%s\" malformed at "
"character: \'%c\'",
__FUNCTION__,
*str);
*(str + 1) = '\0';
}
str++;
}
}
return 1;
}
__setup("iop3xx_init_atu", iop3xx_init_atu_setup);
......@@ -32,22 +32,22 @@ static unsigned long next_jiffy_time;
unsigned long iop_gettimeoffset(void)
{
unsigned long offset, temp1, temp2;
unsigned long offset, temp;
/* enable cp6, if necessary, to avoid taking the overhead of an
* undefined instruction trap
*/
asm volatile (
"mrc p15, 0, %0, c15, c1, 0\n\t"
"ands %1, %0, #(1 << 6)\n\t"
"tst %0, #(1 << 6)\n\t"
"orreq %0, %0, #(1 << 6)\n\t"
"mcreq p15, 0, %0, c15, c1, 0\n\t"
#ifdef CONFIG_XSCALE
#ifdef CONFIG_CPU_XSCALE
"mrceq p15, 0, %0, c15, c1, 0\n\t"
"moveq %0, %0\n\t"
"subeq pc, pc, #4\n\t"
#endif
: "=r"(temp1), "=r"(temp2) : : "cc");
: "=r"(temp) : : "cc");
offset = next_jiffy_time - read_tcr1();
......
......@@ -11,6 +11,7 @@ choice
config ARCH_OMAP1
bool "TI OMAP1"
select GENERIC_CLOCKEVENTS
config ARCH_OMAP2
bool "TI OMAP2"
......
......@@ -156,3 +156,53 @@ static int __init omap_add_serial_console(void)
return add_preferred_console("ttyS", line, opt);
}
console_initcall(omap_add_serial_console);
/*
* 32KHz clocksource ... always available, on pretty most chips except
* OMAP 730 and 1510. Other timers could be used as clocksources, with
* higher resolution in free-running counter modes (e.g. 12 MHz xtal),
* but systems won't necessarily want to spend resources that way.
*/
#if defined(CONFIG_ARCH_OMAP16XX)
#define TIMER_32K_SYNCHRONIZED 0xfffbc410
#elif defined(CONFIG_ARCH_OMAP24XX)
#define TIMER_32K_SYNCHRONIZED 0x48004010
#endif
#ifdef TIMER_32K_SYNCHRONIZED
#include <linux/clocksource.h>
static cycle_t omap_32k_read(void)
{
return omap_readl(TIMER_32K_SYNCHRONIZED);
}
static struct clocksource clocksource_32k = {
.name = "32k_counter",
.rating = 250,
.read = omap_32k_read,
.mask = CLOCKSOURCE_MASK(32),
.shift = 10,
.flags = CLOCK_SOURCE_IS_CONTINUOUS,
};
static int __init omap_init_clocksource_32k(void)
{
static char err[] __initdata = KERN_ERR
"%s: can't register clocksource!\n";
if (cpu_is_omap16xx() || cpu_is_omap24xx()) {
clocksource_32k.mult = clocksource_hz2mult(32768,
clocksource_32k.shift);
if (clocksource_register(&clocksource_32k))
printk(err, clocksource_32k.name);
}
return 0;
}
arch_initcall(omap_init_clocksource_32k);
#endif /* TIMER_32K_SYNCHRONIZED */
......@@ -429,6 +429,10 @@ static inline void omap_init_rng(void) {}
*/
static int __init omap_init_devices(void)
{
/*
* Need to enable relevant once for 2430 SDP
*/
#ifndef CONFIG_MACH_OMAP_2430SDP
/* please keep these calls, and their implementations above,
* in alphabetical order so they're easier to sort through.
*/
......@@ -438,7 +442,7 @@ static int __init omap_init_devices(void)
omap_init_uwire();
omap_init_wdt();
omap_init_rng();
#endif
return 0;
}
arch_initcall(omap_init_devices);
......
......@@ -506,6 +506,8 @@ int omap_dm_timer_init(void)
BUG_ON(dm_source_clocks[i] == NULL);
}
#endif
if (cpu_is_omap243x())
dm_timers[0].phys_base = 0x49018000;
for (i = 0; i < dm_timer_count; i++) {
#ifdef CONFIG_ARCH_OMAP2
......
此差异已折叠。
......@@ -225,11 +225,16 @@ static void omap_mcbsp_dsp_free(void)
#ifdef CONFIG_ARCH_OMAP2
static void omap2_mcbsp2_mux_setup(void)
{
omap_cfg_reg(Y15_24XX_MCBSP2_CLKX);
omap_cfg_reg(R14_24XX_MCBSP2_FSX);
omap_cfg_reg(W15_24XX_MCBSP2_DR);
omap_cfg_reg(V15_24XX_MCBSP2_DX);
omap_cfg_reg(V14_24XX_GPIO117);
if (cpu_is_omap2420()) {
omap_cfg_reg(Y15_24XX_MCBSP2_CLKX);
omap_cfg_reg(R14_24XX_MCBSP2_FSX);
omap_cfg_reg(W15_24XX_MCBSP2_DR);
omap_cfg_reg(V15_24XX_MCBSP2_DX);
omap_cfg_reg(V14_24XX_GPIO117);
}
/*
* Need to add MUX settings for OMAP 2430 SDP
*/
}
#endif
......
此差异已折叠。
......@@ -404,6 +404,18 @@ int s3c24xx_register_clock(struct clk *clk)
return 0;
}
int s3c24xx_register_clocks(struct clk **clks, int nr_clks)
{
int fails = 0;
for (; nr_clks > 0; nr_clks--, clks++) {
if (s3c24xx_register_clock(*clks) < 0)
fails++;
}
return fails;
}
/* initalise all the clocks */
int __init s3c24xx_setup_clocks(unsigned long xtal,
......
......@@ -181,24 +181,6 @@ s3c_lookup_cpu(unsigned long idcode)
return NULL;
}
/* board information */
static struct s3c24xx_board *board;
void s3c24xx_set_board(struct s3c24xx_board *b)
{
int i;
board = b;
if (b->clocks_count != 0) {
struct clk **ptr = b->clocks;
for (i = b->clocks_count; i > 0; i--, ptr++)
s3c24xx_register_clock(*ptr);
}
}
/* cpu information */
static struct cpu_table *cpu;
......@@ -342,26 +324,6 @@ static int __init s3c_arch_init(void)
return ret;
ret = platform_add_devices(s3c24xx_uart_devs, nr_uarts);
if (ret != 0)
return ret;
if (board != NULL) {
struct platform_device **ptr = board->devices;
int i;
for (i = 0; i < board->devices_count; i++, ptr++) {
ret = platform_device_register(*ptr);
if (ret) {
printk(KERN_ERR "s3c24xx: failed to add board device %s (%d) @%p\n", (*ptr)->name, ret, *ptr);
}
}
/* mask any error, we may not need all these board
* devices */
ret = 0;
}
return ret;
}
......
此差异已折叠。
......@@ -34,7 +34,6 @@
#include <linux/bitops.h>
#include <asm/div64.h>
#include <asm/ptrace.h>
#include <asm/vfp.h>
#include "vfpinstr.h"
......
......@@ -34,7 +34,6 @@
#include <linux/bitops.h>
#include <asm/div64.h>
#include <asm/ptrace.h>
#include <asm/vfp.h>
#include "vfpinstr.h"
......
此差异已折叠。
......@@ -61,6 +61,7 @@ obj-$(CONFIG_PATA_TRIFLEX) += pata_triflex.o
obj-$(CONFIG_PATA_IXP4XX_CF) += pata_ixp4xx_cf.o
obj-$(CONFIG_PATA_SCC) += pata_scc.o
obj-$(CONFIG_PATA_PLATFORM) += pata_platform.o
obj-$(CONFIG_PATA_ICSIDE) += pata_icside.o
# Should be last but one libata driver
obj-$(CONFIG_ATA_GENERIC) += ata_generic.o
# Should be last libata driver
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册