2 * arch/sh/cchips/voyagergx/consistent.c
4 * Copyright (C) 2004 Paul Mundt
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file "COPYING" in the main directory of this archive
11 #include <linux/dma-mapping.h>
12 #include <linux/slab.h>
13 #include <linux/list.h>
14 #include <linux/types.h>
15 #include <linux/module.h>
16 #include <linux/device.h>
20 struct voya_alloc_entry
{
21 struct list_head list
;
26 static DEFINE_SPINLOCK(voya_list_lock
);
27 static LIST_HEAD(voya_alloc_list
);
29 #define OHCI_SRAM_START 0xb0000000
30 #define OHCI_HCCA_SIZE 0x100
31 #define OHCI_SRAM_SIZE 0x10000
33 #define VOYAGER_OHCI_NAME "voyager-ohci"
35 void *voyagergx_consistent_alloc(struct device
*dev
, size_t size
,
36 dma_addr_t
*handle
, gfp_t flag
)
38 struct list_head
*list
= &voya_alloc_list
;
39 struct voya_alloc_entry
*entry
;
40 unsigned long start
, end
;
44 * The SM501 contains an integrated 8051 with its own SRAM.
45 * Devices within the cchip can all hook into the 8051 SRAM.
46 * We presently use this for the OHCI.
48 * Everything else goes through consistent_alloc().
50 if (!dev
|| strcmp(dev
->driver
->name
, VOYAGER_OHCI_NAME
))
53 start
= OHCI_SRAM_START
+ OHCI_HCCA_SIZE
;
55 entry
= kmalloc(sizeof(struct voya_alloc_entry
), GFP_ATOMIC
);
57 return ERR_PTR(-ENOMEM
);
59 entry
->len
= (size
+ 15) & ~15;
62 * The basis for this allocator is dwmw2's malloc.. the
63 * Matrox allocator :-)
65 spin_lock_irqsave(&voya_list_lock
, flags
);
66 list_for_each(list
, &voya_alloc_list
) {
67 struct voya_alloc_entry
*p
;
69 p
= list_entry(list
, struct voya_alloc_entry
, list
);
71 if (p
->ofs
- start
>= size
)
74 start
= p
->ofs
+ p
->len
;
77 end
= start
+ (OHCI_SRAM_SIZE
- OHCI_HCCA_SIZE
);
78 list
= &voya_alloc_list
;
80 if (end
- start
>= size
) {
83 list_add_tail(&entry
->list
, list
);
84 spin_unlock_irqrestore(&voya_list_lock
, flags
);
91 spin_unlock_irqrestore(&voya_list_lock
, flags
);
93 return ERR_PTR(-EINVAL
);
96 int voyagergx_consistent_free(struct device
*dev
, size_t size
,
97 void *vaddr
, dma_addr_t handle
)
99 struct voya_alloc_entry
*entry
;
102 if (!dev
|| strcmp(dev
->driver
->name
, VOYAGER_OHCI_NAME
))
105 spin_lock_irqsave(&voya_list_lock
, flags
);
106 list_for_each_entry(entry
, &voya_alloc_list
, list
) {
107 if (entry
->ofs
!= handle
)
110 list_del(&entry
->list
);
115 spin_unlock_irqrestore(&voya_list_lock
, flags
);
120 EXPORT_SYMBOL(voyagergx_consistent_alloc
);
121 EXPORT_SYMBOL(voyagergx_consistent_free
);