drivers: dio: add missing iounmap() in dio_init()
[linux-block.git] / drivers / dio / dio.c
CommitLineData
b2441318 1// SPDX-License-Identifier: GPL-2.0
1da177e4
LT
2/* Code to support devices on the DIO and DIO-II bus
3 * Copyright (C) 05/1998 Peter Maydell <pmaydell@chiark.greenend.org.uk>
4 * Copyright (C) 2004 Jochen Friedrich <jochen@scram.de>
7649cb6f 5 *
1da177e4
LT
6 * This code has basically these routines at the moment:
7 * int dio_find(u_int deviceid)
8 * Search the list of DIO devices and return the select code
9 * of the next unconfigured device found that matches the given device ID.
10 * Note that the deviceid parameter should be the encoded ID.
7649cb6f 11 * This means that framebuffers should pass it as
1da177e4
LT
12 * DIO_ENCODE_ID(DIO_ID_FBUFFER,DIO_ID2_TOPCAT)
13 * (or whatever); everybody else just uses DIO_ID_FOOBAR.
14 * unsigned long dio_scodetophysaddr(int scode)
15 * Return the physical address corresponding to the given select code.
16 * int dio_scodetoipl(int scode)
7649cb6f 17 * Every DIO card has a fixed interrupt priority level. This function
1da177e4
LT
18 * returns it, whatever it is.
19 * const char *dio_scodetoname(int scode)
7649cb6f 20 * Return a character string describing this board [might be "" if
1da177e4
LT
21 * not CONFIG_DIO_CONSTANTS]
22 * void dio_config_board(int scode) mark board as configured in the list
23 * void dio_unconfig_board(int scode) mark board as no longer configured
24 *
7649cb6f 25 * This file is based on the way the Amiga port handles Zorro II cards,
1da177e4
LT
26 * although we aren't so complicated...
27 */
28#include <linux/module.h>
29#include <linux/string.h>
30#include <linux/types.h>
31#include <linux/kernel.h>
32#include <linux/init.h>
33#include <linux/dio.h>
34#include <linux/slab.h> /* kmalloc() */
7c0f6ba6 35#include <linux/uaccess.h>
10f4629f 36#include <linux/io.h> /* readb() */
1da177e4
LT
37
38struct dio_bus dio_bus = {
39 .resources = {
40 /* DIO range */
41 { .name = "DIO mem", .start = 0x00600000, .end = 0x007fffff },
42 /* DIO-II range */
43 { .name = "DIO-II mem", .start = 0x01000000, .end = 0x1fffffff }
44 },
45 .name = "DIO bus"
46};
47
48/* not a real config option yet! */
49#define CONFIG_DIO_CONSTANTS
50
51#ifdef CONFIG_DIO_CONSTANTS
52/* We associate each numeric ID with an appropriate descriptive string
53 * using a constant array of these structs.
54 * FIXME: we should be able to arrange to throw away most of the strings
7649cb6f 55 * using the initdata stuff. Then we wouldn't need to worry about
1da177e4 56 * carrying them around...
7649cb6f 57 * I think we do this by copying them into newly kmalloc()ed memory and
1da177e4
LT
58 * marking the names[] array as .initdata ?
59 */
8a4606c6 60struct dioname {
dffae938
AV
61 int id;
62 const char *name;
1da177e4
LT
63};
64
65/* useful macro */
66#define DIONAME(x) { DIO_ID_##x, DIO_DESC_##x }
c3c61385 67#define DIOFBNAME(x) { DIO_ENCODE_ID(DIO_ID_FBUFFER, DIO_ID2_##x), DIO_DESC2_##x }
1da177e4 68
8a4606c6 69static struct dioname names[] = {
dffae938
AV
70 DIONAME(DCA0), DIONAME(DCA0REM), DIONAME(DCA1), DIONAME(DCA1REM),
71 DIONAME(DCM), DIONAME(DCMREM),
72 DIONAME(LAN),
73 DIONAME(FHPIB), DIONAME(NHPIB),
74 DIONAME(SCSI0), DIONAME(SCSI1), DIONAME(SCSI2), DIONAME(SCSI3),
75 DIONAME(FBUFFER),
76 DIONAME(PARALLEL), DIONAME(VME), DIONAME(DCL), DIONAME(DCLREM),
77 DIONAME(MISC0), DIONAME(MISC1), DIONAME(MISC2), DIONAME(MISC3),
78 DIONAME(MISC4), DIONAME(MISC5), DIONAME(MISC6), DIONAME(MISC7),
7649cb6f 79 DIONAME(MISC8), DIONAME(MISC9), DIONAME(MISC10), DIONAME(MISC11),
dffae938
AV
80 DIONAME(MISC12), DIONAME(MISC13),
81 DIOFBNAME(GATORBOX), DIOFBNAME(TOPCAT), DIOFBNAME(RENAISSANCE),
82 DIOFBNAME(LRCATSEYE), DIOFBNAME(HRCCATSEYE), DIOFBNAME(HRMCATSEYE),
83 DIOFBNAME(DAVINCI), DIOFBNAME(XXXCATSEYE), DIOFBNAME(HYPERION),
7649cb6f 84 DIOFBNAME(XGENESIS), DIOFBNAME(TIGER), DIOFBNAME(YGENESIS)
1da177e4
LT
85};
86
87#undef DIONAME
88#undef DIOFBNAME
89
627f192d
GU
90static const char unknowndioname[]
91 = "unknown DIO board, please email linux-m68k@lists.linux-m68k.org";
1da177e4
LT
92
93static const char *dio_getname(int id)
94{
dffae938 95 /* return pointer to a constant string describing the board with given ID */
1da177e4 96 unsigned int i;
aafce7bc 97
0a8320b0 98 for (i = 0; i < ARRAY_SIZE(names); i++)
7649cb6f 99 if (names[i].id == id)
dffae938 100 return names[i].name;
1da177e4 101
dffae938 102 return unknowndioname;
1da177e4
LT
103}
104
105#else
106
107static char dio_no_name[] = { 0 };
108#define dio_getname(_id) (dio_no_name)
109
110#endif /* CONFIG_DIO_CONSTANTS */
111
112int __init dio_find(int deviceid)
113{
114 /* Called to find a DIO device before the full bus scan has run.
115 * Only used by the console driver.
116 */
117 int scode, id;
118 u_char prid, secid, i;
1da177e4
LT
119
120 for (scode = 0; scode < DIO_SCMAX; scode++) {
121 void *va;
122 unsigned long pa;
123
dffae938
AV
124 if (DIO_SCINHOLE(scode))
125 continue;
1da177e4 126
dffae938 127 pa = dio_scodetophysaddr(scode);
1da177e4
LT
128
129 if (!pa)
130 continue;
131
132 if (scode < DIOII_SCBASE)
133 va = (void *)(pa + DIO_VIRADDRBASE);
134 else
135 va = ioremap(pa, PAGE_SIZE);
136
fe557319
CH
137 if (copy_from_kernel_nofault(&i,
138 (unsigned char *)va + DIO_IDOFF, 1)) {
1da177e4
LT
139 if (scode >= DIOII_SCBASE)
140 iounmap(va);
dffae938 141 continue; /* no board present at that select code */
1da177e4
LT
142 }
143
1da177e4
LT
144 prid = DIO_ID(va);
145
dffae938
AV
146 if (DIO_NEEDSSECID(prid)) {
147 secid = DIO_SECID(va);
148 id = DIO_ENCODE_ID(prid, secid);
149 } else
1da177e4
LT
150 id = prid;
151
152 if (id == deviceid) {
153 if (scode >= DIOII_SCBASE)
154 iounmap(va);
155 return scode;
156 }
157 }
158
159 return -1;
160}
161
162/* This is the function that scans the DIO space and works out what
163 * hardware is actually present.
164 */
165static int __init dio_init(void)
166{
167 int scode;
1da177e4
LT
168 int i;
169 struct dio_dev *dev;
2e4c77be 170 int error;
1da177e4
LT
171
172 if (!MACH_IS_HP300)
173 return 0;
174
175 printk(KERN_INFO "Scanning for DIO devices...\n");
176
7649cb6f 177 /* Initialize the DIO bus */
1da177e4 178 INIT_LIST_HEAD(&dio_bus.devices);
9591463a 179 dev_set_name(&dio_bus.dev, "dio");
2e4c77be
GU
180 error = device_register(&dio_bus.dev);
181 if (error) {
182 pr_err("DIO: Error registering dio_bus\n");
183 return error;
184 }
1da177e4
LT
185
186 /* Request all resources */
187 dio_bus.num_resources = (hp300_model == HP_320 ? 1 : 2);
188 for (i = 0; i < dio_bus.num_resources; i++)
189 request_resource(&iomem_resource, &dio_bus.resources[i]);
190
191 /* Register all devices */
8a4606c6 192 for (scode = 0; scode < DIO_SCMAX; ++scode) {
dffae938
AV
193 u_char prid, secid = 0; /* primary, secondary ID bytes */
194 u_char *va;
1da177e4 195 unsigned long pa;
7649cb6f 196
dffae938
AV
197 if (DIO_SCINHOLE(scode))
198 continue;
1da177e4
LT
199
200 pa = dio_scodetophysaddr(scode);
201
202 if (!pa)
203 continue;
204
205 if (scode < DIOII_SCBASE)
206 va = (void *)(pa + DIO_VIRADDRBASE);
207 else
208 va = ioremap(pa, PAGE_SIZE);
209
fe557319
CH
210 if (copy_from_kernel_nofault(&i,
211 (unsigned char *)va + DIO_IDOFF, 1)) {
1da177e4
LT
212 if (scode >= DIOII_SCBASE)
213 iounmap(va);
dffae938 214 continue; /* no board present at that select code */
1da177e4
LT
215 }
216
dffae938 217 /* Found a board, allocate it an entry in the list */
e66860cb 218 dev = kzalloc(sizeof(struct dio_dev), GFP_KERNEL);
077f5d90
YY
219 if (!dev) {
220 if (scode >= DIOII_SCBASE)
221 iounmap(va);
d1d26f40 222 return -ENOMEM;
077f5d90 223 }
1da177e4 224
1da177e4
LT
225 dev->bus = &dio_bus;
226 dev->dev.parent = &dio_bus.dev;
227 dev->dev.bus = &dio_bus_type;
228 dev->scode = scode;
229 dev->resource.start = pa;
230 dev->resource.end = pa + DIO_SIZE(scode, va);
9591463a 231 dev_set_name(&dev->dev, "%02x", scode);
1da177e4 232
dffae938 233 /* read the ID byte(s) and encode if necessary. */
1da177e4
LT
234 prid = DIO_ID(va);
235
dffae938
AV
236 if (DIO_NEEDSSECID(prid)) {
237 secid = DIO_SECID(va);
238 dev->id = DIO_ENCODE_ID(prid, secid);
239 } else
240 dev->id = prid;
1da177e4 241
dffae938 242 dev->ipl = DIO_IPL(va);
f8b187c2 243 strcpy(dev->name, dio_getname(dev->id));
1da177e4 244 printk(KERN_INFO "select code %3d: ipl %d: ID %02X", dev->scode, dev->ipl, prid);
dffae938 245 if (DIO_NEEDSSECID(prid))
1da177e4
LT
246 printk(":%02X", secid);
247 printk(": %s\n", dev->name);
248
249 if (scode >= DIOII_SCBASE)
250 iounmap(va);
2e4c77be
GU
251 error = device_register(&dev->dev);
252 if (error) {
253 pr_err("DIO: Error registering device %s\n",
254 dev->name);
255 continue;
256 }
257 error = dio_create_sysfs_dev_files(dev);
258 if (error)
259 dev_err(&dev->dev, "Error creating sysfs files\n");
dffae938 260 }
1da177e4
LT
261 return 0;
262}
263
264subsys_initcall(dio_init);
265
266/* Bear in mind that this is called in the very early stages of initialisation
267 * in order to get the address of the serial port for the console...
268 */
269unsigned long dio_scodetophysaddr(int scode)
270{
8a4606c6 271 if (scode >= DIOII_SCBASE)
dffae938 272 return (DIOII_BASE + (scode - 132) * DIOII_DEVSIZE);
8a4606c6 273 else if (scode > DIO_SCMAX || scode < 0)
dffae938
AV
274 return 0;
275 else if (DIO_SCINHOLE(scode))
276 return 0;
1da177e4 277
dffae938 278 return (DIO_BASE + scode * DIO_DEVSIZE);
1da177e4 279}