1 | /* |
2 | * Zorro Bus Services |
3 | * |
4 | * Copyright (C) 1995-2003 Geert Uytterhoeven |
5 | * |
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 |
8 | * for more details. |
9 | */ |
10 | |
11 | #include <linux/module.h> |
12 | #include <linux/types.h> |
13 | #include <linux/kernel.h> |
14 | #include <linux/init.h> |
15 | #include <linux/zorro.h> |
16 | #include <linux/bitops.h> |
17 | #include <linux/string.h> |
18 | #include <linux/platform_device.h> |
19 | #include <linux/dma-mapping.h> |
20 | #include <linux/slab.h> |
21 | |
22 | #include <asm/byteorder.h> |
23 | #include <asm/setup.h> |
24 | #include <asm/amigahw.h> |
25 | |
26 | #include "zorro.h" |
27 | |
28 | |
29 | /* |
30 | * Zorro Expansion Devices |
31 | */ |
32 | |
33 | unsigned int zorro_num_autocon; |
34 | struct zorro_dev_init zorro_autocon_init[ZORRO_NUM_AUTO] __initdata; |
35 | struct zorro_dev *zorro_autocon; |
36 | |
37 | |
38 | /* |
39 | * Zorro bus |
40 | */ |
41 | |
42 | struct zorro_bus { |
43 | struct device dev; |
44 | struct zorro_dev devices[]; |
45 | }; |
46 | |
47 | |
48 | /* |
49 | * Find Zorro Devices |
50 | */ |
51 | |
52 | struct zorro_dev *zorro_find_device(zorro_id id, struct zorro_dev *from) |
53 | { |
54 | struct zorro_dev *z; |
55 | |
56 | if (!zorro_num_autocon) |
57 | return NULL; |
58 | |
59 | for (z = from ? from+1 : &zorro_autocon[0]; |
60 | z < zorro_autocon+zorro_num_autocon; |
61 | z++) |
62 | if (id == ZORRO_WILDCARD || id == z->id) |
63 | return z; |
64 | return NULL; |
65 | } |
66 | EXPORT_SYMBOL(zorro_find_device); |
67 | |
68 | |
69 | /* |
70 | * Bitmask indicating portions of available Zorro II RAM that are unused |
71 | * by the system. Every bit represents a 64K chunk, for a maximum of 8MB |
72 | * (128 chunks, physical 0x00200000-0x009fffff). |
73 | * |
74 | * If you want to use (= allocate) portions of this RAM, you should clear |
75 | * the corresponding bits. |
76 | * |
77 | * Possible uses: |
78 | * - z2ram device |
79 | * - SCSI DMA bounce buffers |
80 | * |
81 | * FIXME: use the normal resource management |
82 | */ |
83 | |
84 | DECLARE_BITMAP(zorro_unused_z2ram, 128); |
85 | EXPORT_SYMBOL(zorro_unused_z2ram); |
86 | |
87 | |
88 | static void __init mark_region(unsigned long start, unsigned long end, |
89 | int flag) |
90 | { |
91 | if (flag) |
92 | start += Z2RAM_CHUNKMASK; |
93 | else |
94 | end += Z2RAM_CHUNKMASK; |
95 | start &= ~Z2RAM_CHUNKMASK; |
96 | end &= ~Z2RAM_CHUNKMASK; |
97 | |
98 | if (end <= Z2RAM_START || start >= Z2RAM_END) |
99 | return; |
100 | start = start < Z2RAM_START ? 0x00000000 : start-Z2RAM_START; |
101 | end = end > Z2RAM_END ? Z2RAM_SIZE : end-Z2RAM_START; |
102 | while (start < end) { |
103 | u32 chunk = start>>Z2RAM_CHUNKSHIFT; |
104 | |
105 | if (flag) |
106 | set_bit(nr: chunk, addr: zorro_unused_z2ram); |
107 | else |
108 | clear_bit(nr: chunk, addr: zorro_unused_z2ram); |
109 | start += Z2RAM_CHUNKSIZE; |
110 | } |
111 | } |
112 | |
113 | |
114 | static struct resource __init *zorro_find_parent_resource( |
115 | struct platform_device *bridge, struct zorro_dev *z) |
116 | { |
117 | int i; |
118 | |
119 | for (i = 0; i < bridge->num_resources; i++) { |
120 | struct resource *r = &bridge->resource[i]; |
121 | |
122 | if (zorro_resource_start(z) >= r->start && |
123 | zorro_resource_end(z) <= r->end) |
124 | return r; |
125 | } |
126 | return &iomem_resource; |
127 | } |
128 | |
129 | |
130 | |
131 | static int __init amiga_zorro_probe(struct platform_device *pdev) |
132 | { |
133 | struct zorro_bus *bus; |
134 | struct zorro_dev_init *zi; |
135 | struct zorro_dev *z; |
136 | struct resource *r; |
137 | unsigned int i; |
138 | int error; |
139 | |
140 | /* Initialize the Zorro bus */ |
141 | bus = kzalloc(struct_size(bus, devices, zorro_num_autocon), |
142 | GFP_KERNEL); |
143 | if (!bus) |
144 | return -ENOMEM; |
145 | |
146 | zorro_autocon = bus->devices; |
147 | bus->dev.parent = &pdev->dev; |
148 | dev_set_name(dev: &bus->dev, name: zorro_bus_type.name); |
149 | error = device_register(dev: &bus->dev); |
150 | if (error) { |
151 | pr_err("Zorro: Error registering zorro_bus\n" ); |
152 | put_device(dev: &bus->dev); |
153 | kfree(objp: bus); |
154 | return error; |
155 | } |
156 | platform_set_drvdata(pdev, data: bus); |
157 | |
158 | pr_info("Zorro: Probing AutoConfig expansion devices: %u device%s\n" , |
159 | zorro_num_autocon, zorro_num_autocon == 1 ? "" : "s" ); |
160 | |
161 | /* First identify all devices ... */ |
162 | for (i = 0; i < zorro_num_autocon; i++) { |
163 | zi = &zorro_autocon_init[i]; |
164 | z = &zorro_autocon[i]; |
165 | |
166 | z->rom = zi->rom; |
167 | z->id = (be16_to_cpu(z->rom.er_Manufacturer) << 16) | |
168 | (z->rom.er_Product << 8); |
169 | if (z->id == ZORRO_PROD_GVP_EPC_BASE) { |
170 | /* GVP quirk */ |
171 | unsigned long magic = zi->boardaddr + 0x8000; |
172 | |
173 | z->id |= *(u16 *)ZTWO_VADDR(magic) & GVP_PRODMASK; |
174 | } |
175 | z->slotaddr = zi->slotaddr; |
176 | z->slotsize = zi->slotsize; |
177 | sprintf(buf: z->name, fmt: "Zorro device %08x" , z->id); |
178 | zorro_name_device(dev: z); |
179 | z->resource.start = zi->boardaddr; |
180 | z->resource.end = zi->boardaddr + zi->boardsize - 1; |
181 | z->resource.name = z->name; |
182 | r = zorro_find_parent_resource(bridge: pdev, z); |
183 | error = request_resource(root: r, new: &z->resource); |
184 | if (error && !(z->rom.er_Type & ERTF_MEMLIST)) |
185 | dev_err(&bus->dev, |
186 | "Address space collision on device %s %pR\n" , |
187 | z->name, &z->resource); |
188 | z->dev.parent = &bus->dev; |
189 | z->dev.bus = &zorro_bus_type; |
190 | z->dev.id = i; |
191 | switch (z->rom.er_Type & ERT_TYPEMASK) { |
192 | case ERT_ZORROIII: |
193 | z->dev.coherent_dma_mask = DMA_BIT_MASK(32); |
194 | break; |
195 | |
196 | case ERT_ZORROII: |
197 | default: |
198 | z->dev.coherent_dma_mask = DMA_BIT_MASK(24); |
199 | break; |
200 | } |
201 | z->dev.dma_mask = &z->dev.coherent_dma_mask; |
202 | } |
203 | |
204 | /* ... then register them */ |
205 | for (i = 0; i < zorro_num_autocon; i++) { |
206 | z = &zorro_autocon[i]; |
207 | error = device_register(dev: &z->dev); |
208 | if (error) { |
209 | dev_err(&bus->dev, "Error registering device %s\n" , |
210 | z->name); |
211 | put_device(dev: &z->dev); |
212 | continue; |
213 | } |
214 | } |
215 | |
216 | /* Mark all available Zorro II memory */ |
217 | zorro_for_each_dev(z) { |
218 | if (z->rom.er_Type & ERTF_MEMLIST) |
219 | mark_region(zorro_resource_start(z), |
220 | zorro_resource_end(z)+1, flag: 1); |
221 | } |
222 | |
223 | /* Unmark all used Zorro II memory */ |
224 | for (i = 0; i < m68k_num_memory; i++) |
225 | if (m68k_memory[i].addr < 16*1024*1024) |
226 | mark_region(m68k_memory[i].addr, |
227 | m68k_memory[i].addr+m68k_memory[i].size, |
228 | 0); |
229 | |
230 | return 0; |
231 | } |
232 | |
233 | static struct platform_driver amiga_zorro_driver = { |
234 | .driver = { |
235 | .name = "amiga-zorro" , |
236 | }, |
237 | }; |
238 | |
239 | static int __init amiga_zorro_init(void) |
240 | { |
241 | return platform_driver_probe(&amiga_zorro_driver, amiga_zorro_probe); |
242 | } |
243 | |
244 | module_init(amiga_zorro_init); |
245 | |
246 | MODULE_LICENSE("GPL" ); |
247 | |