提交 1480d0a3 编写于 作者: L Linus Torvalds

Merge master.kernel.org:/home/rmk/linux-2.6-arm

......@@ -33,8 +33,8 @@
#include <asm/cacheflush.h>
#undef DEBUG
#undef STATS
#ifdef STATS
#define DO_STATS(X) do { X ; } while (0)
#else
......@@ -52,26 +52,31 @@ struct safe_buffer {
int direction;
/* safe buffer info */
struct dma_pool *pool;
struct dmabounce_pool *pool;
void *safe;
dma_addr_t safe_dma_addr;
};
struct dmabounce_pool {
unsigned long size;
struct dma_pool *pool;
#ifdef STATS
unsigned long allocs;
#endif
};
struct dmabounce_device_info {
struct list_head node;
struct device *dev;
struct dma_pool *small_buffer_pool;
struct dma_pool *large_buffer_pool;
struct list_head safe_buffers;
unsigned long small_buffer_size, large_buffer_size;
#ifdef STATS
unsigned long sbp_allocs;
unsigned long lbp_allocs;
unsigned long total_allocs;
unsigned long map_op_count;
unsigned long bounce_count;
#endif
struct dmabounce_pool small;
struct dmabounce_pool large;
};
static LIST_HEAD(dmabounce_devs);
......@@ -82,9 +87,9 @@ static void print_alloc_stats(struct dmabounce_device_info *device_info)
printk(KERN_INFO
"%s: dmabounce: sbp: %lu, lbp: %lu, other: %lu, total: %lu\n",
device_info->dev->bus_id,
device_info->sbp_allocs, device_info->lbp_allocs,
device_info->total_allocs - device_info->sbp_allocs -
device_info->lbp_allocs,
device_info->small.allocs, device_info->large.allocs,
device_info->total_allocs - device_info->small.allocs -
device_info->large.allocs,
device_info->total_allocs);
}
#endif
......@@ -106,18 +111,22 @@ find_dmabounce_dev(struct device *dev)
/* allocate a 'safe' buffer and keep track of it */
static inline struct safe_buffer *
alloc_safe_buffer(struct dmabounce_device_info *device_info, void *ptr,
size_t size, enum dma_data_direction dir)
size_t size, enum dma_data_direction dir)
{
struct safe_buffer *buf;
struct dma_pool *pool;
struct dmabounce_pool *pool;
struct device *dev = device_info->dev;
void *safe;
dma_addr_t safe_dma_addr;
dev_dbg(dev, "%s(ptr=%p, size=%d, dir=%d)\n",
__func__, ptr, size, dir);
DO_STATS ( device_info->total_allocs++ );
if (size <= device_info->small.size) {
pool = &device_info->small;
} else if (size <= device_info->large.size) {
pool = &device_info->large;
} else {
pool = NULL;
}
buf = kmalloc(sizeof(struct safe_buffer), GFP_ATOMIC);
if (buf == NULL) {
......@@ -125,41 +134,35 @@ alloc_safe_buffer(struct dmabounce_device_info *device_info, void *ptr,
return NULL;
}
if (size <= device_info->small_buffer_size) {
pool = device_info->small_buffer_pool;
safe = dma_pool_alloc(pool, GFP_ATOMIC, &safe_dma_addr);
DO_STATS ( device_info->sbp_allocs++ );
} else if (size <= device_info->large_buffer_size) {
pool = device_info->large_buffer_pool;
safe = dma_pool_alloc(pool, GFP_ATOMIC, &safe_dma_addr);
buf->ptr = ptr;
buf->size = size;
buf->direction = dir;
buf->pool = pool;
DO_STATS ( device_info->lbp_allocs++ );
if (pool) {
buf->safe = dma_pool_alloc(pool->pool, GFP_ATOMIC,
&buf->safe_dma_addr);
} else {
pool = NULL;
safe = dma_alloc_coherent(dev, size, &safe_dma_addr, GFP_ATOMIC);
buf->safe = dma_alloc_coherent(dev, size, &buf->safe_dma_addr,
GFP_ATOMIC);
}
if (safe == NULL) {
dev_warn(device_info->dev,
"%s: could not alloc dma memory (size=%d)\n",
__func__, size);
if (buf->safe == NULL) {
dev_warn(dev,
"%s: could not alloc dma memory (size=%d)\n",
__func__, size);
kfree(buf);
return NULL;
}
#ifdef STATS
if (pool)
pool->allocs++;
device_info->total_allocs++;
if (device_info->total_allocs % 1000 == 0)
print_alloc_stats(device_info);
#endif
buf->ptr = ptr;
buf->size = size;
buf->direction = dir;
buf->pool = pool;
buf->safe = safe;
buf->safe_dma_addr = safe_dma_addr;
list_add(&buf->node, &device_info->safe_buffers);
return buf;
......@@ -186,7 +189,7 @@ free_safe_buffer(struct dmabounce_device_info *device_info, struct safe_buffer *
list_del(&buf->node);
if (buf->pool)
dma_pool_free(buf->pool, buf->safe, buf->safe_dma_addr);
dma_pool_free(buf->pool->pool, buf->safe, buf->safe_dma_addr);
else
dma_free_coherent(device_info->dev, buf->size, buf->safe,
buf->safe_dma_addr);
......@@ -197,12 +200,10 @@ free_safe_buffer(struct dmabounce_device_info *device_info, struct safe_buffer *
/* ************************************************** */
#ifdef STATS
static void print_map_stats(struct dmabounce_device_info *device_info)
{
printk(KERN_INFO
"%s: dmabounce: map_op_count=%lu, bounce_count=%lu\n",
device_info->dev->bus_id,
dev_info(device_info->dev,
"dmabounce: map_op_count=%lu, bounce_count=%lu\n",
device_info->map_op_count, device_info->bounce_count);
}
#endif
......@@ -258,13 +259,13 @@ map_single(struct device *dev, void *ptr, size_t size,
__func__, ptr, buf->safe, size);
memcpy(buf->safe, ptr, size);
}
consistent_sync(buf->safe, size, dir);
ptr = buf->safe;
dma_addr = buf->safe_dma_addr;
} else {
consistent_sync(ptr, size, dir);
}
consistent_sync(ptr, size, dir);
return dma_addr;
}
......@@ -278,7 +279,7 @@ unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
/*
* Trying to unmap an invalid mapping
*/
if (dma_addr == ~0) {
if (dma_mapping_error(dma_addr)) {
dev_err(dev, "Trying to unmap invalid mapping\n");
return;
}
......@@ -570,11 +571,25 @@ dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nents,
local_irq_restore(flags);
}
static int
dmabounce_init_pool(struct dmabounce_pool *pool, struct device *dev, const char *name,
unsigned long size)
{
pool->size = size;
DO_STATS(pool->allocs = 0);
pool->pool = dma_pool_create(name, dev, size,
0 /* byte alignment */,
0 /* no page-crossing issues */);
return pool->pool ? 0 : -ENOMEM;
}
int
dmabounce_register_dev(struct device *dev, unsigned long small_buffer_size,
unsigned long large_buffer_size)
{
struct dmabounce_device_info *device_info;
int ret;
device_info = kmalloc(sizeof(struct dmabounce_device_info), GFP_ATOMIC);
if (!device_info) {
......@@ -584,45 +599,31 @@ dmabounce_register_dev(struct device *dev, unsigned long small_buffer_size,
return -ENOMEM;
}
device_info->small_buffer_pool =
dma_pool_create("small_dmabounce_pool",
dev,
small_buffer_size,
0 /* byte alignment */,
0 /* no page-crossing issues */);
if (!device_info->small_buffer_pool) {
printk(KERN_ERR
"dmabounce: could not allocate small DMA pool for %s\n",
dev->bus_id);
kfree(device_info);
return -ENOMEM;
ret = dmabounce_init_pool(&device_info->small, dev,
"small_dmabounce_pool", small_buffer_size);
if (ret) {
dev_err(dev,
"dmabounce: could not allocate DMA pool for %ld byte objects\n",
small_buffer_size);
goto err_free;
}
if (large_buffer_size) {
device_info->large_buffer_pool =
dma_pool_create("large_dmabounce_pool",
dev,
large_buffer_size,
0 /* byte alignment */,
0 /* no page-crossing issues */);
if (!device_info->large_buffer_pool) {
printk(KERN_ERR
"dmabounce: could not allocate large DMA pool for %s\n",
dev->bus_id);
dma_pool_destroy(device_info->small_buffer_pool);
return -ENOMEM;
ret = dmabounce_init_pool(&device_info->large, dev,
"large_dmabounce_pool",
large_buffer_size);
if (ret) {
dev_err(dev,
"dmabounce: could not allocate DMA pool for %ld byte objects\n",
large_buffer_size);
goto err_destroy;
}
}
device_info->dev = dev;
device_info->small_buffer_size = small_buffer_size;
device_info->large_buffer_size = large_buffer_size;
INIT_LIST_HEAD(&device_info->safe_buffers);
#ifdef STATS
device_info->sbp_allocs = 0;
device_info->lbp_allocs = 0;
device_info->total_allocs = 0;
device_info->map_op_count = 0;
device_info->bounce_count = 0;
......@@ -634,6 +635,12 @@ dmabounce_register_dev(struct device *dev, unsigned long small_buffer_size,
dev->bus_id, dev->bus->name);
return 0;
err_destroy:
dma_pool_destroy(device_info->small.pool);
err_free:
kfree(device_info);
return ret;
}
void
......@@ -655,10 +662,10 @@ dmabounce_unregister_dev(struct device *dev)
BUG();
}
if (device_info->small_buffer_pool)
dma_pool_destroy(device_info->small_buffer_pool);
if (device_info->large_buffer_pool)
dma_pool_destroy(device_info->large_buffer_pool);
if (device_info->small.pool)
dma_pool_destroy(device_info->small.pool);
if (device_info->large.pool)
dma_pool_destroy(device_info->large.pool);
#ifdef STATS
print_alloc_stats(device_info);
......
......@@ -559,7 +559,7 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
#
CONFIG_SERIAL_8250=y
CONFIG_SERIAL_8250_CONSOLE=y
CONFIG_SERIAL_8250_NR_UARTS=2
CONFIG_SERIAL_8250_NR_UARTS=1
# CONFIG_SERIAL_8250_EXTENDED is not set
#
......
......@@ -559,7 +559,7 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
#
CONFIG_SERIAL_8250=y
CONFIG_SERIAL_8250_CONSOLE=y
CONFIG_SERIAL_8250_NR_UARTS=2
CONFIG_SERIAL_8250_NR_UARTS=1
# CONFIG_SERIAL_8250_EXTENDED is not set
#
......
......@@ -198,25 +198,16 @@ void show_stack(struct task_struct *tsk, unsigned long *sp)
barrier();
}
DEFINE_SPINLOCK(die_lock);
/*
* This function is protected against re-entrancy.
*/
NORET_TYPE void die(const char *str, struct pt_regs *regs, int err)
static void __die(const char *str, int err, struct thread_info *thread, struct pt_regs *regs)
{
struct task_struct *tsk = current;
struct task_struct *tsk = thread->task;
static int die_counter;
console_verbose();
spin_lock_irq(&die_lock);
bust_spinlocks(1);
printk("Internal error: %s: %x [#%d]\n", str, err, ++die_counter);
print_modules();
__show_regs(regs);
printk("Process %s (pid: %d, stack limit = 0x%p)\n",
tsk->comm, tsk->pid, tsk->thread_info + 1);
tsk->comm, tsk->pid, thread + 1);
if (!user_mode(regs) || in_interrupt()) {
dump_mem("Stack: ", regs->ARM_sp,
......@@ -224,7 +215,21 @@ NORET_TYPE void die(const char *str, struct pt_regs *regs, int err)
dump_backtrace(regs, tsk);
dump_instr(regs);
}
}
DEFINE_SPINLOCK(die_lock);
/*
* This function is protected against re-entrancy.
*/
NORET_TYPE void die(const char *str, struct pt_regs *regs, int err)
{
struct thread_info *thread = current_thread_info();
console_verbose();
spin_lock_irq(&die_lock);
bust_spinlocks(1);
__die(str, err, thread, regs);
bust_spinlocks(0);
spin_unlock_irq(&die_lock);
do_exit(SIGSEGV);
......
/* Copyright 1995, 1996, 1998, 1999, 2000, 2003, 2004, 2005
Free Software Foundation, Inc.
This file 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, or (at your option) any
later version.
In addition to the permissions in the GNU General Public License, the
Free Software Foundation gives you unlimited permission to link the
compiled version of this file into combinations with other programs,
and to distribute those combinations without any restriction coming
from the use of this file. (The General Public License restrictions
do apply in other respects; for example, they cover modification of
the file, and distribution when not linked into a combine
executable.)
This file 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; see the file COPYING. If not, write to
the Free Software Foundation, 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA. */
#include <linux/linkage.h>
#ifdef __ARMEB__
#define al r1
#define ah r0
#else
#define al r0
#define ah r1
#endif
ENTRY(__ashldi3)
subs r3, r2, #32
rsb ip, r2, #32
movmi ah, ah, lsl r2
movpl ah, al, lsl r3
orrmi ah, ah, al, lsr ip
mov al, al, lsl r2
mov pc, lr
/* More subroutines needed by GCC output code on some machines. */
/* Compile this one with gcc. */
/* Copyright (C) 1989, 92-98, 1999 Free Software Foundation, Inc.
This file is part of GNU CC.
GNU CC 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, or (at your option)
any later version.
GNU CC 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 GNU CC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
/* As a special exception, if you link this library with other files,
some of which are compiled with GCC, to produce an executable,
this library does not by itself cause the resulting executable
to be covered by the GNU General Public License.
This exception does not however invalidate any other reasons why
the executable file might be covered by the GNU General Public License.
*/
/* support functions required by the kernel. based on code from gcc-2.95.3 */
/* I Molton 29/07/01 */
#include "gcclib.h"
s64 __ashldi3(s64 u, int b)
{
DIunion w;
int bm;
DIunion uu;
if (b == 0)
return u;
uu.ll = u;
bm = (sizeof(s32) * BITS_PER_UNIT) - b;
if (bm <= 0) {
w.s.low = 0;
w.s.high = (u32) uu.s.low << -bm;
} else {
u32 carries = (u32) uu.s.low >> bm;
w.s.low = (u32) uu.s.low << b;
w.s.high = ((u32) uu.s.high << b) | carries;
}
return w.ll;
}
/* Copyright 1995, 1996, 1998, 1999, 2000, 2003, 2004, 2005
Free Software Foundation, Inc.
This file 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, or (at your option) any
later version.
In addition to the permissions in the GNU General Public License, the
Free Software Foundation gives you unlimited permission to link the
compiled version of this file into combinations with other programs,
and to distribute those combinations without any restriction coming
from the use of this file. (The General Public License restrictions
do apply in other respects; for example, they cover modification of
the file, and distribution when not linked into a combine
executable.)
This file 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; see the file COPYING. If not, write to
the Free Software Foundation, 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA. */
#include <linux/linkage.h>
#ifdef __ARMEB__
#define al r1
#define ah r0
#else
#define al r0
#define ah r1
#endif
ENTRY(__ashrdi3)
subs r3, r2, #32
rsb ip, r2, #32
movmi al, al, lsr r2
movpl al, ah, asr r3
orrmi al, al, ah, lsl ip
mov ah, ah, asr r2
mov pc, lr
/* More subroutines needed by GCC output code on some machines. */
/* Compile this one with gcc. */
/* Copyright (C) 1989, 92-98, 1999 Free Software Foundation, Inc.
This file is part of GNU CC.
GNU CC 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, or (at your option)
any later version.
GNU CC 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 GNU CC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
/* As a special exception, if you link this library with other files,
some of which are compiled with GCC, to produce an executable,
this library does not by itself cause the resulting executable
to be covered by the GNU General Public License.
This exception does not however invalidate any other reasons why
the executable file might be covered by the GNU General Public License.
*/
/* support functions required by the kernel. based on code from gcc-2.95.3 */
/* I Molton 29/07/01 */
#include "gcclib.h"
s64 __ashrdi3(s64 u, int b)
{
DIunion w;
int bm;
DIunion uu;
if (b == 0)
return u;
uu.ll = u;
bm = (sizeof(s32) * BITS_PER_UNIT) - b;
if (bm <= 0) {
/* w.s.high = 1..1 or 0..0 */
w.s.high = uu.s.high >> (sizeof(s32) * BITS_PER_UNIT - 1);
w.s.low = uu.s.high >> -bm;
} else {
u32 carries = (u32) uu.s.high << bm;
w.s.high = uu.s.high >> b;
w.s.low = ((u32) uu.s.low >> b) | carries;
}
return w.ll;
}
/* gcclib.h -- definitions for various functions 'borrowed' from gcc-2.95.3 */
/* I Molton 29/07/01 */
#include <linux/types.h>
#define BITS_PER_UNIT 8
#define SI_TYPE_SIZE (sizeof(s32) * BITS_PER_UNIT)
#ifdef __ARMEB__
struct DIstruct {
s32 high, low;
};
#else
struct DIstruct {
s32 low, high;
};
#endif
typedef union {
struct DIstruct s;
s64 ll;
} DIunion;
/* Copyright 1995, 1996, 1998, 1999, 2000, 2003, 2004, 2005
Free Software Foundation, Inc.
This file 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, or (at your option) any
later version.
In addition to the permissions in the GNU General Public License, the
Free Software Foundation gives you unlimited permission to link the
compiled version of this file into combinations with other programs,
and to distribute those combinations without any restriction coming
from the use of this file. (The General Public License restrictions
do apply in other respects; for example, they cover modification of
the file, and distribution when not linked into a combine
executable.)
This file 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; see the file COPYING. If not, write to
the Free Software Foundation, 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA. */
#include <linux/linkage.h>
#ifdef __ARMEB__
#define al r1
#define ah r0
#else
#define al r0
#define ah r1
#endif
ENTRY(__lshrdi3)
subs r3, r2, #32
rsb ip, r2, #32
movmi al, al, lsr r2
movpl al, ah, lsr r3
orrmi al, al, ah, lsl ip
mov ah, ah, lsr r2
mov pc, lr
/* More subroutines needed by GCC output code on some machines. */
/* Compile this one with gcc. */
/* Copyright (C) 1989, 92-98, 1999 Free Software Foundation, Inc.
This file is part of GNU CC.
GNU CC 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, or (at your option)
any later version.
GNU CC 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 GNU CC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
/* As a special exception, if you link this library with other files,
some of which are compiled with GCC, to produce an executable,
this library does not by itself cause the resulting executable
to be covered by the GNU General Public License.
This exception does not however invalidate any other reasons why
the executable file might be covered by the GNU General Public License.
*/
/* support functions required by the kernel. based on code from gcc-2.95.3 */
/* I Molton 29/07/01 */
#include "gcclib.h"
s64 __lshrdi3(s64 u, int b)
{
DIunion w;
int bm;
DIunion uu;
if (b == 0)
return u;
uu.ll = u;
bm = (sizeof(s32) * BITS_PER_UNIT) - b;
if (bm <= 0) {
w.s.high = 0;
w.s.low = (u32) uu.s.high >> -bm;
} else {
u32 carries = (u32) uu.s.high << bm;
w.s.high = (u32) uu.s.high >> b;
w.s.low = ((u32) uu.s.low >> b) | carries;
}
return w.ll;
}
/*
* linux/arch/arm/lib/muldi3.S
*
* Author: Nicolas Pitre
* Created: Oct 19, 2005
* Copyright: Monta Vista Software, Inc.
*
* 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/linkage.h>
#ifdef __ARMEB__
#define xh r0
#define xl r1
#define yh r2
#define yl r3
#else
#define xl r0
#define xh r1
#define yl r2
#define yh r3
#endif
ENTRY(__muldi3)
mul xh, yl, xh
mla xh, xl, yh, xh
mov ip, xl, asr #16
mov yh, yl, asr #16
bic xl, xl, ip, lsl #16
bic yl, yl, yh, lsl #16
mla xh, yh, ip, xh
mul yh, xl, yh
mul xl, yl, xl
mul ip, yl, ip
adds xl, xl, yh, lsl #16
adc xh, xh, yh, lsr #16
adds xl, xl, ip, lsl #16
adc xh, xh, ip, lsr #16
mov pc, lr
/* More subroutines needed by GCC output code on some machines. */
/* Compile this one with gcc. */
/* Copyright (C) 1989, 92-98, 1999 Free Software Foundation, Inc.
This file is part of GNU CC.
GNU CC 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, or (at your option)
any later version.
GNU CC 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 GNU CC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
/* As a special exception, if you link this library with other files,
some of which are compiled with GCC, to produce an executable,
this library does not by itself cause the resulting executable
to be covered by the GNU General Public License.
This exception does not however invalidate any other reasons why
the executable file might be covered by the GNU General Public License.
*/
/* support functions required by the kernel. based on code from gcc-2.95.3 */
/* I Molton 29/07/01 */
#include "gcclib.h"
#define umul_ppmm(xh, xl, a, b) \
{register u32 __t0, __t1, __t2; \
__asm__ ("%@ Inlined umul_ppmm \n\
mov %2, %5, lsr #16 \n\
mov %0, %6, lsr #16 \n\
bic %3, %5, %2, lsl #16 \n\
bic %4, %6, %0, lsl #16 \n\
mul %1, %3, %4 \n\
mul %4, %2, %4 \n\
mul %3, %0, %3 \n\
mul %0, %2, %0 \n\
adds %3, %4, %3 \n\
addcs %0, %0, #65536 \n\
adds %1, %1, %3, lsl #16 \n\
adc %0, %0, %3, lsr #16" \
: "=&r" ((u32) (xh)), \
"=r" ((u32) (xl)), \
"=&r" (__t0), "=&r" (__t1), "=r" (__t2) \
: "r" ((u32) (a)), \
"r" ((u32) (b)));}
#define __umulsidi3(u, v) \
({DIunion __w; \
umul_ppmm (__w.s.high, __w.s.low, u, v); \
__w.ll; })
s64 __muldi3(s64 u, s64 v)
{
DIunion w;
DIunion uu, vv;
uu.ll = u, vv.ll = v;
w.ll = __umulsidi3(uu.s.low, vv.s.low);
w.s.high += ((u32) uu.s.low * (u32) vv.s.high
+ (u32) uu.s.high * (u32) vv.s.low);
return w.ll;
}
/*
* linux/arch/arm/lib/ucmpdi2.S
*
* Author: Nicolas Pitre
* Created: Oct 19, 2005
* Copyright: Monta Vista Software, Inc.
*
* 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/linkage.h>
#ifdef __ARMEB__
#define xh r0
#define xl r1
#define yh r2
#define yl r3
#else
#define xl r0
#define xh r1
#define yl r2
#define yh r3
#endif
ENTRY(__ucmpdi2)
cmp xh, yh
cmpeq xl, yl
movlo r0, #0
moveq r0, #1
movhi r0, #2
mov pc, lr
/* More subroutines needed by GCC output code on some machines. */
/* Compile this one with gcc. */
/* Copyright (C) 1989, 92-98, 1999 Free Software Foundation, Inc.
This file is part of GNU CC.
GNU CC 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, or (at your option)
any later version.
GNU CC 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 GNU CC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
/* As a special exception, if you link this library with other files,
some of which are compiled with GCC, to produce an executable,
this library does not by itself cause the resulting executable
to be covered by the GNU General Public License.
This exception does not however invalidate any other reasons why
the executable file might be covered by the GNU General Public License.
*/
/* support functions required by the kernel. based on code from gcc-2.95.3 */
/* I Molton 29/07/01 */
#include "gcclib.h"
int __ucmpdi2(s64 a, s64 b)
{
DIunion au, bu;
au.ll = a, bu.ll = b;
if ((u32) au.s.high < (u32) bu.s.high)
return 0;
else if ((u32) au.s.high > (u32) bu.s.high)
return 2;
if ((u32) au.s.low < (u32) bu.s.low)
return 0;
else if ((u32) au.s.low > (u32) bu.s.low)
return 2;
return 1;
}
......@@ -33,6 +33,7 @@
#include <asm/arch/pxa-regs.h>
#include <asm/arch/irq.h>
#include <asm/arch/irda.h>
#include <asm/arch/mmc.h>
#include <asm/arch/udc.h>
#include <asm/arch/corgi.h>
......@@ -224,6 +225,22 @@ static struct pxamci_platform_data corgi_mci_platform_data = {
};
/*
* Irda
*/
static void corgi_irda_transceiver_mode(struct device *dev, int mode)
{
if (mode & IR_OFF)
GPSR(CORGI_GPIO_IR_ON) = GPIO_bit(CORGI_GPIO_IR_ON);
else
GPCR(CORGI_GPIO_IR_ON) = GPIO_bit(CORGI_GPIO_IR_ON);
}
static struct pxaficp_platform_data corgi_ficp_platform_data = {
.transceiver_cap = IR_SIRMODE | IR_OFF,
.transceiver_mode = corgi_irda_transceiver_mode,
};
/*
* USB Device Controller
......@@ -269,10 +286,13 @@ static void __init corgi_init(void)
corgi_ssp_set_machinfo(&corgi_ssp_machinfo);
pxa_gpio_mode(CORGI_GPIO_IR_ON | GPIO_OUT);
pxa_gpio_mode(CORGI_GPIO_USB_PULLUP | GPIO_OUT);
pxa_gpio_mode(CORGI_GPIO_HSYNC | GPIO_IN);
pxa_set_udc_info(&udc_info);
pxa_set_mci_info(&corgi_mci_platform_data);
pxa_set_ficp_info(&corgi_ficp_platform_data);
scoop_num = 1;
scoop_devs = &corgi_pcmcia_scoop[0];
......
......@@ -32,6 +32,7 @@
#include <asm/arch/irq.h>
#include <asm/arch/mmc.h>
#include <asm/arch/udc.h>
#include <asm/arch/irda.h>
#include <asm/arch/poodle.h>
#include <asm/arch/pxafb.h>
......@@ -151,6 +152,24 @@ static struct pxamci_platform_data poodle_mci_platform_data = {
};
/*
* Irda
*/
static void poodle_irda_transceiver_mode(struct device *dev, int mode)
{
if (mode & IR_OFF) {
GPSR(POODLE_GPIO_IR_ON) = GPIO_bit(POODLE_GPIO_IR_ON);
} else {
GPCR(POODLE_GPIO_IR_ON) = GPIO_bit(POODLE_GPIO_IR_ON);
}
}
static struct pxaficp_platform_data poodle_ficp_platform_data = {
.transceiver_cap = IR_SIRMODE | IR_OFF,
.transceiver_mode = poodle_irda_transceiver_mode,
};
/*
* USB Device Controller
*/
......@@ -244,8 +263,10 @@ static void __init poodle_init(void)
set_pxa_fb_info(&poodle_fb_info);
pxa_gpio_mode(POODLE_GPIO_USB_PULLUP | GPIO_OUT);
pxa_gpio_mode(POODLE_GPIO_IR_ON | GPIO_OUT);
pxa_set_udc_info(&udc_info);
pxa_set_mci_info(&poodle_mci_platform_data);
pxa_set_ficp_info(&poodle_ficp_platform_data);
scoop_num = 1;
scoop_devs = &poodle_pcmcia_scoop[0];
......
......@@ -34,6 +34,7 @@
#include <asm/arch/pxa-regs.h>
#include <asm/arch/irq.h>
#include <asm/arch/irda.h>
#include <asm/arch/mmc.h>
#include <asm/arch/udc.h>
#include <asm/arch/pxafb.h>
......@@ -276,6 +277,23 @@ static struct pxamci_platform_data spitz_mci_platform_data = {
};
/*
* Irda
*/
static void spitz_irda_transceiver_mode(struct device *dev, int mode)
{
if (mode & IR_OFF)
set_scoop_gpio(&spitzscoop2_device.dev, SPITZ_SCP2_IR_ON);
else
reset_scoop_gpio(&spitzscoop2_device.dev, SPITZ_SCP2_IR_ON);
}
static struct pxaficp_platform_data spitz_ficp_platform_data = {
.transceiver_cap = IR_SIRMODE | IR_OFF,
.transceiver_mode = spitz_irda_transceiver_mode,
};
/*
* Spitz PXA Framebuffer
*/
......@@ -326,6 +344,7 @@ static void __init common_init(void)
platform_add_devices(devices, ARRAY_SIZE(devices));
pxa_set_mci_info(&spitz_mci_platform_data);
pxa_set_ficp_info(&spitz_ficp_platform_data);
set_pxa_fb_parent(&spitzssp_device.dev);
set_pxa_fb_info(&spitz_pxafb_info);
}
......
......@@ -22,9 +22,7 @@
#endif
#define from_address (0xffff8000)
#define from_pgprot PAGE_KERNEL
#define to_address (0xffffc000)
#define to_pgprot PAGE_KERNEL
#define TOP_PTE(x) pte_offset_kernel(top_pmd, x)
......@@ -34,7 +32,7 @@ static DEFINE_SPINLOCK(v6_lock);
* Copy the user page. No aliasing to deal with so we can just
* attack the kernel's existing mapping of these pages.
*/
void v6_copy_user_page_nonaliasing(void *kto, const void *kfrom, unsigned long vaddr)
static void v6_copy_user_page_nonaliasing(void *kto, const void *kfrom, unsigned long vaddr)
{
copy_page(kto, kfrom);
}
......@@ -43,7 +41,7 @@ void v6_copy_user_page_nonaliasing(void *kto, const void *kfrom, unsigned long v
* Clear the user page. No aliasing to deal with so we can just
* attack the kernel's existing mapping of this page.
*/
void v6_clear_user_page_nonaliasing(void *kaddr, unsigned long vaddr)
static void v6_clear_user_page_nonaliasing(void *kaddr, unsigned long vaddr)
{
clear_page(kaddr);
}
......@@ -51,7 +49,7 @@ void v6_clear_user_page_nonaliasing(void *kaddr, unsigned long vaddr)
/*
* Copy the page, taking account of the cache colour.
*/
void v6_copy_user_page_aliasing(void *kto, const void *kfrom, unsigned long vaddr)
static void v6_copy_user_page_aliasing(void *kto, const void *kfrom, unsigned long vaddr)
{
unsigned int offset = CACHE_COLOUR(vaddr);
unsigned long from, to;
......@@ -72,8 +70,8 @@ void v6_copy_user_page_aliasing(void *kto, const void *kfrom, unsigned long vadd
*/
spin_lock(&v6_lock);
set_pte(TOP_PTE(from_address) + offset, pfn_pte(__pa(kfrom) >> PAGE_SHIFT, from_pgprot));
set_pte(TOP_PTE(to_address) + offset, pfn_pte(__pa(kto) >> PAGE_SHIFT, to_pgprot));
set_pte(TOP_PTE(from_address) + offset, pfn_pte(__pa(kfrom) >> PAGE_SHIFT, PAGE_KERNEL));
set_pte(TOP_PTE(to_address) + offset, pfn_pte(__pa(kto) >> PAGE_SHIFT, PAGE_KERNEL));
from = from_address + (offset << PAGE_SHIFT);
to = to_address + (offset << PAGE_SHIFT);
......@@ -91,7 +89,7 @@ void v6_copy_user_page_aliasing(void *kto, const void *kfrom, unsigned long vadd
* so remap the kernel page into the same cache colour as the user
* page.
*/
void v6_clear_user_page_aliasing(void *kaddr, unsigned long vaddr)
static void v6_clear_user_page_aliasing(void *kaddr, unsigned long vaddr)
{
unsigned int offset = CACHE_COLOUR(vaddr);
unsigned long to = to_address + (offset << PAGE_SHIFT);
......@@ -112,7 +110,7 @@ void v6_clear_user_page_aliasing(void *kaddr, unsigned long vaddr)
*/
spin_lock(&v6_lock);
set_pte(TOP_PTE(to_address) + offset, pfn_pte(__pa(kaddr) >> PAGE_SHIFT, to_pgprot));
set_pte(TOP_PTE(to_address) + offset, pfn_pte(__pa(kaddr) >> PAGE_SHIFT, PAGE_KERNEL));
flush_tlb_kernel_page(to);
clear_page((void *)to);
......
......@@ -9,6 +9,7 @@
*
* Driver for PCF8583 RTC & RAM chip
*/
#include <linux/module.h>
#include <linux/i2c.h>
#include <linux/slab.h>
#include <linux/string.h>
......@@ -32,7 +33,8 @@ static struct i2c_client_address_data addr_data = {
.forces = forces,
};
#define DAT(x) ((unsigned int)(x->dev.driver_data))
#define set_ctrl(x, v) i2c_set_clientdata(x, (void *)(unsigned int)(v))
#define get_ctrl(x) ((unsigned int)i2c_get_clientdata(x))
static int
pcf8583_attach(struct i2c_adapter *adap, int addr, int kind)
......@@ -40,8 +42,17 @@ pcf8583_attach(struct i2c_adapter *adap, int addr, int kind)
struct i2c_client *c;
unsigned char buf[1], ad[1] = { 0 };
struct i2c_msg msgs[2] = {
{ addr, 0, 1, ad },
{ addr, I2C_M_RD, 1, buf }
{
.addr = addr,
.flags = 0,
.len = 1,
.buf = ad,
}, {
.addr = addr,
.flags = I2C_M_RD,
.len = 1,
.buf = buf,
}
};
c = kmalloc(sizeof(*c), GFP_KERNEL);
......@@ -54,7 +65,7 @@ pcf8583_attach(struct i2c_adapter *adap, int addr, int kind)
c->driver = &pcf8583_driver;
if (i2c_transfer(c->adapter, msgs, 2) == 2)
DAT(c) = buf[0];
set_ctrl(c, buf[0]);
return i2c_attach_client(c);
}
......@@ -78,8 +89,17 @@ pcf8583_get_datetime(struct i2c_client *client, struct rtc_tm *dt)
{
unsigned char buf[8], addr[1] = { 1 };
struct i2c_msg msgs[2] = {
{ client->addr, 0, 1, addr },
{ client->addr, I2C_M_RD, 6, buf }
{
.addr = client->addr,
.flags = 0,
.len = 1,
.buf = addr,
}, {
.addr = client->addr,
.flags = I2C_M_RD,
.len = 6,
.buf = buf,
}
};
int ret = -EIO;
......@@ -113,7 +133,7 @@ pcf8583_set_datetime(struct i2c_client *client, struct rtc_tm *dt, int datetoo)
int ret, len = 6;
buf[0] = 0;
buf[1] = DAT(client) | 0x80;
buf[1] = get_ctrl(client) | 0x80;
buf[2] = BIN_TO_BCD(dt->cs);
buf[3] = BIN_TO_BCD(dt->secs);
buf[4] = BIN_TO_BCD(dt->mins);
......@@ -129,7 +149,7 @@ pcf8583_set_datetime(struct i2c_client *client, struct rtc_tm *dt, int datetoo)
if (ret == len)
ret = 0;
buf[1] = DAT(client);
buf[1] = get_ctrl(client);
i2c_master_send(client, (char *)buf, 2);
return ret;
......@@ -138,7 +158,7 @@ pcf8583_set_datetime(struct i2c_client *client, struct rtc_tm *dt, int datetoo)
static int
pcf8583_get_ctrl(struct i2c_client *client, unsigned char *ctrl)
{
*ctrl = DAT(client);
*ctrl = get_ctrl(client);
return 0;
}
......@@ -149,7 +169,7 @@ pcf8583_set_ctrl(struct i2c_client *client, unsigned char *ctrl)
buf[0] = 0;
buf[1] = *ctrl;
DAT(client) = *ctrl;
set_ctrl(client, *ctrl);
return i2c_master_send(client, (char *)buf, 2);
}
......@@ -159,15 +179,23 @@ pcf8583_read_mem(struct i2c_client *client, struct mem *mem)
{
unsigned char addr[1];
struct i2c_msg msgs[2] = {
{ client->addr, 0, 1, addr },
{ client->addr, I2C_M_RD, 0, mem->data }
{
.addr = client->addr,
.flags = 0,
.len = 1,
.buf = addr,
}, {
.addr = client->addr,
.flags = I2C_M_RD,
.len = mem->nr,
.buf = mem->data,
}
};
if (mem->loc < 8)
return -EINVAL;
addr[0] = mem->loc;
msgs[1].len = mem->nr;
return i2c_transfer(client->adapter, msgs, 2) == 2 ? 0 : -EIO;
}
......@@ -177,15 +205,23 @@ pcf8583_write_mem(struct i2c_client *client, struct mem *mem)
{
unsigned char addr[1];
struct i2c_msg msgs[2] = {
{ client->addr, 0, 1, addr },
{ client->addr, 0, 0, mem->data }
{
.addr = client->addr,
.flags = 0,
.len = 1,
.buf = addr,
}, {
.addr = client->addr,
.flags = I2C_M_NOSTART,
.len = mem->nr,
.buf = mem->data,
}
};
if (mem->loc < 8)
return -EINVAL;
addr[0] = mem->loc;
msgs[1].len = mem->nr;
return i2c_transfer(client->adapter, msgs, 2) == 2 ? 0 : -EIO;
}
......@@ -234,4 +270,14 @@ static __init int pcf8583_init(void)
return i2c_add_driver(&pcf8583_driver);
}
__initcall(pcf8583_init);
static __exit void pcf8583_exit(void)
{
i2c_del_driver(&pcf8583_driver);
}
module_init(pcf8583_init);
module_exit(pcf8583_exit);
MODULE_AUTHOR("Russell King");
MODULE_DESCRIPTION("PCF8583 I2C RTC driver");
MODULE_LICENSE("GPL");
......@@ -32,9 +32,12 @@
#include <linux/suspend.h>
#include <linux/slab.h>
#include <linux/kthread.h>
#include <linux/delay.h>
#include <asm/dma.h>
#include <asm/semaphore.h>
#include <asm/arch/collie.h>
#include <asm/mach-types.h>
#include "ucb1x00.h"
......@@ -85,12 +88,23 @@ static inline void ucb1x00_ts_mode_int(struct ucb1x00_ts *ts)
*/
static inline unsigned int ucb1x00_ts_read_pressure(struct ucb1x00_ts *ts)
{
ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
UCB_TS_CR_TSMX_POW | UCB_TS_CR_TSPX_POW |
UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_GND |
UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA);
if (machine_is_collie()) {
ucb1x00_io_write(ts->ucb, COLLIE_TC35143_GPIO_TBL_CHK, 0);
ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
UCB_TS_CR_TSPX_POW | UCB_TS_CR_TSMX_POW |
UCB_TS_CR_MODE_POS | UCB_TS_CR_BIAS_ENA);
return ucb1x00_adc_read(ts->ucb, UCB_ADC_INP_TSPY, ts->adcsync);
udelay(55);
return ucb1x00_adc_read(ts->ucb, UCB_ADC_INP_AD2, ts->adcsync);
} else {
ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
UCB_TS_CR_TSMX_POW | UCB_TS_CR_TSPX_POW |
UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_GND |
UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA);
return ucb1x00_adc_read(ts->ucb, UCB_ADC_INP_TSPY, ts->adcsync);
}
}
/*
......@@ -101,12 +115,16 @@ static inline unsigned int ucb1x00_ts_read_pressure(struct ucb1x00_ts *ts)
*/
static inline unsigned int ucb1x00_ts_read_xpos(struct ucb1x00_ts *ts)
{
ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
UCB_TS_CR_TSMX_GND | UCB_TS_CR_TSPX_POW |
UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA);
ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
UCB_TS_CR_TSMX_GND | UCB_TS_CR_TSPX_POW |
UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA);
if (machine_is_collie())
ucb1x00_io_write(ts->ucb, 0, COLLIE_TC35143_GPIO_TBL_CHK);
else {
ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
UCB_TS_CR_TSMX_GND | UCB_TS_CR_TSPX_POW |
UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA);
ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
UCB_TS_CR_TSMX_GND | UCB_TS_CR_TSPX_POW |
UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA);
}
ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
UCB_TS_CR_TSMX_GND | UCB_TS_CR_TSPX_POW |
UCB_TS_CR_MODE_POS | UCB_TS_CR_BIAS_ENA);
......@@ -124,12 +142,17 @@ static inline unsigned int ucb1x00_ts_read_xpos(struct ucb1x00_ts *ts)
*/
static inline unsigned int ucb1x00_ts_read_ypos(struct ucb1x00_ts *ts)
{
ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_POW |
UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA);
ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_POW |
UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA);
if (machine_is_collie())
ucb1x00_io_write(ts->ucb, 0, COLLIE_TC35143_GPIO_TBL_CHK);
else {
ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_POW |
UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA);
ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_POW |
UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA);
}
ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_POW |
UCB_TS_CR_MODE_POS | UCB_TS_CR_BIAS_ENA);
......@@ -163,6 +186,15 @@ static inline unsigned int ucb1x00_ts_read_yres(struct ucb1x00_ts *ts)
return ucb1x00_adc_read(ts->ucb, 0, ts->adcsync);
}
static inline int ucb1x00_ts_pen_down(struct ucb1x00_ts *ts)
{
unsigned int val = ucb1x00_reg_read(ts->ucb, UCB_TS_CR);
if (machine_is_collie())
return (!(val & (UCB_TS_CR_TSPX_LOW)));
else
return (val & (UCB_TS_CR_TSPX_LOW | UCB_TS_CR_TSMX_LOW));
}
/*
* This is a RT kernel thread that handles the ADC accesses
* (mainly so we can use semaphores in the UCB1200 core code
......@@ -186,7 +218,7 @@ static int ucb1x00_thread(void *_ts)
add_wait_queue(&ts->irq_wait, &wait);
while (!kthread_should_stop()) {
unsigned int x, y, p, val;
unsigned int x, y, p;
signed long timeout;
ts->restart = 0;
......@@ -206,12 +238,12 @@ static int ucb1x00_thread(void *_ts)
msleep(10);
ucb1x00_enable(ts->ucb);
val = ucb1x00_reg_read(ts->ucb, UCB_TS_CR);
if (val & (UCB_TS_CR_TSPX_LOW | UCB_TS_CR_TSMX_LOW)) {
if (ucb1x00_ts_pen_down(ts)) {
set_task_state(tsk, TASK_INTERRUPTIBLE);
ucb1x00_enable_irq(ts->ucb, UCB_IRQ_TSPX, UCB_FALLING);
ucb1x00_enable_irq(ts->ucb, UCB_IRQ_TSPX, machine_is_collie() ? UCB_RISING : UCB_FALLING);
ucb1x00_disable(ts->ucb);
/*
......
......@@ -704,15 +704,12 @@ static int pxa_irda_stop(struct net_device *dev)
return 0;
}
static int pxa_irda_suspend(struct device *_dev, pm_message_t state, u32 level)
static int pxa_irda_suspend(struct device *_dev, pm_message_t state)
{
struct net_device *dev = dev_get_drvdata(_dev);
struct pxa_irda *si;
if (!dev || level != SUSPEND_DISABLE)
return 0;
if (netif_running(dev)) {
if (dev && netif_running(dev)) {
si = netdev_priv(dev);
netif_device_detach(dev);
pxa_irda_shutdown(si);
......@@ -721,15 +718,12 @@ static int pxa_irda_suspend(struct device *_dev, pm_message_t state, u32 level)
return 0;
}
static int pxa_irda_resume(struct device *_dev, u32 level)
static int pxa_irda_resume(struct device *_dev)
{
struct net_device *dev = dev_get_drvdata(_dev);
struct pxa_irda *si;
if (!dev || level != RESUME_ENABLE)
return 0;
if (netif_running(dev)) {
if (dev && netif_running(dev)) {
si = netdev_priv(dev);
pxa_irda_startup(si);
netif_device_attach(dev);
......
......@@ -59,6 +59,7 @@ sa1111_cs-$(CONFIG_SA1100_JORNADA720) += sa1100_jornada720.o
sa1100_cs-y += sa1100_generic.o
sa1100_cs-$(CONFIG_SA1100_ASSABET) += sa1100_assabet.o
sa1100_cs-$(CONFIG_SA1100_CERF) += sa1100_cerf.o
sa1100_cs-$(CONFIG_SA1100_COLLIE) += pxa2xx_sharpsl.o
sa1100_cs-$(CONFIG_SA1100_H3600) += sa1100_h3600.o
sa1100_cs-$(CONFIG_SA1100_SHANNON) += sa1100_shannon.o
sa1100_cs-$(CONFIG_SA1100_SIMPAD) += sa1100_simpad.o
......
......@@ -18,10 +18,15 @@
#include <linux/interrupt.h>
#include <linux/device.h>
#include <asm/mach-types.h>
#include <asm/hardware.h>
#include <asm/irq.h>
#include <asm/hardware/scoop.h>
#include <asm/arch/pxa-regs.h>
#ifdef CONFIG_SA1100_COLLIE
#include <asm/arch-sa1100/collie.h>
#else
#include <asm/arch-pxa/pxa-regs.h>
#endif
#include "soc_common.h"
......@@ -38,6 +43,7 @@ static int sharpsl_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
{
int ret;
#ifndef CONFIG_SA1100_COLLIE
/*
* Setup default state of GPIO outputs
* before we enable them as outputs.
......@@ -60,6 +66,7 @@ static int sharpsl_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
pxa_gpio_mode(GPIO55_nPREG_MD);
pxa_gpio_mode(GPIO56_nPWAIT_MD);
pxa_gpio_mode(GPIO57_nIOIS16_MD);
#endif
/* Register interrupts */
if (scoop_devs[skt->nr].cd_irq >= 0) {
......@@ -213,12 +220,20 @@ static void sharpsl_pcmcia_socket_init(struct soc_pcmcia_socket *skt)
write_scoop_reg(scoop_devs[skt->nr].dev, SCOOP_IMR, 0x00C0);
write_scoop_reg(scoop_devs[skt->nr].dev, SCOOP_MCR, 0x0101);
scoop_devs[skt->nr].keep_vs = NO_KEEP_VS;
if (machine_is_collie())
/* We need to disable SS_OUTPUT_ENA here. */
write_scoop_reg(scoop_devs[skt->nr].dev, SCOOP_CPR, read_scoop_reg(scoop_devs[skt->nr].dev, SCOOP_CPR) & ~0x0080);
}
static void sharpsl_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt)
{
/* CF_BUS_OFF */
sharpsl_pcmcia_init_reset(&scoop_devs[skt->nr]);
if (machine_is_collie())
/* We need to disable SS_OUTPUT_ENA here. */
write_scoop_reg(scoop_devs[skt->nr].dev, SCOOP_CPR, read_scoop_reg(scoop_devs[skt->nr].dev, SCOOP_CPR) & ~0x0080);
}
static struct pcmcia_low_level sharpsl_pcmcia_ops = {
......@@ -235,6 +250,19 @@ static struct pcmcia_low_level sharpsl_pcmcia_ops = {
static struct platform_device *sharpsl_pcmcia_device;
#ifdef CONFIG_SA1100_COLLIE
int __init pcmcia_collie_init(struct device *dev)
{
int ret = -ENODEV;
if (machine_is_collie())
ret = sa11xx_drv_pcmcia_probe(dev, &sharpsl_pcmcia_ops, 0, 1);
return ret;
}
#else
static int __init sharpsl_pcmcia_init(void)
{
int ret;
......@@ -269,6 +297,7 @@ static void __exit sharpsl_pcmcia_exit(void)
fs_initcall(sharpsl_pcmcia_init);
module_exit(sharpsl_pcmcia_exit);
#endif
MODULE_DESCRIPTION("Sharp SL Series PCMCIA Support");
MODULE_LICENSE("GPL");
......@@ -38,8 +38,12 @@
#include <pcmcia/cs.h>
#include <pcmcia/ss.h>
#include <asm/hardware/scoop.h>
#include "sa1100_generic.h"
int __init pcmcia_collie_init(struct device *dev);
static int (*sa11x0_pcmcia_hw_init[])(struct device *dev) = {
#ifdef CONFIG_SA1100_ASSABET
pcmcia_assabet_init,
......@@ -56,6 +60,9 @@ static int (*sa11x0_pcmcia_hw_init[])(struct device *dev) = {
#ifdef CONFIG_SA1100_SIMPAD
pcmcia_simpad_init,
#endif
#ifdef CONFIG_SA1100_COLLIE
pcmcia_collie_init,
#endif
};
static int sa11x0_drv_pcmcia_probe(struct device *dev)
......
......@@ -22,7 +22,7 @@
#define IXDP2X01_CPLD_REGION_SIZE 0x00100000
#define IXDP2X01_CPLD_VIRT_REG(reg) (volatile unsigned long*)(IXDP2X01_VIRT_CPLD_BASE | reg)
#define IXDP2X01_CPLD_PHYS_REG(reg) (volatile u32*)(IXDP2X01_PHYS_CPLD_BASE | reg)
#define IXDP2X01_CPLD_PHYS_REG(reg) (IXDP2X01_PHYS_CPLD_BASE | reg)
#define IXDP2X01_UART1_VIRT_BASE IXDP2X01_CPLD_VIRT_REG(0x40)
#define IXDP2X01_UART1_PHYS_BASE IXDP2X01_CPLD_PHYS_REG(0x40)
......
......@@ -113,7 +113,7 @@ __ixp4xx_writeb(u8 value, u32 addr)
}
static inline void
__ixp4xx_writesb(u32 bus_addr, u8 *vaddr, int count)
__ixp4xx_writesb(u32 bus_addr, const u8 *vaddr, int count)
{
while (count--)
writeb(*vaddr++, bus_addr);
......@@ -136,7 +136,7 @@ __ixp4xx_writew(u16 value, u32 addr)
}
static inline void
__ixp4xx_writesw(u32 bus_addr, u16 *vaddr, int count)
__ixp4xx_writesw(u32 bus_addr, const u16 *vaddr, int count)
{
while (count--)
writew(*vaddr++, bus_addr);
......@@ -154,7 +154,7 @@ __ixp4xx_writel(u32 value, u32 addr)
}
static inline void
__ixp4xx_writesl(u32 bus_addr, u32 *vaddr, int count)
__ixp4xx_writesl(u32 bus_addr, const u32 *vaddr, int count)
{
while (count--)
writel(*vaddr++, bus_addr);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册