Commit 6f3cafce authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'devel' of master.kernel.org:/home/rmk/linux-2.6-arm

* 'devel' of master.kernel.org:/home/rmk/linux-2.6-arm: (21 commits)
  [ARM] 3629/1: S3C24XX: fix missing bracket in regs-dsc.h
  [ARM] 3537/1: Rework DMA-bounce locking for finer granularity
  [ARM] 3601/1: i.MX/MX1 DMA error handling for signaled channels only
  [ARM] 3597/1: ixp4xx/nslu2: Board support for new LED subsystem
  [ARM] 3595/1: ixp4xx/nas100d: Board support for new LED subsystem
  [ARM] 3626/1: ARM EABI: fix syscall restarting
  [ARM] 3628/1: S3C24XX: add get_rate call to struct clk
  [ARM] 3627/1: S3C24XX: split s3c2410 clocks from core clocks
  [ARM] 3613/1: S3C2410: Add sysdev and sysclass
  [ARM] 3624/1: Report true modem control line states
  [ARM] 3620/2: ixp23xx: add uengine loader support
  [ARM] 3618/1: add defconfig for logicpd pxa270 card engine
  [ARM] 3617/1: ep93xx: fix slightly incorrect timer tick rate
  [ARM] 3616/1: fix timer handler wrap logic for a number of platforms
  [ARM] 3615/1: ixp23xx: use platform devices for physmap flash
  [ARM] 3614/1: ep93xx: use platform devices for physmap flash
  [ARM] 3621/1: fix compilation breakage for pnx4008
  [ARM] 3623/1: pnx4008: move GPIO-related defines to gpio.h
  [ARM] 3622/1: pnx4008: remove clk_use/clk_unuse
  [ARM] Enable VFP to be built when non-VFP capable CPUs are selected
  ...
