1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun * Copyright (C) 2004 - 2007 Paul Mundt
3*4882a593Smuzhiyun *
4*4882a593Smuzhiyun * This file is subject to the terms and conditions of the GNU General Public
5*4882a593Smuzhiyun * License. See the file "COPYING" in the main directory of this archive
6*4882a593Smuzhiyun * for more details.
7*4882a593Smuzhiyun */
8*4882a593Smuzhiyun #include <linux/mm.h>
9*4882a593Smuzhiyun #include <linux/init.h>
10*4882a593Smuzhiyun #include <linux/platform_device.h>
11*4882a593Smuzhiyun #include <linux/dma-mapping.h>
12*4882a593Smuzhiyun #include <linux/io.h>
13*4882a593Smuzhiyun
memchunk_setup(char * str)14*4882a593Smuzhiyun static int __init memchunk_setup(char *str)
15*4882a593Smuzhiyun {
16*4882a593Smuzhiyun return 1; /* accept anything that begins with "memchunk." */
17*4882a593Smuzhiyun }
18*4882a593Smuzhiyun __setup("memchunk.", memchunk_setup);
19*4882a593Smuzhiyun
memchunk_cmdline_override(char * name,unsigned long * sizep)20*4882a593Smuzhiyun static void __init memchunk_cmdline_override(char *name, unsigned long *sizep)
21*4882a593Smuzhiyun {
22*4882a593Smuzhiyun char *p = boot_command_line;
23*4882a593Smuzhiyun int k = strlen(name);
24*4882a593Smuzhiyun
25*4882a593Smuzhiyun while ((p = strstr(p, "memchunk."))) {
26*4882a593Smuzhiyun p += 9; /* strlen("memchunk.") */
27*4882a593Smuzhiyun if (!strncmp(name, p, k) && p[k] == '=') {
28*4882a593Smuzhiyun p += k + 1;
29*4882a593Smuzhiyun *sizep = memparse(p, NULL);
30*4882a593Smuzhiyun pr_info("%s: forcing memory chunk size to 0x%08lx\n",
31*4882a593Smuzhiyun name, *sizep);
32*4882a593Smuzhiyun break;
33*4882a593Smuzhiyun }
34*4882a593Smuzhiyun }
35*4882a593Smuzhiyun }
36*4882a593Smuzhiyun
platform_resource_setup_memory(struct platform_device * pdev,char * name,unsigned long memsize)37*4882a593Smuzhiyun int __init platform_resource_setup_memory(struct platform_device *pdev,
38*4882a593Smuzhiyun char *name, unsigned long memsize)
39*4882a593Smuzhiyun {
40*4882a593Smuzhiyun struct resource *r;
41*4882a593Smuzhiyun dma_addr_t dma_handle;
42*4882a593Smuzhiyun void *buf;
43*4882a593Smuzhiyun
44*4882a593Smuzhiyun r = pdev->resource + pdev->num_resources - 1;
45*4882a593Smuzhiyun if (r->flags) {
46*4882a593Smuzhiyun pr_warn("%s: unable to find empty space for resource\n", name);
47*4882a593Smuzhiyun return -EINVAL;
48*4882a593Smuzhiyun }
49*4882a593Smuzhiyun
50*4882a593Smuzhiyun memchunk_cmdline_override(name, &memsize);
51*4882a593Smuzhiyun if (!memsize)
52*4882a593Smuzhiyun return 0;
53*4882a593Smuzhiyun
54*4882a593Smuzhiyun buf = dma_alloc_coherent(&pdev->dev, memsize, &dma_handle, GFP_KERNEL);
55*4882a593Smuzhiyun if (!buf) {
56*4882a593Smuzhiyun pr_warn("%s: unable to allocate memory\n", name);
57*4882a593Smuzhiyun return -ENOMEM;
58*4882a593Smuzhiyun }
59*4882a593Smuzhiyun
60*4882a593Smuzhiyun r->flags = IORESOURCE_MEM;
61*4882a593Smuzhiyun r->start = dma_handle;
62*4882a593Smuzhiyun r->end = r->start + memsize - 1;
63*4882a593Smuzhiyun r->name = name;
64*4882a593Smuzhiyun return 0;
65*4882a593Smuzhiyun }
66