• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/linux/linux-2.6/arch/m68k/amiga/
1/*
2**  linux/amiga/chipram.c
3**
4**      Modified 03-May-94 by Geert Uytterhoeven <geert@linux-m68k.org>
5**          - 64-bit aligned allocations for full AGA compatibility
6**
7**	Rewritten 15/9/2000 by Geert to use resource management
8*/
9
10#include <linux/types.h>
11#include <linux/kernel.h>
12#include <linux/mm.h>
13#include <linux/init.h>
14#include <linux/ioport.h>
15#include <linux/slab.h>
16#include <linux/string.h>
17#include <linux/module.h>
18
19#include <asm/page.h>
20#include <asm/amigahw.h>
21
22unsigned long amiga_chip_size;
23EXPORT_SYMBOL(amiga_chip_size);
24
25static struct resource chipram_res = {
26    .name = "Chip RAM", .start = CHIP_PHYSADDR
27};
28static unsigned long chipavail;
29
30
31void __init amiga_chip_init(void)
32{
33    if (!AMIGAHW_PRESENT(CHIP_RAM))
34	return;
35
36    /*
37     *  Remove the first 4 pages where PPC exception handlers will be located
38     */
39    amiga_chip_size -= 0x4000;
40    chipram_res.end = amiga_chip_size-1;
41    request_resource(&iomem_resource, &chipram_res);
42
43    chipavail = amiga_chip_size;
44}
45
46
47void *amiga_chip_alloc(unsigned long size, const char *name)
48{
49    struct resource *res;
50
51    /* round up */
52    size = PAGE_ALIGN(size);
53
54#ifdef DEBUG
55    printk("amiga_chip_alloc: allocate %ld bytes\n", size);
56#endif
57    res = kzalloc(sizeof(struct resource), GFP_KERNEL);
58    if (!res)
59	return NULL;
60    res->name = name;
61
62    if (allocate_resource(&chipram_res, res, size, 0, UINT_MAX, PAGE_SIZE, NULL, NULL) < 0) {
63	kfree(res);
64	return NULL;
65    }
66    chipavail -= size;
67#ifdef DEBUG
68    printk("amiga_chip_alloc: returning %lx\n", res->start);
69#endif
70    return (void *)ZTWO_VADDR(res->start);
71}
72EXPORT_SYMBOL(amiga_chip_alloc);
73
74
75    /*
76     *  Warning:
77     *  amiga_chip_alloc_res is meant only for drivers that need to allocate
78     *  Chip RAM before kmalloc() is functional. As a consequence, those
79     *  drivers must not free that Chip RAM afterwards.
80     */
81
82void * __init amiga_chip_alloc_res(unsigned long size, struct resource *res)
83{
84    unsigned long start;
85
86    /* round up */
87    size = PAGE_ALIGN(size);
88    /* dmesg into chipmem prefers memory at the safe end */
89    start = CHIP_PHYSADDR + chipavail - size;
90
91#ifdef DEBUG
92    printk("amiga_chip_alloc_res: allocate %ld bytes\n", size);
93#endif
94    if (allocate_resource(&chipram_res, res, size, start, UINT_MAX, PAGE_SIZE, NULL, NULL) < 0) {
95	printk("amiga_chip_alloc_res: first alloc failed!\n");
96	if (allocate_resource(&chipram_res, res, size, 0, UINT_MAX, PAGE_SIZE, NULL, NULL) < 0)
97	    return NULL;
98    }
99    chipavail -= size;
100#ifdef DEBUG
101    printk("amiga_chip_alloc_res: returning %lx\n", res->start);
102#endif
103    return (void *)ZTWO_VADDR(res->start);
104}
105
106void amiga_chip_free(void *ptr)
107{
108    unsigned long start = ZTWO_PADDR(ptr);
109    struct resource **p, *res;
110    unsigned long size;
111
112    for (p = &chipram_res.child; (res = *p); p = &res->sibling) {
113	if (res->start != start)
114	    continue;
115	*p = res->sibling;
116	size = res->end-start;
117#ifdef DEBUG
118	printk("amiga_chip_free: free %ld bytes at %p\n", size, ptr);
119#endif
120	chipavail += size;
121	kfree(res);
122	return;
123    }
124    printk("amiga_chip_free: trying to free nonexistent region at %p\n", ptr);
125}
126EXPORT_SYMBOL(amiga_chip_free);
127
128
129unsigned long amiga_chip_avail(void)
130{
131#ifdef DEBUG
132	printk("amiga_chip_avail : %ld bytes\n", chipavail);
133#endif
134	return chipavail;
135}
136EXPORT_SYMBOL(amiga_chip_avail);
137