Skip to content

Commit

Permalink
Merge branch 'devel' of master.kernel.org:/home/rmk/linux-2.6-arm
Browse files Browse the repository at this point in the history
* '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
  ...
  • Loading branch information
Linus Torvalds committed Jun 23, 2006
2 parents 0c97f52 + 0291652 commit 6f3cafc
Show file tree
Hide file tree
Showing 47 changed files with 1,946 additions and 497 deletions.
1 change: 1 addition & 0 deletions arch/arm/common/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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
67 changes: 21 additions & 46 deletions arch/arm/common/dmabounce.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -163,31 +166,45 @@ 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;
}

/* determine if a buffer is from our "safe" pool */
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
Expand Down Expand Up @@ -396,20 +413,15 @@ 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",
__func__, ptr, size, dir);

BUG_ON(dir == DMA_NONE);

local_irq_save(flags);

dma_addr = map_single(dev, ptr, size, dir);

local_irq_restore(flags);

return dma_addr;
}

Expand All @@ -424,34 +436,25 @@ 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",
__func__, sg, nents, dir);

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;
Expand All @@ -462,113 +465,84 @@ dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
map_single(dev, ptr, length, dir);
}

local_irq_restore(flags);

return nents;
}

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",
__func__, sg, nents, dir);

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",
__func__, sg, nents, dir);

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",
__func__, sg, nents, dir);

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
Expand Down Expand Up @@ -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;
Expand Down
58 changes: 48 additions & 10 deletions arch/arm/common/uengine.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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);
}

/*
Expand Down Expand Up @@ -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);

Expand Down Expand Up @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -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;
Expand All @@ -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;
}
Expand All @@ -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;
}
Expand Down
Loading

0 comments on commit 6f3cafc

Please sign in to comment.