parents 0c97f524 02916526
......@@ -16,3 +16,4 @@ obj-$(CONFIG_SHARP_PARAM) += sharpsl_param.o
obj-$(CONFIG_SHARPSL_PM) += sharpsl_pm.o
obj-$(CONFIG_SHARP_SCOOP) += scoop.o
obj-$(CONFIG_ARCH_IXP2000) += uengine.o
obj-$(CONFIG_ARCH_IXP23XX) += uengine.o
......@@ -77,6 +77,8 @@ struct dmabounce_device_info {
#endif
struct dmabounce_pool small;
struct dmabounce_pool large;
rwlock_t lock;
};
static LIST_HEAD(dmabounce_devs);
......@@ -116,6 +118,7 @@ alloc_safe_buffer(struct dmabounce_device_info *device_info, void *ptr,
struct safe_buffer *buf;
struct dmabounce_pool *pool;
struct device *dev = device_info->dev;
unsigned long flags;
dev_dbg(dev, "%s(ptr=%p, size=%d, dir=%d)\n",
__func__, ptr, size, dir);
......@@ -163,8 +166,12 @@ alloc_safe_buffer(struct dmabounce_device_info *device_info, void *ptr,
print_alloc_stats(device_info);
#endif
write_lock_irqsave(&device_info->lock, flags);
list_add(&buf->node, &device_info->safe_buffers);
write_unlock_irqrestore(&device_info->lock, flags);
return buf;
}
......@@ -172,22 +179,32 @@ alloc_safe_buffer(struct dmabounce_device_info *device_info, void *ptr,
static inline struct safe_buffer *
find_safe_buffer(struct dmabounce_device_info *device_info, dma_addr_t safe_dma_addr)
{
struct safe_buffer *b;
struct safe_buffer *b = NULL;
unsigned long flags;
read_lock_irqsave(&device_info->lock, flags);
list_for_each_entry(b, &device_info->safe_buffers, node)
if (b->safe_dma_addr == safe_dma_addr)
return b;
break;
return NULL;
read_unlock_irqrestore(&device_info->lock, flags);
return b;
}
static inline void
free_safe_buffer(struct dmabounce_device_info *device_info, struct safe_buffer *buf)
{
unsigned long flags;
dev_dbg(device_info->dev, "%s(buf=%p)\n", __func__, buf);
write_lock_irqsave(&device_info->lock, flags);
list_del(&buf->node);
write_unlock_irqrestore(&device_info->lock, flags);
if (buf->pool)
dma_pool_free(buf->pool->pool, buf->safe, buf->safe_dma_addr);
else
......@@ -396,7 +413,6 @@ dma_addr_t
dma_map_single(struct device *dev, void *ptr, size_t size,
enum dma_data_direction dir)
{
unsigned long flags;
dma_addr_t dma_addr;
dev_dbg(dev, "%s(ptr=%p,size=%d,dir=%x)\n",
......@@ -404,12 +420,8 @@ dma_map_single(struct device *dev, void *ptr, size_t size,
BUG_ON(dir == DMA_NONE);
local_irq_save(flags);
dma_addr = map_single(dev, ptr, size, dir);
local_irq_restore(flags);
return dma_addr;
}
......@@ -424,25 +436,18 @@ void
dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
enum dma_data_direction dir)
{
unsigned long flags;
dev_dbg(dev, "%s(ptr=%p,size=%d,dir=%x)\n",
__func__, (void *) dma_addr, size, dir);
BUG_ON(dir == DMA_NONE);
local_irq_save(flags);
unmap_single(dev, dma_addr, size, dir);
local_irq_restore(flags);
}
int
dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
enum dma_data_direction dir)
{
unsigned long flags;
int i;
dev_dbg(dev, "%s(sg=%p,nents=%d,dir=%x)\n",
......@@ -450,8 +455,6 @@ dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
BUG_ON(dir == DMA_NONE);
local_irq_save(flags);
for (i = 0; i < nents; i++, sg++) {
struct page *page = sg->page;
unsigned int offset = sg->offset;
......@@ -462,8 +465,6 @@ dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
map_single(dev, ptr, length, dir);
}
local_irq_restore(flags);
return nents;
}
......@@ -471,7 +472,6 @@ void
dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nents,
enum dma_data_direction dir)
{
unsigned long flags;
int i;
dev_dbg(dev, "%s(sg=%p,nents=%d,dir=%x)\n",
......@@ -479,55 +479,38 @@ dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nents,
BUG_ON(dir == DMA_NONE);
local_irq_save(flags);
for (i = 0; i < nents; i++, sg++) {
dma_addr_t dma_addr = sg->dma_address;
unsigned int length = sg->length;
unmap_single(dev, dma_addr, length, dir);
}
local_irq_restore(flags);
}
void
dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_addr, size_t size,
enum dma_data_direction dir)
{
unsigned long flags;
dev_dbg(dev, "%s(ptr=%p,size=%d,dir=%x)\n",
__func__, (void *) dma_addr, size, dir);
local_irq_save(flags);
sync_single(dev, dma_addr, size, dir);
local_irq_restore(flags);
}
void
dma_sync_single_for_device(struct device *dev, dma_addr_t dma_addr, size_t size,
enum dma_data_direction dir)
{
unsigned long flags;
dev_dbg(dev, "%s(ptr=%p,size=%d,dir=%x)\n",
__func__, (void *) dma_addr, size, dir);
local_irq_save(flags);
sync_single(dev, dma_addr, size, dir);
local_irq_restore(flags);
}
void
dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, int nents,
enum dma_data_direction dir)
{
unsigned long flags;
int i;
dev_dbg(dev, "%s(sg=%p,nents=%d,dir=%x)\n",
......@@ -535,23 +518,18 @@ dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, int nents,
BUG_ON(dir == DMA_NONE);
local_irq_save(flags);
for (i = 0; i < nents; i++, sg++) {
dma_addr_t dma_addr = sg->dma_address;
unsigned int length = sg->length;
sync_single(dev, dma_addr, length, dir);
}
local_irq_restore(flags);
}
void
dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nents,
enum dma_data_direction dir)
{
unsigned long flags;
int i;
dev_dbg(dev, "%s(sg=%p,nents=%d,dir=%x)\n",
......@@ -559,16 +537,12 @@ dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nents,
BUG_ON(dir == DMA_NONE);
local_irq_save(flags);
for (i = 0; i < nents; i++, sg++) {
dma_addr_t dma_addr = sg->dma_address;
unsigned int length = sg->length;
sync_single(dev, dma_addr, length, dir);
}
local_irq_restore(flags);
}
static int
......@@ -622,6 +596,7 @@ dmabounce_register_dev(struct device *dev, unsigned long small_buffer_size,
device_info->dev = dev;
INIT_LIST_HEAD(&device_info->safe_buffers);
rwlock_init(&device_info->lock);
#ifdef STATS
device_info->total_allocs = 0;
......
......@@ -18,10 +18,26 @@
#include <linux/module.h>
#include <linux/string.h>
#include <asm/hardware.h>
#include <asm/arch/ixp2000-regs.h>
#include <asm/arch/hardware.h>
#include <asm/hardware/uengine.h>
#include <asm/io.h>
#if defined(CONFIG_ARCH_IXP2000)
#define IXP_UENGINE_CSR_VIRT_BASE IXP2000_UENGINE_CSR_VIRT_BASE
#define IXP_PRODUCT_ID IXP2000_PRODUCT_ID
#define IXP_MISC_CONTROL IXP2000_MISC_CONTROL
#define IXP_RESET1 IXP2000_RESET1
#else
#if defined(CONFIG_ARCH_IXP23XX)
#define IXP_UENGINE_CSR_VIRT_BASE IXP23XX_UENGINE_CSR_VIRT_BASE
#define IXP_PRODUCT_ID IXP23XX_PRODUCT_ID
#define IXP_MISC_CONTROL IXP23XX_MISC_CONTROL
#define IXP_RESET1 IXP23XX_RESET1
#else
#error unknown platform
#endif
#endif
#define USTORE_ADDRESS 0x000
#define USTORE_DATA_LOWER 0x004
#define USTORE_DATA_UPPER 0x008
......@@ -43,7 +59,7 @@ u32 ixp2000_uengine_mask;
static void *ixp2000_uengine_csr_area(int uengine)
{
return ((void *)IXP2000_UENGINE_CSR_VIRT_BASE) + (uengine << 10);
return ((void *)IXP_UENGINE_CSR_VIRT_BASE) + (uengine << 10);
}
/*
......@@ -91,8 +107,13 @@ EXPORT_SYMBOL(ixp2000_uengine_csr_write);
void ixp2000_uengine_reset(u32 uengine_mask)
{
ixp2000_reg_wrb(IXP2000_RESET1, uengine_mask & ixp2000_uengine_mask);
ixp2000_reg_wrb(IXP2000_RESET1, 0);
u32 value;
value = ixp2000_reg_read(IXP_RESET1) & ~ixp2000_uengine_mask;
uengine_mask &= ixp2000_uengine_mask;
ixp2000_reg_wrb(IXP_RESET1, value | uengine_mask);
ixp2000_reg_wrb(IXP_RESET1, value);
}
EXPORT_SYMBOL(ixp2000_uengine_reset);
......@@ -235,11 +256,12 @@ static int check_ixp_type(struct ixp2000_uengine_code *c)
u32 product_id;
u32 rev;
product_id = ixp2000_reg_read(IXP2000_PRODUCT_ID);
product_id = ixp2000_reg_read(IXP_PRODUCT_ID);
if (((product_id >> 16) & 0x1f) != 0)
return 0;
switch ((product_id >> 8) & 0xff) {
#ifdef CONFIG_ARCH_IXP2000
case 0: /* IXP2800 */
if (!(c->cpu_model_bitmask & 4))
return 0;
......@@ -254,6 +276,14 @@ static int check_ixp_type(struct ixp2000_uengine_code *c)
if (!(c->cpu_model_bitmask & 2))
return 0;
break;
#endif
#ifdef CONFIG_ARCH_IXP23XX
case 4: /* IXP23xx */
if (!(c->cpu_model_bitmask & 0x3f0))
return 0;
break;
#endif
default:
return 0;
......@@ -432,7 +462,8 @@ static int __init ixp2000_uengine_init(void)
/*
* Determine number of microengines present.
*/
switch ((ixp2000_reg_read(IXP2000_PRODUCT_ID) >> 8) & 0x1fff) {
switch ((ixp2000_reg_read(IXP_PRODUCT_ID) >> 8) & 0x1fff) {
#ifdef CONFIG_ARCH_IXP2000
case 0: /* IXP2800 */
case 1: /* IXP2850 */
ixp2000_uengine_mask = 0x00ff00ff;
......@@ -441,10 +472,17 @@ static int __init ixp2000_uengine_init(void)
case 2: /* IXP2400 */
ixp2000_uengine_mask = 0x000f000f;
break;
#endif
#ifdef CONFIG_ARCH_IXP23XX
case 4: /* IXP23xx */
ixp2000_uengine_mask = (*IXP23XX_EXP_CFG_FUSE >> 8) & 0xf;
break;
#endif
default:
printk(KERN_INFO "Detected unknown IXP2000 model (%.8x)\n",
(unsigned int)ixp2000_reg_read(IXP2000_PRODUCT_ID));
(unsigned int)ixp2000_reg_read(IXP_PRODUCT_ID));
ixp2000_uengine_mask = 0x00000000;
break;
}
......@@ -457,15 +495,15 @@ static int __init ixp2000_uengine_init(void)
/*
* Synchronise timestamp counters across all microengines.
*/
value = ixp2000_reg_read(IXP2000_MISC_CONTROL);
ixp2000_reg_wrb(IXP2000_MISC_CONTROL, value & ~0x80);
value = ixp2000_reg_read(IXP_MISC_CONTROL);
ixp2000_reg_wrb(IXP_MISC_CONTROL, value & ~0x80);
for (uengine = 0; uengine < 32; uengine++) {
if (ixp2000_uengine_mask & (1 << uengine)) {
ixp2000_uengine_csr_write(uengine, TIMESTAMP_LOW, 0);
ixp2000_uengine_csr_write(uengine, TIMESTAMP_HIGH, 0);
}
}
ixp2000_reg_wrb(IXP2000_MISC_CONTROL, value | 0x80);
ixp2000_reg_wrb(IXP_MISC_CONTROL, value | 0x80);
return 0;
}
......
This diff is collapsed.
......@@ -20,6 +20,7 @@
#include <asm/glue.h>
#include <asm/vfpmacros.h>
#include <asm/arch/entry-macro.S>
#include <asm/thread_notify.h>
#include "entry-header.S"
......@@ -560,10 +561,8 @@ ENTRY(__switch_to)
add ip, r1, #TI_CPU_SAVE
ldr r3, [r2, #TI_TP_VALUE]
stmia ip!, {r4 - sl, fp, sp, lr} @ Store most regs on stack
#ifndef CONFIG_MMU
add r2, r2, #TI_CPU_DOMAIN
#else
ldr r6, [r2, #TI_CPU_DOMAIN]!
#ifdef CONFIG_MMU
ldr r6, [r2, #TI_CPU_DOMAIN]
#endif
#if __LINUX_ARM_ARCH__ >= 6
#ifdef CONFIG_CPU_32v6K
......@@ -585,21 +584,20 @@ ENTRY(__switch_to)
#ifdef CONFIG_MMU
mcr p15, 0, r6, c3, c0, 0 @ Set domain register
#endif
#ifdef CONFIG_VFP
@ Always disable VFP so we can lazily save/restore the old
@ state. This occurs in the context of the previous thread.
VFPFMRX r4, FPEXC
bic r4, r4, #FPEXC_ENABLE
VFPFMXR FPEXC, r4
#endif
#if defined(CONFIG_IWMMXT)
bl iwmmxt_task_switch
#elif defined(CONFIG_CPU_XSCALE)
add r4, r2, #40 @ cpu_context_save->extra
add r4, r2, #TI_CPU_DOMAIN + 40 @ cpu_context_save->extra
ldmib r4, {r4, r5}
mar acc0, r4, r5
#endif
ldmib r2, {r4 - sl, fp, sp, pc} @ Load all regs saved previously
mov r5, r0
add r4, r2, #TI_CPU_SAVE
ldr r0, =thread_notify_head
mov r1, #THREAD_NOTIFY_SWITCH
bl atomic_notifier_call_chain
mov r0, r5
ldmia r4, {r4 - sl, fp, sp, pc} @ Load all regs saved previously
__INIT
......
......@@ -285,7 +285,7 @@ ENTRY(iwmmxt_task_switch)
bne 1f @ yes: block them for next task
ldr r5, =concan_owner
add r6, r2, #(TI_IWMMXT_STATE - TI_CPU_DOMAIN) @ get next task Concan save area
add r6, r2, #TI_IWMMXT_STATE @ get next task Concan save area
ldr r5, [r5] @ get current Concan owner
teq r5, r6 @ next task owns it?
movne pc, lr @ no: leave Concan disabled
......
......@@ -33,6 +33,7 @@
#include <asm/leds.h>
#include <asm/processor.h>
#include <asm/system.h>
#include <asm/thread_notify.h>
#include <asm/uaccess.h>
#include <asm/mach/time.h>
......@@ -338,13 +339,9 @@ void exit_thread(void)
{
}
static void default_fp_init(union fp_state *fp)
{
memset(fp, 0, sizeof(union fp_state));
}
ATOMIC_NOTIFIER_HEAD(thread_notify_head);
void (*fp_init)(union fp_state *) = default_fp_init;
EXPORT_SYMBOL(fp_init);
EXPORT_SYMBOL_GPL(thread_notify_head);
void flush_thread(void)
{
......@@ -353,22 +350,21 @@ void flush_thread(void)
memset(thread->used_cp, 0, sizeof(thread->used_cp));
memset(&tsk->thread.debug, 0, sizeof(struct debug_info));
memset(&thread->fpstate, 0, sizeof(union fp_state));
thread_notify(THREAD_NOTIFY_FLUSH, thread);
#if defined(CONFIG_IWMMXT)
iwmmxt_task_release(thread);
#endif
fp_init(&thread->fpstate);
#if defined(CONFIG_VFP)
vfp_flush_thread(&thread->vfpstate);
#endif
}
void release_thread(struct task_struct *dead_task)
{
#if defined(CONFIG_VFP)
vfp_release_thread(&task_thread_info(dead_task)->vfpstate);
#endif
struct thread_info *thread = task_thread_info(dead_task);
thread_notify(THREAD_NOTIFY_RELEASE, thread);
#if defined(CONFIG_IWMMXT)
iwmmxt_task_release(task_thread_info(dead_task));
iwmmxt_task_release(thread);
#endif
}
......
......@@ -665,17 +665,33 @@ static int do_signal(sigset_t *oldset, struct pt_regs *regs, int syscall)
if (syscall) {
if (regs->ARM_r0 == -ERESTART_RESTARTBLOCK) {
if (thumb_mode(regs)) {
regs->ARM_r7 = __NR_restart_syscall;
regs->ARM_r7 = __NR_restart_syscall - __NR_SYSCALL_BASE;
regs->ARM_pc -= 2;
} else {
#if defined(CONFIG_AEABI) && !defined(CONFIG_OABI_COMPAT)
regs->ARM_r7 = __NR_restart_syscall;
regs->ARM_pc -= 4;
#else
u32 __user *usp;
u32 swival = __NR_restart_syscall;
regs->ARM_sp -= 12;
usp = (u32 __user *)regs->ARM_sp;
/*
* Either we supports OABI only, or we have
* EABI with the OABI compat layer enabled.
* In the later case we don't know if user
* space is EABI or not, and if not we must
* not clobber r7. Always using the OABI
* syscall solves that issue and works for
* all those cases.
*/
swival = swival - __NR_SYSCAll_BASE + __NR_OABI_SYSCALL_BASE;
put_user(regs->ARM_pc, &usp[0]);
/* swi __NR_restart_syscall */
put_user(0xef000000 | __NR_restart_syscall, &usp[1]);
put_user(0xef000000 | swival, &usp[1]);
/* ldr pc, [sp], #12 */
put_user(0xe49df00c, &usp[2]);
......@@ -683,6 +699,7 @@ static int do_signal(sigset_t *oldset, struct pt_regs *regs, int syscall)
(unsigned long)(usp + 3));
regs->ARM_pc = regs->ARM_sp + 4;
#endif
}
}
if (regs->ARM_r0 == -ERESTARTNOHAND ||
......
......@@ -103,7 +103,8 @@ static int ep93xx_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
write_seqlock(&xtime_lock);
__raw_writel(1, EP93XX_TIMER1_CLEAR);
while (__raw_readl(EP93XX_TIMER4_VALUE_LOW) - last_jiffy_time
while ((signed long)
(__raw_readl(EP93XX_TIMER4_VALUE_LOW) - last_jiffy_time)
>= TIMER4_TICKS_PER_JIFFY) {
last_jiffy_time += TIMER4_TICKS_PER_JIFFY;
timer_tick(regs);
......@@ -124,7 +125,7 @@ static void __init ep93xx_timer_init(void)
{
/* Enable periodic HZ timer. */
__raw_writel(0x48, EP93XX_TIMER1_CONTROL);
__raw_writel((508000 / HZ) - 1, EP93XX_TIMER1_LOAD);
__raw_writel((508469 / HZ) - 1, EP93XX_TIMER1_LOAD);
__raw_writel(0xc8, EP93XX_TIMER1_CONTROL);
/* Enable lost jiffy timer. */
......
......@@ -16,16 +16,38 @@
#include <linux/mm.h>
#include <linux/sched.h>
#include <linux/interrupt.h>
#include <linux/ioport.h>
#include <linux/mtd/physmap.h>
#include <linux/platform_device.h>
#include <asm/io.h>
#include <asm/hardware.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
static struct physmap_flash_data gesbc9312_flash_data = {
.width = 4,
};
static struct resource gesbc9312_flash_resource = {
.start = 0x60000000,
.end = 0x60800000,
.flags = IORESOURCE_MEM,
};
static struct platform_device gesbc9312_flash = {
.name = "physmap-flash",
.id = 0,
.dev = {
.platform_data = &gesbc9312_flash_data,
},
.num_resources = 1,
.resource = &gesbc9312_flash_resource,
};
static void __init gesbc9312_init_machine(void)
{
ep93xx_init_devices();
physmap_configure(0x60000000, 0x00800000, 4, NULL);
platform_device_register(&gesbc9312_flash);
}
MACHINE_START(GESBC9312, "Glomation GESBC-9312-sx")
......
......@@ -16,6 +16,7 @@
#include <linux/mm.h>
#include <linux/sched.h>
#include <linux/interrupt.h>
#include <linux/ioport.h>
#include <linux/mtd/physmap.h>
#include <linux/platform_device.h>
#include <linux/m48t86.h>
......@@ -111,6 +112,26 @@ static void __init ts72xx_map_io(void)
}
}
static struct physmap_flash_data ts72xx_flash_data = {
.width = 1,
};
static struct resource ts72xx_flash_resource = {
.start = TS72XX_NOR_PHYS_BASE,
.end = TS72XX_NOR_PHYS_BASE + 0x01000000,
.flags = IORESOURCE_MEM,
};
static struct platform_device ts72xx_flash = {
.name = "physmap-flash",
.id = 0,
.dev = {
.platform_data = &ts72xx_flash_data,
},
.num_resources = 1,
.resource = &ts72xx_flash_resource,
};
static unsigned char ts72xx_rtc_readbyte(unsigned long addr)
{
__raw_writeb(addr, TS72XX_RTC_INDEX_VIRT_BASE);
......@@ -141,7 +162,7 @@ static void __init ts72xx_init_machine(void)
{
ep93xx_init_devices();
if (board_is_ts7200())
physmap_configure(TS72XX_NOR_PHYS_BASE, 0x01000000, 1, NULL);
platform_device_register(&ts72xx_flash);
platform_device_register(&ts72xx_rtc_device);
}
......
......@@ -15,6 +15,9 @@
* Changed to support scatter gather DMA
* by taking Russell's code from RiscPC
*
* 2006-05-31 Pavel Pisa <pisa@cmp.felk.cvut.cz>
* Corrected error handling code.
*
*/
#undef DEBUG
......@@ -277,7 +280,7 @@ imx_dma_setup_sg(imx_dmach_t dma_ch,
int
imx_dma_setup_handlers(imx_dmach_t dma_ch,
void (*irq_handler) (int, void *, struct pt_regs *),
void (*err_handler) (int, void *, struct pt_regs *),
void (*err_handler) (int, void *, struct pt_regs *, int),
void *data)
{
struct imx_dma_channel *imxdma = &imx_dma_channels[dma_ch];
......@@ -463,43 +466,53 @@ static irqreturn_t dma_err_handler(int irq, void *dev_id, struct pt_regs *regs)
int i, disr = DISR;
struct imx_dma_channel *channel;
unsigned int err_mask = DBTOSR | DRTOSR | DSESR | DBOSR;
int errcode;
DISR = disr;
DISR = disr & err_mask;
for (i = 0; i < IMX_DMA_CHANNELS; i++) {
channel = &imx_dma_channels[i];
if ((err_mask & 1 << i) && channel->name
&& channel->err_handler) {
channel->err_handler(i, channel->data, regs);
if(!(err_mask & (1 << i)))
continue;
}
imx_dma_channels[i].sg = NULL;
channel = &imx_dma_channels[i];
errcode = 0;
if (DBTOSR & (1 << i)) {
printk(KERN_WARNING
"Burst timeout on channel %d (%s)\n",
i, channel->name);
DBTOSR |= (1 << i);
DBTOSR = (1 << i);
errcode |= IMX_DMA_ERR_BURST;
}
if (DRTOSR & (1 << i)) {
printk(KERN_WARNING
"Request timeout on channel %d (%s)\n",
i, channel->name);
DRTOSR |= (1 << i);
DRTOSR = (1 << i);
errcode |= IMX_DMA_ERR_REQUEST;
}
if (DSESR & (1 << i)) {
printk(KERN_WARNING
"Transfer timeout on channel %d (%s)\n",
i, channel->name);
DSESR |= (1 << i);
DSESR = (1 << i);
errcode |= IMX_DMA_ERR_TRANSFER;
}
if (DBOSR & (1 << i)) {
printk(KERN_WARNING
"Buffer overflow timeout on channel %d (%s)\n",
i, channel->name);
DBOSR |= (1 << i);
DBOSR = (1 << i);
errcode |= IMX_DMA_ERR_BUFFER;
}
/*
* The cleaning of @sg field would be questionable
* there, because its value can help to compute
* remaining/transfered bytes count in the handler
*/
/*imx_dma_channels[i].sg = NULL;*/
if (channel->name && channel->err_handler) {
channel->err_handler(i, channel->data, regs, errcode);
continue;
}
imx_dma_channels[i].sg = NULL;
printk(KERN_WARNING
"DMA timeout on channel %d (%s) -%s%s%s%s\n",
i, channel->name,
errcode&IMX_DMA_ERR_BURST? " burst":"",
errcode&IMX_DMA_ERR_REQUEST? " request":"",
errcode&IMX_DMA_ERR_TRANSFER? " transfer":"",
errcode&IMX_DMA_ERR_BUFFER? " buffer":"");
}
return IRQ_HANDLED;
}
......
......@@ -211,7 +211,8 @@ static int ixp2000_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
/* clear timer 1 */
ixp2000_reg_wrb(IXP2000_T1_CLR, 1);
while ((next_jiffy_time - *missing_jiffy_timer_csr) > ticks_per_jiffy) {
while ((signed long)(next_jiffy_time - *missing_jiffy_timer_csr)
>= ticks_per_jiffy) {
timer_tick(regs);
next_jiffy_time -= ticks_per_jiffy;
}
......
......@@ -334,7 +334,7 @@ void __init ixp23xx_init_irq(void)
/*************************************************************************
* Timer-tick functions for IXP23xx
*************************************************************************/
#define CLOCK_TICKS_PER_USEC CLOCK_TICK_RATE / (USEC_PER_SEC)
#define CLOCK_TICKS_PER_USEC (CLOCK_TICK_RATE / USEC_PER_SEC)
static unsigned long next_jiffy_time;
......@@ -353,7 +353,7 @@ ixp23xx_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
/* Clear Pending Interrupt by writing '1' to it */
*IXP23XX_TIMER_STATUS = IXP23XX_TIMER1_INT_PEND;
while ((*IXP23XX_TIMER_CONT - next_jiffy_time) > LATCH) {
while ((signed long)(*IXP23XX_TIMER_CONT - next_jiffy_time) >= LATCH) {
timer_tick(regs);
next_jiffy_time += LATCH;
}
......@@ -439,5 +439,6 @@ static struct platform_device *ixp23xx_devices[] __initdata = {
void __init ixp23xx_sys_init(void)
{
*IXP23XX_EXP_UNIT_FUSE |= 0xf;
platform_add_devices(ixp23xx_devices, ARRAY_SIZE(ixp23xx_devices));
}
......@@ -53,9 +53,29 @@ static int __init espresso_pci_init(void)
};
subsys_initcall(espresso_pci_init);
static struct physmap_flash_data espresso_flash_data = {
.width = 2,
};
static struct resource espresso_flash_resource = {
.start = 0x90000000,
.end = 0x92000000,
.flags = IORESOURCE_MEM,
};
static struct platform_device espresso_flash = {
.name = "physmap-flash",
.id = 0,
.dev = {
.platform_data = &espresso_flash_data,
},
.num_resources = 1,
.resource = &espresso_flash_resource,
};
static void __init espresso_init(void)
{
physmap_configure(0x90000000, 0x02000000, 2, NULL);
platform_device_register(&espresso_flash);
/*
* Mark flash as writeable.
......
......@@ -298,9 +298,29 @@ static void __init ixdp2351_map_io(void)
iotable_init(ixdp2351_io_desc, ARRAY_SIZE(ixdp2351_io_desc));
}
static struct physmap_flash_data ixdp2351_flash_data = {
.width = 1,
};
static struct resource ixdp2351_flash_resource = {
.start = 0x90000000,
.end = 0x94000000,
.flags = IORESOURCE_MEM,
};
static struct platform_device ixdp2351_flash = {
.name = "physmap-flash",
.id = 0,
.dev = {
.platform_data = &ixdp2351_flash_data,
},
.num_resources = 1,
.resource = &ixdp2351_flash_resource,
};
static void __init ixdp2351_init(void)
{
physmap_configure(0x90000000, 0x04000000, 1, NULL);
platform_device_register(&ixdp2351_flash);
/*
* Mark flash as writeable
......
......@@ -137,9 +137,29 @@ static int __init roadrunner_pci_init(void)
subsys_initcall(roadrunner_pci_init);
static struct physmap_flash_data roadrunner_flash_data = {
.width = 2,
};
static struct resource roadrunner_flash_resource = {
.start = 0x90000000,
.end = 0x94000000,
.flags = IORESOURCE_MEM,
};
static struct platform_device roadrunner_flash = {
.name = "physmap-flash",
.id = 0,
.dev = {
.platform_data = &roadrunner_flash_data,
},
.num_resources = 1,
.resource = &roadrunner_flash_resource,
};
static void __init roadrunner_init(void)
{
physmap_configure(0x90000000, 0x04000000, 2, NULL);
platform_device_register(&roadrunner_flash);
/*
* Mark flash as writeable
......
......@@ -276,7 +276,7 @@ static irqreturn_t ixp4xx_timer_interrupt(int irq, void *dev_id, struct pt_regs
/*
* Catch up with the real idea of time
*/
while ((*IXP4XX_OSTS - last_jiffy_time) > LATCH) {
while ((signed long)(*IXP4XX_OSTS - last_jiffy_time) >= LATCH) {
timer_tick(regs);
last_jiffy_time += LATCH;
}
......
......@@ -15,6 +15,7 @@
#include <linux/kernel.h>
#include <linux/serial.h>
#include <linux/serial_8250.h>
#include <linux/leds.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
......@@ -37,6 +38,36 @@ static struct platform_device nas100d_flash = {
.resource = &nas100d_flash_resource,
};
#ifdef CONFIG_LEDS_IXP4XX
static struct resource nas100d_led_resources[] = {
{
.name = "wlan", /* green led */
.start = 0,
.end = 0,
.flags = IXP4XX_GPIO_LOW,
},
{
.name = "ready", /* blue power led (off is flashing!) */
.start = 15,
.end = 15,
.flags = IXP4XX_GPIO_LOW,
},
{
.name = "disk", /* yellow led */
.start = 3,
.end = 3,
.flags = IXP4XX_GPIO_LOW,
},
};
static struct platform_device nas100d_leds = {
.name = "IXP4XX-GPIO-LED",
.id = -1,
.num_resources = ARRAY_SIZE(nas100d_led_resources),
.resource = nas100d_led_resources,
};
#endif
static struct ixp4xx_i2c_pins nas100d_i2c_gpio_pins = {
.sda_pin = NAS100D_SDA_PIN,
.scl_pin = NAS100D_SCL_PIN,
......@@ -95,7 +126,9 @@ static struct platform_device nas100d_uart = {
static struct platform_device *nas100d_devices[] __initdata = {
&nas100d_i2c_controller,
&nas100d_flash,
&nas100d_uart,
#ifdef CONFIG_LEDS_IXP4XX
&nas100d_leds,
#endif
};
static void nas100d_power_off(void)
......@@ -122,6 +155,12 @@ static void __init nas100d_init(void)
pm_power_off = nas100d_power_off;
/* This is only useful on a modified machine, but it is valuable
* to have it first in order to see debug messages, and so that
* it does *not* get removed if platform_add_devices fails!
*/
(void)platform_device_register(&nas100d_uart);
platform_add_devices(nas100d_devices, ARRAY_SIZE(nas100d_devices));
}
......
......@@ -7,6 +7,7 @@
* Copyright (C) 2003-2004 MontaVista Software, Inc.
*
* Author: Mark Rakes <mrakes at mac.com>
* Author: Rod Whitby <rod@whitby.id.au>
* Maintainers: http://www.nslu2-linux.org/
*
* Fixed missing init_time in MACHINE_START kas11 10/22/04
......@@ -16,6 +17,7 @@
#include <linux/kernel.h>
#include <linux/serial.h>
#include <linux/serial_8250.h>
#include <linux/leds.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
......@@ -43,6 +45,42 @@ static struct ixp4xx_i2c_pins nslu2_i2c_gpio_pins = {
.scl_pin = NSLU2_SCL_PIN,
};
#ifdef CONFIG_LEDS_IXP4XX
static struct resource nslu2_led_resources[] = {
{
.name = "ready", /* green led */
.start = NSLU2_LED_GRN,
.end = NSLU2_LED_GRN,
.flags = IXP4XX_GPIO_HIGH,
},
{
.name = "status", /* red led */
.start = NSLU2_LED_RED,
.end = NSLU2_LED_RED,
.flags = IXP4XX_GPIO_HIGH,
},
{
.name = "disk-1",
.start = NSLU2_LED_DISK1,
.end = NSLU2_LED_DISK1,
.flags = IXP4XX_GPIO_LOW,
},
{
.name = "disk-2",
.start = NSLU2_LED_DISK2,
.end = NSLU2_LED_DISK2,
.flags = IXP4XX_GPIO_LOW,
},
};
static struct platform_device nslu2_leds = {
.name = "IXP4XX-GPIO-LED",
.id = -1,
.num_resources = ARRAY_SIZE(nslu2_led_resources),
.resource = nslu2_led_resources,
};
#endif
static struct platform_device nslu2_i2c_controller = {
.name = "IXP4XX-I2C",
.id = 0,
......@@ -102,8 +140,10 @@ static struct platform_device nslu2_uart = {
static struct platform_device *nslu2_devices[] __initdata = {
&nslu2_i2c_controller,
&nslu2_flash,
&nslu2_uart,
&nslu2_beeper,
#ifdef CONFIG_LEDS_IXP4XX
&nslu2_leds,
#endif
};
static void nslu2_power_off(void)
......@@ -127,6 +167,12 @@ static void __init nslu2_init(void)
pm_power_off = nslu2_power_off;
/* This is only useful on a modified machine, but it is valuable
* to have it first in order to see debug messages, and so that
* it does *not* get removed if platform_add_devices fails!
*/
(void)platform_device_register(&nslu2_uart);
platform_add_devices(nslu2_devices, ARRAY_SIZE(nslu2_devices));
}
......
......@@ -767,6 +767,54 @@ static struct clk *onchip_clks[] = {
&uart6_ck,
};
static int local_clk_enable(struct clk *clk)
{
int ret = 0;
if (!(clk->flags & FIXED_RATE) && !clk->rate && clk->set_rate
&& clk->user_rate)
ret = clk->set_rate(clk, clk->user_rate);
return ret;
}
static void local_clk_disable(struct clk *clk)
{
if (!(clk->flags & FIXED_RATE) && clk->rate && clk->set_rate)
clk->set_rate(clk, 0);
}
static void local_clk_unuse(struct clk *clk)
{
if (clk->usecount > 0 && !(--clk->usecount)) {
local_clk_disable(clk);
if (clk->parent)
local_clk_unuse(clk->parent);
}
}
static int local_clk_use(struct clk *clk)
{
int ret = 0;
if (clk->usecount++ == 0) {
if (clk->parent)
ret = local_clk_use(clk->parent);
if (ret != 0) {
clk->usecount--;
goto out;
}
ret = local_clk_enable(clk);
if (ret != 0 && clk->parent) {
local_clk_unuse(clk->parent);
clk->usecount--;
}
}
out:
return ret;
}
static int local_set_rate(struct clk *clk, u32 rate)
{
int ret = -EINVAL;
......@@ -847,28 +895,12 @@ unsigned long clk_get_rate(struct clk *clk)
}
EXPORT_SYMBOL(clk_get_rate);
static int local_clk_enable(struct clk *clk)
{
int ret = 0;
if (!(clk->flags & FIXED_RATE) && !clk->rate && clk->set_rate
&& clk->user_rate)
ret = clk->set_rate(clk, clk->user_rate);
return ret;
}
static void local_clk_disable(struct clk *clk)
{
if (!(clk->flags & FIXED_RATE) && clk->rate && clk->set_rate)
clk->set_rate(clk, 0);
}
int clk_enable(struct clk *clk)
{
int ret = 0;
clock_lock();
ret = local_clk_enable(clk);
ret = local_clk_use(clk);
clock_unlock();
return ret;
}
......@@ -877,71 +909,12 @@ EXPORT_SYMBOL(clk_enable);
void clk_disable(struct clk *clk)
{
clock_lock();
local_clk_disable(clk);
clock_unlock();
}
EXPORT_SYMBOL(clk_disable);
static void local_clk_unuse(struct clk *clk)
{
if (clk->usecount > 0 && !(--clk->usecount)) {
local_clk_disable(clk);
if (clk->parent)
local_clk_unuse(clk->parent);
}
}
static int local_clk_use(struct clk *clk)
{
int ret = 0;
if (clk->usecount++ == 0) {
if (clk->parent)
ret = local_clk_use(clk->parent);
if (ret != 0) {
clk->usecount--;
goto out;
}
ret = local_clk_enable(clk);
if (ret != 0 && clk->parent) {
local_clk_unuse(clk->parent);
clk->usecount--;
}
}
out:
return ret;
}
/* The main purpose of clk_use ans clk_unuse functions
* is to control switching 13MHz oscillator and PLL1 (13'MHz),
* so that they are disabled whenever none of PLL2-5 is using them.
* Although in theory these functions should work with any clock,
* please use them only on PLL2 - PLL5 to avoid confusion.
*/
int clk_use(struct clk *clk)
{
int ret = 0;
clock_lock();
ret = local_clk_use(clk);
clock_unlock();
return ret;
}
EXPORT_SYMBOL(clk_use);
void clk_unuse(struct clk *clk)
{
clock_lock();
local_clk_unuse(clk);
clock_unlock();
}
EXPORT_SYMBOL(clk_unuse);
EXPORT_SYMBOL(clk_disable);
long clk_round_rate(struct clk *clk, unsigned long rate)
{
......@@ -995,7 +968,7 @@ static int __init clk_init(void)
__FUNCTION__, (*clkp)->name, (*clkp)->rate);
}
clk_use(&ck_pll4);
local_clk_use(&ck_pll4);
/* if ck_13MHz is not used, disable it. */
if (ck_13MHz.usecount == 0)
......
......@@ -20,7 +20,7 @@
#include <linux/serial_core.h>
#include <linux/serial_reg.h>
#include <asm/arch/pm.h>
#include <asm/arch/gpio.h>
#include <asm/arch/clock.h>
......
......@@ -114,9 +114,15 @@ config MACH_NEXCODER_2440
endmenu
config S3C2410_CLOCK
bool
help
Clock code for the S3C2410, and similar processors
config CPU_S3C2410
bool
depends on ARCH_S3C2410
select S3C2410_CLOCK
help
Support for S3C2410 and S3C2410A family from the S3C24XX line
of Samsung Mobile CPUs.
......@@ -130,6 +136,7 @@ config CPU_S3C244X
config CPU_S3C2440
bool
depends on ARCH_S3C2410
select S3C2410_CLOCK
select CPU_S3C244X
help
Support for S3C2440 Samsung Mobile CPU based systems.
......@@ -137,6 +144,7 @@ config CPU_S3C2440
config CPU_S3C2442
bool
depends on ARCH_S3C2420
select S3C2410_CLOCK
select CPU_S3C244X
help
Support for S3C2442 Samsung Mobile CPU based systems.
......
......@@ -29,6 +29,10 @@ obj-$(CONFIG_PM_SIMTEC) += pm-simtec.o
obj-$(CONFIG_CPU_S3C244X) += s3c244x.o
obj-$(CONFIG_CPU_S3C244X) += s3c244x-irq.o
# Clock control
obj-$(CONFIG_S3C2410_CLOCK) += s3c2410-clock.o
# S3C2440 support
obj-$(CONFIG_CPU_S3C2440) += s3c2440.o s3c2440-dsc.o
......
......@@ -3,7 +3,7 @@
* Copyright (c) 2004-2005 Simtec Electronics
* Ben Dooks <ben@simtec.co.uk>
*
* S3C2410 Clock control support
* S3C24XX Core clock control support
*
* Based on, and code from linux/arch/arm/mach-versatile/clock.c
**
......@@ -56,25 +56,6 @@ static LIST_HEAD(clocks);
DEFINE_MUTEX(clocks_mutex);
/* old functions */
void inline s3c24xx_clk_enable(unsigned int clocks, unsigned int enable)
{
unsigned long clkcon;
clkcon = __raw_readl(S3C2410_CLKCON);
if (enable)
clkcon |= clocks;
else
clkcon &= ~clocks;
/* ensure none of the special function bits set */
clkcon &= ~(S3C2410_CLKCON_IDLE|S3C2410_CLKCON_POWER | 3);
__raw_writel(clkcon, S3C2410_CLKCON);
}
/* enable and disable calls for use with the clk struct */
static int clk_null_enable(struct clk *clk, int enable)
......@@ -82,12 +63,6 @@ static int clk_null_enable(struct clk *clk, int enable)
return 0;
}
int s3c24xx_clkcon_enable(struct clk *clk, int enable)
{
s3c24xx_clk_enable(clk->ctrlbit, enable);
return 0;
}
/* Clock API calls */
struct clk *clk_get(struct device *dev, const char *id)
......@@ -173,8 +148,11 @@ unsigned long clk_get_rate(struct clk *clk)
if (clk->rate != 0)
return clk->rate;
while (clk->parent != NULL && clk->rate == 0)
clk = clk->parent;
if (clk->get_rate != NULL)
return (clk->get_rate)(clk);
if (clk->parent != NULL)
return clk_get_rate(clk->parent);
return clk->rate;
}
......@@ -233,28 +211,6 @@ EXPORT_SYMBOL(clk_set_rate);
EXPORT_SYMBOL(clk_get_parent);
EXPORT_SYMBOL(clk_set_parent);
/* base clock enable */
static int s3c24xx_upll_enable(struct clk *clk, int enable)
{
unsigned long clkslow = __raw_readl(S3C2410_CLKSLOW);
unsigned long orig = clkslow;
if (enable)
clkslow &= ~S3C2410_CLKSLOW_UCLK_OFF;
else
clkslow |= S3C2410_CLKSLOW_UCLK_OFF;
__raw_writel(clkslow, S3C2410_CLKSLOW);
/* if we started the UPLL, then allow to settle */
if (enable && (orig & S3C2410_CLKSLOW_UCLK_OFF))
udelay(200);
return 0;
}
/* base clocks */
static struct clk clk_xtal = {
......@@ -265,15 +221,14 @@ static struct clk clk_xtal = {
.ctrlbit = 0,
};
static struct clk clk_upll = {
struct clk clk_upll = {
.name = "upll",
.id = -1,
.parent = NULL,
.enable = s3c24xx_upll_enable,
.ctrlbit = 0,
};
static struct clk clk_f = {
struct clk clk_f = {
.name = "fclk",
.id = -1,
.rate = 0,
......@@ -281,7 +236,7 @@ static struct clk clk_f = {
.ctrlbit = 0,
};
static struct clk clk_h = {
struct clk clk_h = {
.name = "hclk",
.id = -1,
.rate = 0,
......@@ -289,7 +244,7 @@ static struct clk clk_h = {
.ctrlbit = 0,
};
static struct clk clk_p = {
struct clk clk_p = {
.name = "pclk",
.id = -1,
.rate = 0,
......@@ -426,108 +381,6 @@ struct clk s3c24xx_uclk = {
.id = -1,
};
/* standard clock definitions */
static struct clk init_clocks[] = {
{
.name = "nand",
.id = -1,
.parent = &clk_h,
.enable = s3c24xx_clkcon_enable,
.ctrlbit = S3C2410_CLKCON_NAND,
}, {
.name = "lcd",
.id = -1,
.parent = &clk_h,
.enable = s3c24xx_clkcon_enable,
.ctrlbit = S3C2410_CLKCON_LCDC,
}, {
.name = "usb-host",
.id = -1,
.parent = &clk_h,
.enable = s3c24xx_clkcon_enable,
.ctrlbit = S3C2410_CLKCON_USBH,
}, {
.name = "usb-device",
.id = -1,
.parent = &clk_h,
.enable = s3c24xx_clkcon_enable,
.ctrlbit = S3C2410_CLKCON_USBD,
}, {
.name = "timers",
.id = -1,
.parent = &clk_p,
.enable = s3c24xx_clkcon_enable,
.ctrlbit = S3C2410_CLKCON_PWMT,
}, {
.name = "sdi",
.id = -1,
.parent = &clk_p,
.enable = s3c24xx_clkcon_enable,
.ctrlbit = S3C2410_CLKCON_SDI,
}, {
.name = "uart",
.id = 0,
.parent = &clk_p,
.enable = s3c24xx_clkcon_enable,
.ctrlbit = S3C2410_CLKCON_UART0,
}, {
.name = "uart",
.id = 1,
.parent = &clk_p,
.enable = s3c24xx_clkcon_enable,
.ctrlbit = S3C2410_CLKCON_UART1,
}, {
.name = "uart",
.id = 2,
.parent = &clk_p,
.enable = s3c24xx_clkcon_enable,
.ctrlbit = S3C2410_CLKCON_UART2,
}, {
.name = "gpio",
.id = -1,
.parent = &clk_p,
.enable = s3c24xx_clkcon_enable,
.ctrlbit = S3C2410_CLKCON_GPIO,
}, {
.name = "rtc",
.id = -1,
.parent = &clk_p,
.enable = s3c24xx_clkcon_enable,
.ctrlbit = S3C2410_CLKCON_RTC,
}, {
.name = "adc",
.id = -1,
.parent = &clk_p,
.enable = s3c24xx_clkcon_enable,
.ctrlbit = S3C2410_CLKCON_ADC,
}, {
.name = "i2c",
.id = -1,
.parent = &clk_p,
.enable = s3c24xx_clkcon_enable,
.ctrlbit = S3C2410_CLKCON_IIC,
}, {
.name = "iis",
.id = -1,
.parent = &clk_p,
.enable = s3c24xx_clkcon_enable,
.ctrlbit = S3C2410_CLKCON_IIS,
}, {
.name = "spi",
.id = -1,
.parent = &clk_p,
.enable = s3c24xx_clkcon_enable,
.ctrlbit = S3C2410_CLKCON_SPI,
}, {
.name = "watchdog",
.id = -1,
.parent = &clk_p,
.ctrlbit = 0,
}
};
/* initialise the clock system */
int s3c24xx_register_clock(struct clk *clk)
......@@ -537,14 +390,6 @@ int s3c24xx_register_clock(struct clk *clk)
if (clk->enable == NULL)
clk->enable = clk_null_enable;
/* if this is a standard clock, set the usage state */
if (clk->ctrlbit && clk->enable == s3c24xx_clkcon_enable) {
unsigned long clkcon = __raw_readl(S3C2410_CLKCON);
clk->usage = (clkcon & clk->ctrlbit) ? 1 : 0;
}
/* add to the list of available clocks */
mutex_lock(&clocks_mutex);
......@@ -561,44 +406,17 @@ int __init s3c24xx_setup_clocks(unsigned long xtal,
unsigned long hclk,
unsigned long pclk)
{
unsigned long upllcon = __raw_readl(S3C2410_UPLLCON);
unsigned long clkslow = __raw_readl(S3C2410_CLKSLOW);
struct clk *clkp = init_clocks;
int ptr;
int ret;
printk(KERN_INFO "S3C2410 Clocks, (c) 2004 Simtec Electronics\n");
printk(KERN_INFO "S3C24XX Clocks, (c) 2004 Simtec Electronics\n");
/* initialise the main system clocks */
clk_xtal.rate = xtal;
clk_upll.rate = s3c2410_get_pll(upllcon, xtal);
clk_upll.rate = s3c2410_get_pll(__raw_readl(S3C2410_UPLLCON), xtal);
clk_h.rate = hclk;
clk_p.rate = pclk;
clk_f.rate = fclk;
/* We must be careful disabling the clocks we are not intending to
* be using at boot time, as subsytems such as the LCD which do
* their own DMA requests to the bus can cause the system to lockup
* if they where in the middle of requesting bus access.
*
* Disabling the LCD clock if the LCD is active is very dangerous,
* and therefore the bootloader should be careful to not enable
* the LCD clock if it is not needed.
*/
mutex_lock(&clocks_mutex);
s3c24xx_clk_enable(S3C2410_CLKCON_NAND, 0);
s3c24xx_clk_enable(S3C2410_CLKCON_USBH, 0);
s3c24xx_clk_enable(S3C2410_CLKCON_USBD, 0);
s3c24xx_clk_enable(S3C2410_CLKCON_ADC, 0);
s3c24xx_clk_enable(S3C2410_CLKCON_IIC, 0);
s3c24xx_clk_enable(S3C2410_CLKCON_SPI, 0);
mutex_unlock(&clocks_mutex);
/* assume uart clocks are correctly setup */
/* register our clocks */
......@@ -618,27 +436,5 @@ int __init s3c24xx_setup_clocks(unsigned long xtal,
if (s3c24xx_register_clock(&clk_p) < 0)
printk(KERN_ERR "failed to register cpu pclk\n");
if (s3c24xx_register_clock(&clk_usb_bus) < 0)
printk(KERN_ERR "failed to register usb bus clock\n");
/* register clocks from clock array */
for (ptr = 0; ptr < ARRAY_SIZE(init_clocks); ptr++, clkp++) {
ret = s3c24xx_register_clock(clkp);
if (ret < 0) {
printk(KERN_ERR "Failed to register clock %s (%d)\n",
clkp->name, ret);
}
}
/* show the clock-slow value */
printk("CLOCK: Slow mode (%ld.%ld MHz), %s, MPLL %s, UPLL %s\n",
print_mhz(xtal / ( 2 * S3C2410_CLKSLOW_GET_SLOWVAL(clkslow))),
(clkslow & S3C2410_CLKSLOW_SLOW) ? "slow" : "fast",
(clkslow & S3C2410_CLKSLOW_MPLL_OFF) ? "off" : "on",
(clkslow & S3C2410_CLKSLOW_UCLK_OFF) ? "off" : "on");
return 0;
}
......@@ -22,6 +22,7 @@ struct clk {
int (*enable)(struct clk *, int enable);
int (*set_rate)(struct clk *c, unsigned long rate);
unsigned long (*get_rate)(struct clk *c);
unsigned long (*round_rate)(struct clk *c, unsigned long rate);
int (*set_parent)(struct clk *c, struct clk *parent);
};
......@@ -36,6 +37,13 @@ extern struct clk s3c24xx_uclk;
extern struct clk clk_usb_bus;
/* core clock support */
extern struct clk clk_f;
extern struct clk clk_h;
extern struct clk clk_p;
extern struct clk clk_upll;
/* exports for arch/arm/mach-s3c2410
*
* Please DO NOT use these outside of arch/arm/mach-s3c2410
......@@ -43,7 +51,8 @@ extern struct clk clk_usb_bus;
extern struct mutex clocks_mutex;
extern int s3c24xx_clkcon_enable(struct clk *clk, int enable);
extern int s3c2410_clkcon_enable(struct clk *clk, int enable);
extern int s3c24xx_register_clock(struct clk *clk);
extern int s3c24xx_setup_clocks(unsigned long xtal,
......
......@@ -73,5 +73,6 @@ extern struct sys_timer s3c24xx_timer;
/* system device classes */
extern struct sysdev_class s3c2410_sysclass;
extern struct sysdev_class s3c2440_sysclass;
extern struct sysdev_class s3c2442_sysclass;
/* linux/arch/arm/mach-s3c2410/clock.c
*
* Copyright (c) 2006 Simtec Electronics
* Ben Dooks <ben@simtec.co.uk>
*
* S3C2410,S3C2440,S3C2442 Clock control support
*
* 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/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/list.h>
#include <linux/errno.h>
#include <linux/err.h>
#include <linux/sysdev.h>
#include <linux/clk.h>
#include <linux/mutex.h>
#include <linux/delay.h>
#include <asm/hardware.h>
#include <asm/io.h>
#include <asm/arch/regs-clock.h>
#include <asm/arch/regs-gpio.h>
#include "clock.h"
#include "cpu.h"
int s3c2410_clkcon_enable(struct clk *clk, int enable)
{
unsigned int clocks = clk->ctrlbit;
unsigned long clkcon;
clkcon = __raw_readl(S3C2410_CLKCON);
if (enable)
clkcon |= clocks;
else
clkcon &= ~clocks;
/* ensure none of the special function bits set */
clkcon &= ~(S3C2410_CLKCON_IDLE|S3C2410_CLKCON_POWER);
__raw_writel(clkcon, S3C2410_CLKCON);
return 0;
}
static int s3c2410_upll_enable(struct clk *clk, int enable)
{
unsigned long clkslow = __raw_readl(S3C2410_CLKSLOW);
unsigned long orig = clkslow;
if (enable)
clkslow &= ~S3C2410_CLKSLOW_UCLK_OFF;
else
clkslow |= S3C2410_CLKSLOW_UCLK_OFF;
__raw_writel(clkslow, S3C2410_CLKSLOW);
/* if we started the UPLL, then allow to settle */
if (enable && (orig & S3C2410_CLKSLOW_UCLK_OFF))
udelay(200);
return 0;
}
/* standard clock definitions */
static struct clk init_clocks_disable[] = {
{
.name = "nand",
.id = -1,
.parent = &clk_h,
.enable = s3c2410_clkcon_enable,
.ctrlbit = S3C2410_CLKCON_NAND,
}, {
.name = "sdi",
.id = -1,
.parent = &clk_p,
.enable = s3c2410_clkcon_enable,
.ctrlbit = S3C2410_CLKCON_SDI,
}, {
.name = "adc",
.id = -1,
.parent = &clk_p,
.enable = s3c2410_clkcon_enable,
.ctrlbit = S3C2410_CLKCON_ADC,
}, {
.name = "i2c",
.id = -1,
.parent = &clk_p,
.enable = s3c2410_clkcon_enable,
.ctrlbit = S3C2410_CLKCON_IIC,
}, {
.name = "iis",
.id = -1,
.parent = &clk_p,
.enable = s3c2410_clkcon_enable,
.ctrlbit = S3C2410_CLKCON_IIS,
}, {
.name = "spi",
.id = -1,
.parent = &clk_p,
.enable = s3c2410_clkcon_enable,
.ctrlbit = S3C2410_CLKCON_SPI,
}
};
static struct clk init_clocks[] = {
{
.name = "lcd",
.id = -1,
.parent = &clk_h,
.enable = s3c2410_clkcon_enable,
.ctrlbit = S3C2410_CLKCON_LCDC,
}, {
.name = "gpio",
.id = -1,
.parent = &clk_p,
.enable = s3c2410_clkcon_enable,
.ctrlbit = S3C2410_CLKCON_GPIO,
}, {
.name = "usb-host",
.id = -1,
.parent = &clk_h,
.enable = s3c2410_clkcon_enable,
.ctrlbit = S3C2410_CLKCON_USBH,
}, {
.name = "usb-device",
.id = -1,
.parent = &clk_h,
.enable = s3c2410_clkcon_enable,
.ctrlbit = S3C2410_CLKCON_USBD,
}, {
.name = "timers",
.id = -1,
.parent = &clk_p,
.enable = s3c2410_clkcon_enable,
.ctrlbit = S3C2410_CLKCON_PWMT,
}, {
.name = "uart",
.id = 0,
.parent = &clk_p,
.enable = s3c2410_clkcon_enable,
.ctrlbit = S3C2410_CLKCON_UART0,
}, {
.name = "uart",
.id = 1,
.parent = &clk_p,
.enable = s3c2410_clkcon_enable,
.ctrlbit = S3C2410_CLKCON_UART1,
}, {
.name = "uart",
.id = 2,
.parent = &clk_p,
.enable = s3c2410_clkcon_enable,
.ctrlbit = S3C2410_CLKCON_UART2,
}, {
.name = "rtc",
.id = -1,
.parent = &clk_p,
.enable = s3c2410_clkcon_enable,
.ctrlbit = S3C2410_CLKCON_RTC,
}, {
.name = "watchdog",
.id = -1,
.parent = &clk_p,
.ctrlbit = 0,
}
};
/* s3c2410_baseclk_add()
*
* Add all the clocks used by the s3c2410 or compatible CPUs
* such as the S3C2440 and S3C2442.
*
* We cannot use a system device as we are needed before any
* of the init-calls that initialise the devices are actually
* done.
*/
int __init s3c2410_baseclk_add(void)
{
unsigned long clkslow = __raw_readl(S3C2410_CLKSLOW);
unsigned long clkcon = __raw_readl(S3C2410_CLKCON);
struct clk *clkp;
struct clk *xtal;
int ret;
int ptr;
clk_upll.enable = s3c2410_upll_enable;
if (s3c24xx_register_clock(&clk_usb_bus) < 0)
printk(KERN_ERR "failed to register usb bus clock\n");
/* register clocks from clock array */
clkp = init_clocks;
for (ptr = 0; ptr < ARRAY_SIZE(init_clocks); ptr++, clkp++) {
/* ensure that we note the clock state */
clkp->usage = clkcon & clkp->ctrlbit ? 1 : 0;
ret = s3c24xx_register_clock(clkp);
if (ret < 0) {
printk(KERN_ERR "Failed to register clock %s (%d)\n",
clkp->name, ret);
}
}
/* We must be careful disabling the clocks we are not intending to
* be using at boot time, as subsytems such as the LCD which do
* their own DMA requests to the bus can cause the system to lockup
* if they where in the middle of requesting bus access.
*
* Disabling the LCD clock if the LCD is active is very dangerous,
* and therefore the bootloader should be careful to not enable
* the LCD clock if it is not needed.
*/
/* install (and disable) the clocks we do not need immediately */
clkp = init_clocks_disable;
for (ptr = 0; ptr < ARRAY_SIZE(init_clocks_disable); ptr++, clkp++) {
ret = s3c24xx_register_clock(clkp);
if (ret < 0) {
printk(KERN_ERR "Failed to register clock %s (%d)\n",
clkp->name, ret);
}
s3c2410_clkcon_enable(clkp, 0);
}
/* show the clock-slow value */
xtal = clk_get(NULL, "xtal");
printk("CLOCK: Slow mode (%ld.%ld MHz), %s, MPLL %s, UPLL %s\n",
print_mhz(clk_get_rate(xtal) /
( 2 * S3C2410_CLKSLOW_GET_SLOWVAL(clkslow))),
(clkslow & S3C2410_CLKSLOW_SLOW) ? "slow" : "fast",
(clkslow & S3C2410_CLKSLOW_MPLL_OFF) ? "off" : "on",
(clkslow & S3C2410_CLKSLOW_UCLK_OFF) ? "off" : "on");
return 0;
}
......@@ -27,6 +27,7 @@
#include <linux/list.h>
#include <linux/timer.h>
#include <linux/init.h>
#include <linux/sysdev.h>
#include <linux/platform_device.h>
#include <asm/mach/arch.h>
......@@ -108,11 +109,33 @@ void __init s3c2410_init_clocks(int xtal)
*/
s3c24xx_setup_clocks(xtal, fclk, hclk, pclk);
s3c2410_baseclk_add();
}
struct sysdev_class s3c2410_sysclass = {
set_kset_name("s3c2410-core"),
};
static struct sys_device s3c2410_sysdev = {
.cls = &s3c2410_sysclass,
};
/* need to register class before we actually register the device, and
* we also need to ensure that it has been initialised before any of the
* drivers even try to use it (even if not on an s3c2440 based system)
* as a driver which may support both 2410 and 2440 may try and use it.
*/
static int __init s3c2410_core_init(void)
{
return sysdev_class_register(&s3c2410_sysclass);
}
core_initcall(s3c2410_core_init);
int __init s3c2410_init(void)
{
printk("S3C2410: Initialising architecture\n");
return 0;
return sysdev_register(&s3c2410_sysdev);
}
......@@ -29,6 +29,8 @@ extern void s3c2410_init_uarts(struct s3c2410_uartcfg *cfg, int no);
extern void s3c2410_init_clocks(int xtal);
extern int s3c2410_baseclk_add(void);
#else
#define s3c2410_init_clocks NULL
#define s3c2410_init_uarts NULL
......
......@@ -91,7 +91,7 @@ static int s3c2440_camif_upll_setrate(struct clk *clk, unsigned long rate)
static struct clk s3c2440_clk_cam = {
.name = "camif",
.id = -1,
.enable = s3c24xx_clkcon_enable,
.enable = s3c2410_clkcon_enable,
.ctrlbit = S3C2440_CLKCON_CAMERA,
};
......@@ -105,7 +105,7 @@ static struct clk s3c2440_clk_cam_upll = {
static struct clk s3c2440_clk_ac97 = {
.name = "ac97",
.id = -1,
.enable = s3c24xx_clkcon_enable,
.enable = s3c2410_clkcon_enable,
.ctrlbit = S3C2440_CLKCON_CAMERA,
};
......
......@@ -102,7 +102,7 @@ static int s3c2442_camif_upll_setrate(struct clk *clk, unsigned long rate)
static struct clk s3c2442_clk_cam = {
.name = "camif",
.id = -1,
.enable = s3c24xx_clkcon_enable,
.enable = s3c2410_clkcon_enable,
.ctrlbit = S3C2440_CLKCON_CAMERA,
};
......
......@@ -34,6 +34,7 @@
#include <asm/arch/regs-gpioj.h>
#include <asm/arch/regs-dsc.h>
#include "s3c2410.h"
#include "s3c2440.h"
#include "s3c244x.h"
#include "clock.h"
......@@ -118,6 +119,7 @@ void __init s3c244x_init_clocks(int xtal)
*/
s3c24xx_setup_clocks(xtal, fclk, hclk, pclk);
s3c2410_baseclk_add();
}
#ifdef CONFIG_PM
......
......@@ -33,7 +33,8 @@
#include <linux/signal.h>
#include <linux/sched.h>
#include <linux/init.h>
/* XXX */
#include <asm/thread_notify.h>
#include "softfloat.h"
#include "fpopcode.h"
......@@ -56,16 +57,28 @@ void fp_send_sig(unsigned long sig, struct task_struct *p, int priv);
extern char fpe_type[];
#endif
static int nwfpe_notify(struct notifier_block *self, unsigned long cmd, void *v)
{
struct thread_info *thread = v;
if (cmd == THREAD_NOTIFY_FLUSH)
nwfpe_init_fpa(&thread->fpstate);
return NOTIFY_DONE;
}
static struct notifier_block nwfpe_notifier_block = {
.notifier_call = nwfpe_notify,
};
/* kernel function prototypes required */
void fp_setup(void);
/* external declarations for saved kernel symbols */
extern void (*kern_fp_enter)(void);
extern void (*fp_init)(union fp_state *);
/* Original value of fp_enter from kernel before patched by fpe_init. */
static void (*orig_fp_enter)(void);
static void (*orig_fp_init)(union fp_state *);
/* forward declarations */
extern void nwfpe_enter(void);
......@@ -88,20 +101,20 @@ static int __init fpe_init(void)
printk(KERN_WARNING "NetWinder Floating Point Emulator V0.97 ("
NWFPE_BITS " precision)\n");
thread_register_notifier(&nwfpe_notifier_block);
/* Save pointer to the old FP handler and then patch ourselves in */
orig_fp_enter = kern_fp_enter;
orig_fp_init = fp_init;
kern_fp_enter = nwfpe_enter;
fp_init = nwfpe_init_fpa;
return 0;
}
static void __exit fpe_exit(void)
{
thread_unregister_notifier(&nwfpe_notifier_block);
/* Restore the values we saved earlier. */
kern_fp_enter = orig_fp_enter;
fp_init = orig_fp_init;
}
/*
......
......@@ -210,7 +210,8 @@ static irqreturn_t omap_32k_timer_interrupt(int irq, void *dev_id,
now = omap_32k_sync_timer_read();
while (now - omap_32k_last_tick >= OMAP_32K_TICKS_PER_HZ) {
while ((signed long)(now - omap_32k_last_tick)
>= OMAP_32K_TICKS_PER_HZ) {
omap_32k_last_tick += OMAP_32K_TICKS_PER_HZ;
timer_tick(regs);
}
......
......@@ -7,6 +7,9 @@
# EXTRA_CFLAGS := -DDEBUG
# EXTRA_AFLAGS := -DDEBUG
AFLAGS :=$(AFLAGS:-msoft-float=-Wa,-mfpu=softvfp+vfp)
LDFLAGS +=--no-warn-mismatch
obj-y += vfp.o
vfp-$(CONFIG_VFP) += entry.o vfpmodule.o vfphw.o vfpsingle.o vfpdouble.o
vfp-$(CONFIG_VFP) += vfpmodule.o entry.o vfphw.o vfpsingle.o vfpdouble.o
......@@ -192,7 +192,7 @@ vfp_get_double:
add pc, pc, r0, lsl #3
mov r0, r0
.irp dr,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
mrrc p11, 1, r0, r1, c\dr @ fmrrd r0, r1, d\dr
fmrrd r0, r1, d\dr
mov pc, lr
.endr
......@@ -206,6 +206,6 @@ vfp_put_double:
add pc, pc, r0, lsl #3
mov r0, r0
.irp dr,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
mcrr p11, 1, r1, r2, c\dr @ fmdrr r1, r2, d\dr
fmdrr d\dr, r1, r2
mov pc, lr
.endr
......@@ -15,6 +15,8 @@
#include <linux/signal.h>
#include <linux/sched.h>
#include <linux/init.h>
#include <asm/thread_notify.h>
#include <asm/vfp.h>
#include "vfpinstr.h"
......@@ -36,38 +38,55 @@ union vfp_state *last_VFP_context;
*/
unsigned int VFP_arch;
/*
* Per-thread VFP initialisation.
*/
void vfp_flush_thread(union vfp_state *vfp)
static int vfp_notifier(struct notifier_block *self, unsigned long cmd, void *v)
{
memset(vfp, 0, sizeof(union vfp_state));
struct thread_info *thread = v;
union vfp_state *vfp = &thread->vfpstate;
vfp->hard.fpexc = FPEXC_ENABLE;
vfp->hard.fpscr = FPSCR_ROUND_NEAREST;
switch (cmd) {
case THREAD_NOTIFY_FLUSH:
/*
* Per-thread VFP initialisation.
*/
memset(vfp, 0, sizeof(union vfp_state));
/*
* Disable VFP to ensure we initialise it first.
*/
fmxr(FPEXC, fmrx(FPEXC) & ~FPEXC_ENABLE);
vfp->hard.fpexc = FPEXC_ENABLE;
vfp->hard.fpscr = FPSCR_ROUND_NEAREST;
/*
* Ensure we don't try to overwrite our newly initialised
* state information on the first fault.
*/
if (last_VFP_context == vfp)
last_VFP_context = NULL;
}
/*
* Disable VFP to ensure we initialise it first.
*/
fmxr(FPEXC, fmrx(FPEXC) & ~FPEXC_ENABLE);
/*
* Per-thread VFP cleanup.
*/
void vfp_release_thread(union vfp_state *vfp)
{
if (last_VFP_context == vfp)
last_VFP_context = NULL;
/*
* FALLTHROUGH: Ensure we don't try to overwrite our newly
* initialised state information on the first fault.
*/
case THREAD_NOTIFY_RELEASE:
/*
* Per-thread VFP cleanup.
*/
if (last_VFP_context == vfp)
last_VFP_context = NULL;
break;
case THREAD_NOTIFY_SWITCH:
/*
* Always disable VFP so we can lazily save/restore the
* old state.
*/
fmxr(FPEXC, fmrx(FPEXC) & ~FPEXC_ENABLE);
break;
}
return NOTIFY_DONE;
}
static struct notifier_block vfp_notifier_block = {
.notifier_call = vfp_notifier,
};
/*
* Raise a SIGFPE for the current process.
* sicode describes the signal being raised.
......@@ -281,6 +300,8 @@ static int __init vfp_init(void)
(vfpsid & FPSID_VARIANT_MASK) >> FPSID_VARIANT_BIT,
(vfpsid & FPSID_REV_MASK) >> FPSID_REV_BIT);
vfp_vector = vfp_support_entry;
thread_register_notifier(&vfp_notifier_block);
}
return 0;
}
......
......@@ -269,7 +269,6 @@ static unsigned int serial_pxa_get_mctrl(struct uart_port *port)
unsigned char status;
unsigned int ret;
return TIOCM_CTS | TIOCM_DSR | TIOCM_CAR;
status = serial_in(up, UART_MSR);
ret = 0;
......
......@@ -46,7 +46,7 @@
struct imx_dma_channel {
const char *name;
void (*irq_handler) (int, void *, struct pt_regs *);
void (*err_handler) (int, void *, struct pt_regs *);
void (*err_handler) (int, void *, struct pt_regs *, int errcode);
void *data;
dmamode_t dma_mode;
struct scatterlist *sg;
......@@ -58,6 +58,10 @@ struct imx_dma_channel {
extern struct imx_dma_channel imx_dma_channels[IMX_DMA_CHANNELS];
#define IMX_DMA_ERR_BURST 1
#define IMX_DMA_ERR_REQUEST 2
#define IMX_DMA_ERR_TRANSFER 4
#define IMX_DMA_ERR_BUFFER 8
/* The type to distinguish channel numbers parameter from ordinal int type */
typedef int imx_dmach_t;
......@@ -74,7 +78,7 @@ imx_dma_setup_sg(imx_dmach_t dma_ch,
int
imx_dma_setup_handlers(imx_dmach_t dma_ch,
void (*irq_handler) (int, void *, struct pt_regs *),
void (*err_handler) (int, void *, struct pt_regs *), void *data);
void (*err_handler) (int, void *, struct pt_regs *, int), void *data);
void imx_dma_enable(imx_dmach_t dma_ch);
......
......@@ -124,6 +124,7 @@
#define IXP23XX_EXP_UNIT_FUSE IXP23XX_EXP_CFG_REG(0x28)
#define IXP23XX_EXP_MSF_MUX IXP23XX_EXP_CFG_REG(0x30)
#define IXP23XX_EXP_CFG_FUSE IXP23XX_EXP_CFG_REG(0x34)
#define IXP23XX_EXP_BUS_PHYS 0x90000000
#define IXP23XX_EXP_BUS_WINDOW_SIZE 0x01000000
......@@ -265,6 +266,8 @@
#define IXP23XX_PCI_UNIT_RESET (1 << 1)
#define IXP23XX_XSCALE_RESET (1 << 0)
#define IXP23XX_UENGINE_CSR_VIRT_BASE (IXP23XX_CAP_CSR_VIRT + 0x18000)
/****************************************************************************
* PCI CSRs.
......
......@@ -14,6 +14,21 @@
#ifndef __ASSEMBLY__
extern inline unsigned long ixp2000_reg_read(volatile void *reg)
{
return *((volatile unsigned long *)reg);
}
extern inline void ixp2000_reg_write(volatile void *reg, unsigned long val)
{
*((volatile unsigned long *)reg) = val;
}
extern inline void ixp2000_reg_wrb(volatile void *reg, unsigned long val)
{
*((volatile unsigned long *)reg) = val;
}
struct pci_sys_data;
void ixp23xx_map_io(void);
......
......@@ -19,9 +19,5 @@
addne \rx, \rx, #0xf4000000
.endm
.macro senduart,rd,rx
strb \rd, [\rx, #0x0]
.endm
#define UART_SHIFT 2
#include <asm/hardware/debug-8250.S>
......@@ -127,6 +127,79 @@
#define GPIO_ISOUT(K) ((GPIO_TYPE_MASK(K) == GPIO_OUT) && (GPIO_BIT(K) & GPIO_OUT_MASK))
#define GPIO_ISIN(K) ((GPIO_TYPE_MASK(K) == GPIO_IN) && (GPIO_BIT(K) & GPIO_IN_MASK))
/* Start Enable Pin Interrupts - table 58 page 66 */
#define SE_PIN_BASE_INT 32
#define SE_U7_RX_INT 63
#define SE_U7_HCTS_INT 62
#define SE_BT_CLKREQ_INT 61
#define SE_U6_IRRX_INT 60
/*59 unused*/
#define SE_U5_RX_INT 58
#define SE_GPI_11_INT 57
#define SE_U3_RX_INT 56
#define SE_U2_HCTS_INT 55
#define SE_U2_RX_INT 54
#define SE_U1_RX_INT 53
#define SE_DISP_SYNC_INT 52
/*51 unused*/
#define SE_SDIO_INT_N 50
#define SE_MSDIO_START_INT 49
#define SE_GPI_06_INT 48
#define SE_GPI_05_INT 47
#define SE_GPI_04_INT 46
#define SE_GPI_03_INT 45
#define SE_GPI_02_INT 44
#define SE_GPI_01_INT 43
#define SE_GPI_00_INT 42
#define SE_SYSCLKEN_PIN_INT 41
#define SE_SPI1_DATAIN_INT 40
#define SE_GPI_07_INT 39
#define SE_SPI2_DATAIN_INT 38
#define SE_GPI_10_INT 37
#define SE_GPI_09_INT 36
#define SE_GPI_08_INT 35
/*34-32 unused*/
/* Start Enable Internal Interrupts - table 57 page 65 */
#define SE_INT_BASE_INT 0
#define SE_TS_IRQ 31
#define SE_TS_P_INT 30
#define SE_TS_AUX_INT 29
/*27-28 unused*/
#define SE_USB_AHB_NEED_CLK_INT 26
#define SE_MSTIMER_INT 25
#define SE_RTC_INT 24
#define SE_USB_NEED_CLK_INT 23
#define SE_USB_INT 22
#define SE_USB_I2C_INT 21
#define SE_USB_OTG_TIMER_INT 20
#define SE_USB_OTG_ATX_INT_N 19
/*18 unused*/
#define SE_DSP_GPIO4_INT 17
#define SE_KEY_IRQ 16
#define SE_DSP_SLAVEPORT_INT 15
#define SE_DSP_GPIO1_INT 14
#define SE_DSP_GPIO0_INT 13
#define SE_DSP_AHB_INT 12
/*11-6 unused*/
#define SE_GPIO_05_INT 5
#define SE_GPIO_04_INT 4
#define SE_GPIO_03_INT 3
#define SE_GPIO_02_INT 2
#define SE_GPIO_01_INT 1
#define SE_GPIO_00_INT 0
#define START_INT_REG_BIT(irq) (1<<((irq)&0x1F))
#define START_INT_ER_REG(irq) IO_ADDRESS((PNX4008_PWRMAN_BASE + 0x20 + (((irq)&(0x1<<5))>>1)))
#define START_INT_RSR_REG(irq) IO_ADDRESS((PNX4008_PWRMAN_BASE + 0x24 + (((irq)&(0x1<<5))>>1)))
#define START_INT_SR_REG(irq) IO_ADDRESS((PNX4008_PWRMAN_BASE + 0x28 + (((irq)&(0x1<<5))>>1)))
#define START_INT_APR_REG(irq) IO_ADDRESS((PNX4008_PWRMAN_BASE + 0x2C + (((irq)&(0x1<<5))>>1)))
extern int pnx4008_gpio_register_pin(unsigned short pin);
extern int pnx4008_gpio_unregister_pin(unsigned short pin);
extern unsigned long pnx4008_gpio_read_pin(unsigned short pin);
......@@ -136,4 +209,33 @@ extern int pnx4008_gpio_read_pin_direction(unsigned short pin);
extern int pnx4008_gpio_set_pin_mux(unsigned short pin, int output);
extern int pnx4008_gpio_read_pin_mux(unsigned short pin);
static inline void start_int_umask(u8 irq)
{
__raw_writel(__raw_readl(START_INT_ER_REG(irq)) |
START_INT_REG_BIT(irq), START_INT_ER_REG(irq));
}
static inline void start_int_mask(u8 irq)
{
__raw_writel(__raw_readl(START_INT_ER_REG(irq)) &
~START_INT_REG_BIT(irq), START_INT_ER_REG(irq));
}
static inline void start_int_ack(u8 irq)
{
__raw_writel(START_INT_REG_BIT(irq), START_INT_RSR_REG(irq));
}
static inline void start_int_set_falling_edge(u8 irq)
{
__raw_writel(__raw_readl(START_INT_APR_REG(irq)) &
~START_INT_REG_BIT(irq), START_INT_APR_REG(irq));
}
static inline void start_int_set_rising_edge(u8 irq)
{
__raw_writel(__raw_readl(START_INT_APR_REG(irq)) |
START_INT_REG_BIT(irq), START_INT_APR_REG(irq));
}
#endif /* _PNX4008_GPIO_H_ */
......@@ -29,34 +29,5 @@ extern void pnx4008_cpu_standby(void);
extern int pnx4008_startup_pll(struct clk *);
extern int pnx4008_shutdown_pll(struct clk *);
static inline void start_int_umask(u8 irq)
{
__raw_writel(__raw_readl(START_INT_ER_REG(irq)) |
START_INT_REG_BIT(irq), START_INT_ER_REG(irq));
}
static inline void start_int_mask(u8 irq)
{
__raw_writel(__raw_readl(START_INT_ER_REG(irq)) &
~START_INT_REG_BIT(irq), START_INT_ER_REG(irq));
}
static inline void start_int_ack(u8 irq)
{
__raw_writel(START_INT_REG_BIT(irq), START_INT_RSR_REG(irq));
}
static inline void start_int_set_falling_edge(u8 irq)
{
__raw_writel(__raw_readl(START_INT_APR_REG(irq)) &
~START_INT_REG_BIT(irq), START_INT_APR_REG(irq));
}
static inline void start_int_set_rising_edge(u8 irq)
{
__raw_writel(__raw_readl(START_INT_APR_REG(irq)) |
START_INT_REG_BIT(irq), START_INT_APR_REG(irq));
}
#endif /* ASSEMBLER */
#endif /* __ASM_ARCH_PNX4008_PM_H */
......@@ -170,7 +170,7 @@
#define S3C2440_DSC1_CS1_4mA (3<<2)
#define S3C2440_DSC1_CS1_MASK (3<<2)
#define S3C2440_DSC1_CS0 (S3C2440_SELECT_DSC1 | 0
#define S3C2440_DSC1_CS0 (S3C2440_SELECT_DSC1 | 0)
#define S3C2440_DSC1_CS0_10mA (0<<0)
#define S3C2440_DSC1_CS0_8mA (1<<0)
#define S3C2440_DSC1_CS0_6mA (2<<0)
......
/*
* linux/include/asm-arm/thread_notify.h
*
* Copyright (C) 2006 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.
*/
#ifndef ASMARM_THREAD_NOTIFY_H
#define ASMARM_THREAD_NOTIFY_H
#ifdef __KERNEL__
#ifndef __ASSEMBLY__
#include <linux/notifier.h>
#include <asm/thread_info.h>
static inline int thread_register_notifier(struct notifier_block *n)
{
extern struct atomic_notifier_head thread_notify_head;
return atomic_notifier_chain_register(&thread_notify_head, n);
}
static inline void thread_unregister_notifier(struct notifier_block *n)
{
extern struct atomic_notifier_head thread_notify_head;
atomic_notifier_chain_unregister(&thread_notify_head, n);
}
static inline void thread_notify(unsigned long rc, struct thread_info *thread)
{
extern struct atomic_notifier_head thread_notify_head;
atomic_notifier_call_chain(&thread_notify_head, rc, thread);
}
#endif
/*
* These are the reason codes for the thread notifier.
*/
#define THREAD_NOTIFY_FLUSH 0
#define THREAD_NOTIFY_RELEASE 1
#define THREAD_NOTIFY_SWITCH 2
#endif
#endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment