aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/common
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/common')
-rw-r--r--arch/arm/common/Makefile1
-rw-r--r--arch/arm/common/dmabounce.c67
-rw-r--r--arch/arm/common/uengine.c58
3 files changed, 70 insertions, 56 deletions
diff --git a/arch/arm/common/Makefile b/arch/arm/common/Makefile
index 847e3e6356c6..e1289a256ce5 100644
--- a/arch/arm/common/Makefile
+++ b/arch/arm/common/Makefile
@@ -16,3 +16,4 @@ obj-$(CONFIG_SHARP_PARAM) += sharpsl_param.o
16obj-$(CONFIG_SHARPSL_PM) += sharpsl_pm.o 16obj-$(CONFIG_SHARPSL_PM) += sharpsl_pm.o
17obj-$(CONFIG_SHARP_SCOOP) += scoop.o 17obj-$(CONFIG_SHARP_SCOOP) += scoop.o
18obj-$(CONFIG_ARCH_IXP2000) += uengine.o 18obj-$(CONFIG_ARCH_IXP2000) += uengine.o
19obj-$(CONFIG_ARCH_IXP23XX) += uengine.o
diff --git a/arch/arm/common/dmabounce.c b/arch/arm/common/dmabounce.c
index 7971d0dc6892..5b7c26395b44 100644
--- a/arch/arm/common/dmabounce.c
+++ b/arch/arm/common/dmabounce.c
@@ -77,6 +77,8 @@ struct dmabounce_device_info {
77#endif 77#endif
78 struct dmabounce_pool small; 78 struct dmabounce_pool small;
79 struct dmabounce_pool large; 79 struct dmabounce_pool large;
80
81 rwlock_t lock;
80}; 82};
81 83
82static LIST_HEAD(dmabounce_devs); 84static LIST_HEAD(dmabounce_devs);
@@ -116,6 +118,7 @@ alloc_safe_buffer(struct dmabounce_device_info *device_info, void *ptr,
116 struct safe_buffer *buf; 118 struct safe_buffer *buf;
117 struct dmabounce_pool *pool; 119 struct dmabounce_pool *pool;
118 struct device *dev = device_info->dev; 120 struct device *dev = device_info->dev;
121 unsigned long flags;
119 122
120 dev_dbg(dev, "%s(ptr=%p, size=%d, dir=%d)\n", 123 dev_dbg(dev, "%s(ptr=%p, size=%d, dir=%d)\n",
121 __func__, ptr, size, dir); 124 __func__, ptr, size, dir);
@@ -163,8 +166,12 @@ alloc_safe_buffer(struct dmabounce_device_info *device_info, void *ptr,
163 print_alloc_stats(device_info); 166 print_alloc_stats(device_info);
164#endif 167#endif
165 168
169 write_lock_irqsave(&device_info->lock, flags);
170
166 list_add(&buf->node, &device_info->safe_buffers); 171 list_add(&buf->node, &device_info->safe_buffers);
167 172
173 write_unlock_irqrestore(&device_info->lock, flags);
174
168 return buf; 175 return buf;
169} 176}
170 177
@@ -172,22 +179,32 @@ alloc_safe_buffer(struct dmabounce_device_info *device_info, void *ptr,
172static inline struct safe_buffer * 179static inline struct safe_buffer *
173find_safe_buffer(struct dmabounce_device_info *device_info, dma_addr_t safe_dma_addr) 180find_safe_buffer(struct dmabounce_device_info *device_info, dma_addr_t safe_dma_addr)
174{ 181{
175 struct safe_buffer *b; 182 struct safe_buffer *b = NULL;
183 unsigned long flags;
184
185 read_lock_irqsave(&device_info->lock, flags);
176 186
177 list_for_each_entry(b, &device_info->safe_buffers, node) 187 list_for_each_entry(b, &device_info->safe_buffers, node)
178 if (b->safe_dma_addr == safe_dma_addr) 188 if (b->safe_dma_addr == safe_dma_addr)
179 return b; 189 break;
180 190
181 return NULL; 191 read_unlock_irqrestore(&device_info->lock, flags);
192 return b;
182} 193}
183 194
184static inline void 195static inline void
185free_safe_buffer(struct dmabounce_device_info *device_info, struct safe_buffer *buf) 196free_safe_buffer(struct dmabounce_device_info *device_info, struct safe_buffer *buf)
186{ 197{
198 unsigned long flags;
199
187 dev_dbg(device_info->dev, "%s(buf=%p)\n", __func__, buf); 200 dev_dbg(device_info->dev, "%s(buf=%p)\n", __func__, buf);
188 201
202 write_lock_irqsave(&device_info->lock, flags);
203
189 list_del(&buf->node); 204 list_del(&buf->node);
190 205
206 write_unlock_irqrestore(&device_info->lock, flags);
207
191 if (buf->pool) 208 if (buf->pool)
192 dma_pool_free(buf->pool->pool, buf->safe, buf->safe_dma_addr); 209 dma_pool_free(buf->pool->pool, buf->safe, buf->safe_dma_addr);
193 else 210 else
@@ -396,7 +413,6 @@ dma_addr_t
396dma_map_single(struct device *dev, void *ptr, size_t size, 413dma_map_single(struct device *dev, void *ptr, size_t size,
397 enum dma_data_direction dir) 414 enum dma_data_direction dir)
398{ 415{
399 unsigned long flags;
400 dma_addr_t dma_addr; 416 dma_addr_t dma_addr;
401 417
402 dev_dbg(dev, "%s(ptr=%p,size=%d,dir=%x)\n", 418 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,
404 420
405 BUG_ON(dir == DMA_NONE); 421 BUG_ON(dir == DMA_NONE);
406 422
407 local_irq_save(flags);
408
409 dma_addr = map_single(dev, ptr, size, dir); 423 dma_addr = map_single(dev, ptr, size, dir);
410 424
411 local_irq_restore(flags);
412
413 return dma_addr; 425 return dma_addr;
414} 426}
415 427
@@ -424,25 +436,18 @@ void
424dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size, 436dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
425 enum dma_data_direction dir) 437 enum dma_data_direction dir)
426{ 438{
427 unsigned long flags;
428
429 dev_dbg(dev, "%s(ptr=%p,size=%d,dir=%x)\n", 439 dev_dbg(dev, "%s(ptr=%p,size=%d,dir=%x)\n",
430 __func__, (void *) dma_addr, size, dir); 440 __func__, (void *) dma_addr, size, dir);
431 441
432 BUG_ON(dir == DMA_NONE); 442 BUG_ON(dir == DMA_NONE);
433 443
434 local_irq_save(flags);
435
436 unmap_single(dev, dma_addr, size, dir); 444 unmap_single(dev, dma_addr, size, dir);
437
438 local_irq_restore(flags);
439} 445}
440 446
441int 447int
442dma_map_sg(struct device *dev, struct scatterlist *sg, int nents, 448dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
443 enum dma_data_direction dir) 449 enum dma_data_direction dir)
444{ 450{
445 unsigned long flags;
446 int i; 451 int i;
447 452
448 dev_dbg(dev, "%s(sg=%p,nents=%d,dir=%x)\n", 453 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,
450 455
451 BUG_ON(dir == DMA_NONE); 456 BUG_ON(dir == DMA_NONE);
452 457
453 local_irq_save(flags);
454
455 for (i = 0; i < nents; i++, sg++) { 458 for (i = 0; i < nents; i++, sg++) {
456 struct page *page = sg->page; 459 struct page *page = sg->page;
457 unsigned int offset = sg->offset; 460 unsigned int offset = sg->offset;
@@ -462,8 +465,6 @@ dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
462 map_single(dev, ptr, length, dir); 465 map_single(dev, ptr, length, dir);
463 } 466 }
464 467
465 local_irq_restore(flags);
466
467 return nents; 468 return nents;
468} 469}
469 470
@@ -471,7 +472,6 @@ void
471dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nents, 472dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nents,
472 enum dma_data_direction dir) 473 enum dma_data_direction dir)
473{ 474{
474 unsigned long flags;
475 int i; 475 int i;
476 476
477 dev_dbg(dev, "%s(sg=%p,nents=%d,dir=%x)\n", 477 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,
479 479
480 BUG_ON(dir == DMA_NONE); 480 BUG_ON(dir == DMA_NONE);
481 481
482 local_irq_save(flags);
483
484 for (i = 0; i < nents; i++, sg++) { 482 for (i = 0; i < nents; i++, sg++) {
485 dma_addr_t dma_addr = sg->dma_address; 483 dma_addr_t dma_addr = sg->dma_address;
486 unsigned int length = sg->length; 484 unsigned int length = sg->length;
487 485
488 unmap_single(dev, dma_addr, length, dir); 486 unmap_single(dev, dma_addr, length, dir);
489 } 487 }
490
491 local_irq_restore(flags);
492} 488}
493 489
494void 490void
495dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_addr, size_t size, 491dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_addr, size_t size,
496 enum dma_data_direction dir) 492 enum dma_data_direction dir)
497{ 493{
498 unsigned long flags;
499
500 dev_dbg(dev, "%s(ptr=%p,size=%d,dir=%x)\n", 494 dev_dbg(dev, "%s(ptr=%p,size=%d,dir=%x)\n",
501 __func__, (void *) dma_addr, size, dir); 495 __func__, (void *) dma_addr, size, dir);
502 496
503 local_irq_save(flags);
504
505 sync_single(dev, dma_addr, size, dir); 497 sync_single(dev, dma_addr, size, dir);
506
507 local_irq_restore(flags);
508} 498}
509 499
510void 500void
511dma_sync_single_for_device(struct device *dev, dma_addr_t dma_addr, size_t size, 501dma_sync_single_for_device(struct device *dev, dma_addr_t dma_addr, size_t size,
512 enum dma_data_direction dir) 502 enum dma_data_direction dir)
513{ 503{
514 unsigned long flags;
515
516 dev_dbg(dev, "%s(ptr=%p,size=%d,dir=%x)\n", 504 dev_dbg(dev, "%s(ptr=%p,size=%d,dir=%x)\n",
517 __func__, (void *) dma_addr, size, dir); 505 __func__, (void *) dma_addr, size, dir);
518 506
519 local_irq_save(flags);
520
521 sync_single(dev, dma_addr, size, dir); 507 sync_single(dev, dma_addr, size, dir);
522
523 local_irq_restore(flags);
524} 508}
525 509
526void 510void
527dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, int nents, 511dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, int nents,
528 enum dma_data_direction dir) 512 enum dma_data_direction dir)
529{ 513{
530 unsigned long flags;
531 int i; 514 int i;
532 515
533 dev_dbg(dev, "%s(sg=%p,nents=%d,dir=%x)\n", 516 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,
535 518
536 BUG_ON(dir == DMA_NONE); 519 BUG_ON(dir == DMA_NONE);
537 520
538 local_irq_save(flags);
539
540 for (i = 0; i < nents; i++, sg++) { 521 for (i = 0; i < nents; i++, sg++) {
541 dma_addr_t dma_addr = sg->dma_address; 522 dma_addr_t dma_addr = sg->dma_address;
542 unsigned int length = sg->length; 523 unsigned int length = sg->length;
543 524
544 sync_single(dev, dma_addr, length, dir); 525 sync_single(dev, dma_addr, length, dir);
545 } 526 }
546
547 local_irq_restore(flags);
548} 527}
549 528
550void 529void
551dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nents, 530dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nents,
552 enum dma_data_direction dir) 531 enum dma_data_direction dir)
553{ 532{
554 unsigned long flags;
555 int i; 533 int i;
556 534
557 dev_dbg(dev, "%s(sg=%p,nents=%d,dir=%x)\n", 535 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,
559 537
560 BUG_ON(dir == DMA_NONE); 538 BUG_ON(dir == DMA_NONE);
561 539
562 local_irq_save(flags);
563
564 for (i = 0; i < nents; i++, sg++) { 540 for (i = 0; i < nents; i++, sg++) {
565 dma_addr_t dma_addr = sg->dma_address; 541 dma_addr_t dma_addr = sg->dma_address;
566 unsigned int length = sg->length; 542 unsigned int length = sg->length;
567 543
568 sync_single(dev, dma_addr, length, dir); 544 sync_single(dev, dma_addr, length, dir);
569 } 545 }
570
571 local_irq_restore(flags);
572} 546}
573 547
574static int 548static int
@@ -622,6 +596,7 @@ dmabounce_register_dev(struct device *dev, unsigned long small_buffer_size,
622 596
623 device_info->dev = dev; 597 device_info->dev = dev;
624 INIT_LIST_HEAD(&device_info->safe_buffers); 598 INIT_LIST_HEAD(&device_info->safe_buffers);
599 rwlock_init(&device_info->lock);
625 600
626#ifdef STATS 601#ifdef STATS
627 device_info->total_allocs = 0; 602 device_info->total_allocs = 0;
diff --git a/arch/arm/common/uengine.c b/arch/arm/common/uengine.c
index a1310b71004e..dfca596a9a27 100644
--- a/arch/arm/common/uengine.c
+++ b/arch/arm/common/uengine.c
@@ -18,10 +18,26 @@
18#include <linux/module.h> 18#include <linux/module.h>
19#include <linux/string.h> 19#include <linux/string.h>
20#include <asm/hardware.h> 20#include <asm/hardware.h>
21#include <asm/arch/ixp2000-regs.h> 21#include <asm/arch/hardware.h>
22#include <asm/hardware/uengine.h> 22#include <asm/hardware/uengine.h>
23#include <asm/io.h> 23#include <asm/io.h>
24 24
25#if defined(CONFIG_ARCH_IXP2000)
26#define IXP_UENGINE_CSR_VIRT_BASE IXP2000_UENGINE_CSR_VIRT_BASE
27#define IXP_PRODUCT_ID IXP2000_PRODUCT_ID
28#define IXP_MISC_CONTROL IXP2000_MISC_CONTROL
29#define IXP_RESET1 IXP2000_RESET1
30#else
31#if defined(CONFIG_ARCH_IXP23XX)
32#define IXP_UENGINE_CSR_VIRT_BASE IXP23XX_UENGINE_CSR_VIRT_BASE
33#define IXP_PRODUCT_ID IXP23XX_PRODUCT_ID
34#define IXP_MISC_CONTROL IXP23XX_MISC_CONTROL
35#define IXP_RESET1 IXP23XX_RESET1
36#else
37#error unknown platform
38#endif
39#endif
40
25#define USTORE_ADDRESS 0x000 41#define USTORE_ADDRESS 0x000
26#define USTORE_DATA_LOWER 0x004 42#define USTORE_DATA_LOWER 0x004
27#define USTORE_DATA_UPPER 0x008 43#define USTORE_DATA_UPPER 0x008
@@ -43,7 +59,7 @@ u32 ixp2000_uengine_mask;
43 59
44static void *ixp2000_uengine_csr_area(int uengine) 60static void *ixp2000_uengine_csr_area(int uengine)
45{ 61{
46 return ((void *)IXP2000_UENGINE_CSR_VIRT_BASE) + (uengine << 10); 62 return ((void *)IXP_UENGINE_CSR_VIRT_BASE) + (uengine << 10);
47} 63}
48 64
49/* 65/*
@@ -91,8 +107,13 @@ EXPORT_SYMBOL(ixp2000_uengine_csr_write);
91 107
92void ixp2000_uengine_reset(u32 uengine_mask) 108void ixp2000_uengine_reset(u32 uengine_mask)
93{ 109{
94 ixp2000_reg_wrb(IXP2000_RESET1, uengine_mask & ixp2000_uengine_mask); 110 u32 value;
95 ixp2000_reg_wrb(IXP2000_RESET1, 0); 111
112 value = ixp2000_reg_read(IXP_RESET1) & ~ixp2000_uengine_mask;
113
114 uengine_mask &= ixp2000_uengine_mask;
115 ixp2000_reg_wrb(IXP_RESET1, value | uengine_mask);
116 ixp2000_reg_wrb(IXP_RESET1, value);
96} 117}
97EXPORT_SYMBOL(ixp2000_uengine_reset); 118EXPORT_SYMBOL(ixp2000_uengine_reset);
98 119
@@ -235,11 +256,12 @@ static int check_ixp_type(struct ixp2000_uengine_code *c)
235 u32 product_id; 256 u32 product_id;
236 u32 rev; 257 u32 rev;
237 258
238 product_id = ixp2000_reg_read(IXP2000_PRODUCT_ID); 259 product_id = ixp2000_reg_read(IXP_PRODUCT_ID);
239 if (((product_id >> 16) & 0x1f) != 0) 260 if (((product_id >> 16) & 0x1f) != 0)
240 return 0; 261 return 0;
241 262
242 switch ((product_id >> 8) & 0xff) { 263 switch ((product_id >> 8) & 0xff) {
264#ifdef CONFIG_ARCH_IXP2000
243 case 0: /* IXP2800 */ 265 case 0: /* IXP2800 */
244 if (!(c->cpu_model_bitmask & 4)) 266 if (!(c->cpu_model_bitmask & 4))
245 return 0; 267 return 0;
@@ -254,6 +276,14 @@ static int check_ixp_type(struct ixp2000_uengine_code *c)
254 if (!(c->cpu_model_bitmask & 2)) 276 if (!(c->cpu_model_bitmask & 2))
255 return 0; 277 return 0;
256 break; 278 break;
279#endif
280
281#ifdef CONFIG_ARCH_IXP23XX
282 case 4: /* IXP23xx */
283 if (!(c->cpu_model_bitmask & 0x3f0))
284 return 0;
285 break;
286#endif
257 287
258 default: 288 default:
259 return 0; 289 return 0;
@@ -432,7 +462,8 @@ static int __init ixp2000_uengine_init(void)
432 /* 462 /*
433 * Determine number of microengines present. 463 * Determine number of microengines present.
434 */ 464 */
435 switch ((ixp2000_reg_read(IXP2000_PRODUCT_ID) >> 8) & 0x1fff) { 465 switch ((ixp2000_reg_read(IXP_PRODUCT_ID) >> 8) & 0x1fff) {
466#ifdef CONFIG_ARCH_IXP2000
436 case 0: /* IXP2800 */ 467 case 0: /* IXP2800 */
437 case 1: /* IXP2850 */ 468 case 1: /* IXP2850 */
438 ixp2000_uengine_mask = 0x00ff00ff; 469 ixp2000_uengine_mask = 0x00ff00ff;
@@ -441,10 +472,17 @@ static int __init ixp2000_uengine_init(void)
441 case 2: /* IXP2400 */ 472 case 2: /* IXP2400 */
442 ixp2000_uengine_mask = 0x000f000f; 473 ixp2000_uengine_mask = 0x000f000f;
443 break; 474 break;
475#endif
476
477#ifdef CONFIG_ARCH_IXP23XX
478 case 4: /* IXP23xx */
479 ixp2000_uengine_mask = (*IXP23XX_EXP_CFG_FUSE >> 8) & 0xf;
480 break;
481#endif
444 482
445 default: 483 default:
446 printk(KERN_INFO "Detected unknown IXP2000 model (%.8x)\n", 484 printk(KERN_INFO "Detected unknown IXP2000 model (%.8x)\n",
447 (unsigned int)ixp2000_reg_read(IXP2000_PRODUCT_ID)); 485 (unsigned int)ixp2000_reg_read(IXP_PRODUCT_ID));
448 ixp2000_uengine_mask = 0x00000000; 486 ixp2000_uengine_mask = 0x00000000;
449 break; 487 break;
450 } 488 }
@@ -457,15 +495,15 @@ static int __init ixp2000_uengine_init(void)
457 /* 495 /*
458 * Synchronise timestamp counters across all microengines. 496 * Synchronise timestamp counters across all microengines.
459 */ 497 */
460 value = ixp2000_reg_read(IXP2000_MISC_CONTROL); 498 value = ixp2000_reg_read(IXP_MISC_CONTROL);
461 ixp2000_reg_wrb(IXP2000_MISC_CONTROL, value & ~0x80); 499 ixp2000_reg_wrb(IXP_MISC_CONTROL, value & ~0x80);
462 for (uengine = 0; uengine < 32; uengine++) { 500 for (uengine = 0; uengine < 32; uengine++) {
463 if (ixp2000_uengine_mask & (1 << uengine)) { 501 if (ixp2000_uengine_mask & (1 << uengine)) {
464 ixp2000_uengine_csr_write(uengine, TIMESTAMP_LOW, 0); 502 ixp2000_uengine_csr_write(uengine, TIMESTAMP_LOW, 0);
465 ixp2000_uengine_csr_write(uengine, TIMESTAMP_HIGH, 0); 503 ixp2000_uengine_csr_write(uengine, TIMESTAMP_HIGH, 0);
466 } 504 }
467 } 505 }
468 ixp2000_reg_wrb(IXP2000_MISC_CONTROL, value | 0x80); 506 ixp2000_reg_wrb(IXP_MISC_CONTROL, value | 0x80);
469 507
470 return 0; 508 return 0;
471} 509}