blob: 7f2bcee7ac343904883d6012dcabfc8e6d307251 [file] [log] [blame]
Manuel Lauss27dd65a2009-10-04 14:55:28 +02001/*
2 * devoard misc stuff.
3 */
4
5#include <linux/init.h>
Manuel Lauss206aa6c2009-10-19 12:53:37 +02006#include <linux/mtd/mtd.h>
7#include <linux/mtd/map.h>
8#include <linux/mtd/physmap.h>
Manuel Lauss27dd65a2009-10-04 14:55:28 +02009#include <linux/slab.h>
10#include <linux/platform_device.h>
11
12/* register a pcmcia socket */
13int __init db1x_register_pcmcia_socket(unsigned long pseudo_attr_start,
14 unsigned long pseudo_attr_end,
15 unsigned long pseudo_mem_start,
16 unsigned long pseudo_mem_end,
17 unsigned long pseudo_io_start,
18 unsigned long pseudo_io_end,
19 int card_irq,
20 int cd_irq,
21 int stschg_irq,
22 int eject_irq,
23 int id)
24{
25 int cnt, i, ret;
26 struct resource *sr;
27 struct platform_device *pd;
28
29 cnt = 5;
30 if (eject_irq)
31 cnt++;
32 if (stschg_irq)
33 cnt++;
34
35 sr = kzalloc(sizeof(struct resource) * cnt, GFP_KERNEL);
36 if (!sr)
37 return -ENOMEM;
38
39 pd = platform_device_alloc("db1xxx_pcmcia", id);
40 if (!pd) {
41 ret = -ENOMEM;
42 goto out;
43 }
44
45 sr[0].name = "pseudo-attr";
46 sr[0].flags = IORESOURCE_MEM;
47 sr[0].start = pseudo_attr_start;
48 sr[0].end = pseudo_attr_end;
49
50 sr[1].name = "pseudo-mem";
51 sr[1].flags = IORESOURCE_MEM;
52 sr[1].start = pseudo_mem_start;
53 sr[1].end = pseudo_mem_end;
54
55 sr[2].name = "pseudo-io";
56 sr[2].flags = IORESOURCE_MEM;
57 sr[2].start = pseudo_io_start;
58 sr[2].end = pseudo_io_end;
59
60 sr[3].name = "insert";
61 sr[3].flags = IORESOURCE_IRQ;
62 sr[3].start = sr[3].end = cd_irq;
63
64 sr[4].name = "card";
65 sr[4].flags = IORESOURCE_IRQ;
66 sr[4].start = sr[4].end = card_irq;
67
68 i = 5;
69 if (stschg_irq) {
70 sr[i].name = "insert";
71 sr[i].flags = IORESOURCE_IRQ;
72 sr[i].start = sr[i].end = cd_irq;
73 i++;
74 }
75 if (eject_irq) {
76 sr[i].name = "eject";
77 sr[i].flags = IORESOURCE_IRQ;
78 sr[i].start = sr[i].end = eject_irq;
79 }
80
81 pd->resource = sr;
82 pd->num_resources = cnt;
83
84 ret = platform_device_add(pd);
85 if (!ret)
86 return 0;
87
88 platform_device_put(pd);
89out:
90 kfree(sr);
91 return ret;
92}
Manuel Lauss206aa6c2009-10-19 12:53:37 +020093
94#define YAMON_SIZE 0x00100000
95#define YAMON_ENV_SIZE 0x00040000
96
97int __init db1x_register_norflash(unsigned long size, int width,
98 int swapped)
99{
100 struct physmap_flash_data *pfd;
101 struct platform_device *pd;
102 struct mtd_partition *parts;
103 struct resource *res;
104 int ret, i;
105
106 if (size < (8 * 1024 * 1024))
107 return -EINVAL;
108
109 ret = -ENOMEM;
110 parts = kzalloc(sizeof(struct mtd_partition) * 5, GFP_KERNEL);
111 if (!parts)
112 goto out;
113
114 res = kzalloc(sizeof(struct resource), GFP_KERNEL);
115 if (!res)
116 goto out1;
117
118 pfd = kzalloc(sizeof(struct physmap_flash_data), GFP_KERNEL);
119 if (!pfd)
120 goto out2;
121
122 pd = platform_device_alloc("physmap-flash", 0);
123 if (!pd)
124 goto out3;
125
126 /* NOR flash ends at 0x20000000, regardless of size */
127 res->start = 0x20000000 - size;
128 res->end = 0x20000000 - 1;
129 res->flags = IORESOURCE_MEM;
130
131 /* partition setup. Most Develboards have a switch which allows
132 * to swap the physical locations of the 2 NOR flash banks.
133 */
134 i = 0;
135 if (!swapped) {
136 /* first NOR chip */
137 parts[i].offset = 0;
138 parts[i].name = "User FS";
139 parts[i].size = size / 2;
140 i++;
141 }
142
143 parts[i].offset = MTDPART_OFS_APPEND;
144 parts[i].name = "User FS 2";
145 parts[i].size = (size / 2) - (0x20000000 - 0x1fc00000);
146 i++;
147
148 parts[i].offset = MTDPART_OFS_APPEND;
149 parts[i].name = "YAMON";
150 parts[i].size = YAMON_SIZE;
151 parts[i].mask_flags = MTD_WRITEABLE;
152 i++;
153
154 parts[i].offset = MTDPART_OFS_APPEND;
155 parts[i].name = "raw kernel";
156 parts[i].size = 0x00400000 - YAMON_SIZE - YAMON_ENV_SIZE;
157 i++;
158
159 parts[i].offset = MTDPART_OFS_APPEND;
160 parts[i].name = "YAMON Env";
161 parts[i].size = YAMON_ENV_SIZE;
162 parts[i].mask_flags = MTD_WRITEABLE;
163 i++;
164
165 if (swapped) {
166 parts[i].offset = MTDPART_OFS_APPEND;
167 parts[i].name = "User FS";
168 parts[i].size = size / 2;
169 i++;
170 }
171
172 pfd->width = width;
173 pfd->parts = parts;
174 pfd->nr_parts = 5;
175
176 pd->dev.platform_data = pfd;
177 pd->resource = res;
178 pd->num_resources = 1;
179
180 ret = platform_device_add(pd);
181 if (!ret)
182 return ret;
183
184 platform_device_put(pd);
185out3:
186 kfree(pfd);
187out2:
188 kfree(res);
189out1:
190 kfree(parts);
191out:
192 return ret;
193}