]>
git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/blob - drivers/dio/dio.c
1 // SPDX-License-Identifier: GPL-2.0
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>
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.
11 * This means that framebuffers should pass it as
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)
17 * Every DIO card has a fixed interrupt priority level. This function
18 * returns it, whatever it is.
19 * const char *dio_scodetoname(int scode)
20 * Return a character string describing this board [might be "" if
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
25 * This file is based on the way the Amiga port handles Zorro II cards,
26 * although we aren't so complicated...
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() */
35 #include <linux/uaccess.h>
36 #include <asm/io.h> /* readb() */
38 struct dio_bus dio_bus
= {
41 { .name
= "DIO mem", .start
= 0x00600000, .end
= 0x007fffff },
43 { .name
= "DIO-II mem", .start
= 0x01000000, .end
= 0x1fffffff }
48 /* not a real config option yet! */
49 #define CONFIG_DIO_CONSTANTS
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
55 * using the initdata stuff. Then we wouldn't need to worry about
56 * carrying them around...
57 * I think we do this by copying them into newly kmalloc()ed memory and
58 * marking the names[] array as .initdata ?
67 #define DIONAME(x) { DIO_ID_##x, DIO_DESC_##x }
68 #define DIOFBNAME(x) { DIO_ENCODE_ID( DIO_ID_FBUFFER, DIO_ID2_##x), DIO_DESC2_##x }
70 static struct dioname names
[] =
72 DIONAME(DCA0
), DIONAME(DCA0REM
), DIONAME(DCA1
), DIONAME(DCA1REM
),
73 DIONAME(DCM
), DIONAME(DCMREM
),
75 DIONAME(FHPIB
), DIONAME(NHPIB
),
76 DIONAME(SCSI0
), DIONAME(SCSI1
), DIONAME(SCSI2
), DIONAME(SCSI3
),
78 DIONAME(PARALLEL
), DIONAME(VME
), DIONAME(DCL
), DIONAME(DCLREM
),
79 DIONAME(MISC0
), DIONAME(MISC1
), DIONAME(MISC2
), DIONAME(MISC3
),
80 DIONAME(MISC4
), DIONAME(MISC5
), DIONAME(MISC6
), DIONAME(MISC7
),
81 DIONAME(MISC8
), DIONAME(MISC9
), DIONAME(MISC10
), DIONAME(MISC11
),
82 DIONAME(MISC12
), DIONAME(MISC13
),
83 DIOFBNAME(GATORBOX
), DIOFBNAME(TOPCAT
), DIOFBNAME(RENAISSANCE
),
84 DIOFBNAME(LRCATSEYE
), DIOFBNAME(HRCCATSEYE
), DIOFBNAME(HRMCATSEYE
),
85 DIOFBNAME(DAVINCI
), DIOFBNAME(XXXCATSEYE
), DIOFBNAME(HYPERION
),
86 DIOFBNAME(XGENESIS
), DIOFBNAME(TIGER
), DIOFBNAME(YGENESIS
)
92 static const char unknowndioname
[]
93 = "unknown DIO board, please email linux-m68k@lists.linux-m68k.org";
95 static const char *dio_getname(int id
)
97 /* return pointer to a constant string describing the board with given ID */
99 for (i
= 0; i
< ARRAY_SIZE(names
); i
++)
100 if (names
[i
].id
== id
)
101 return names
[i
].name
;
103 return unknowndioname
;
108 static char dio_no_name
[] = { 0 };
109 #define dio_getname(_id) (dio_no_name)
111 #endif /* CONFIG_DIO_CONSTANTS */
113 int __init
dio_find(int deviceid
)
115 /* Called to find a DIO device before the full bus scan has run.
116 * Only used by the console driver.
119 u_char prid
, secid
, i
;
121 for (scode
= 0; scode
< DIO_SCMAX
; scode
++) {
125 if (DIO_SCINHOLE(scode
))
128 pa
= dio_scodetophysaddr(scode
);
133 if (scode
< DIOII_SCBASE
)
134 va
= (void *)(pa
+ DIO_VIRADDRBASE
);
136 va
= ioremap(pa
, PAGE_SIZE
);
138 if (copy_from_kernel_nofault(&i
,
139 (unsigned char *)va
+ DIO_IDOFF
, 1)) {
140 if (scode
>= DIOII_SCBASE
)
142 continue; /* no board present at that select code */
147 if (DIO_NEEDSSECID(prid
)) {
148 secid
= DIO_SECID(va
);
149 id
= DIO_ENCODE_ID(prid
, secid
);
153 if (id
== deviceid
) {
154 if (scode
>= DIOII_SCBASE
)
163 /* This is the function that scans the DIO space and works out what
164 * hardware is actually present.
166 static int __init
dio_init(void)
176 printk(KERN_INFO
"Scanning for DIO devices...\n");
178 /* Initialize the DIO bus */
179 INIT_LIST_HEAD(&dio_bus
.devices
);
180 dev_set_name(&dio_bus
.dev
, "dio");
181 error
= device_register(&dio_bus
.dev
);
183 pr_err("DIO: Error registering dio_bus\n");
187 /* Request all resources */
188 dio_bus
.num_resources
= (hp300_model
== HP_320
? 1 : 2);
189 for (i
= 0; i
< dio_bus
.num_resources
; i
++)
190 request_resource(&iomem_resource
, &dio_bus
.resources
[i
]);
192 /* Register all devices */
193 for (scode
= 0; scode
< DIO_SCMAX
; ++scode
)
195 u_char prid
, secid
= 0; /* primary, secondary ID bytes */
199 if (DIO_SCINHOLE(scode
))
202 pa
= dio_scodetophysaddr(scode
);
207 if (scode
< DIOII_SCBASE
)
208 va
= (void *)(pa
+ DIO_VIRADDRBASE
);
210 va
= ioremap(pa
, PAGE_SIZE
);
212 if (copy_from_kernel_nofault(&i
,
213 (unsigned char *)va
+ DIO_IDOFF
, 1)) {
214 if (scode
>= DIOII_SCBASE
)
216 continue; /* no board present at that select code */
219 /* Found a board, allocate it an entry in the list */
220 dev
= kzalloc(sizeof(struct dio_dev
), GFP_KERNEL
);
225 dev
->dev
.parent
= &dio_bus
.dev
;
226 dev
->dev
.bus
= &dio_bus_type
;
228 dev
->resource
.start
= pa
;
229 dev
->resource
.end
= pa
+ DIO_SIZE(scode
, va
);
230 dev_set_name(&dev
->dev
, "%02x", scode
);
232 /* read the ID byte(s) and encode if necessary. */
235 if (DIO_NEEDSSECID(prid
)) {
236 secid
= DIO_SECID(va
);
237 dev
->id
= DIO_ENCODE_ID(prid
, secid
);
241 dev
->ipl
= DIO_IPL(va
);
242 strcpy(dev
->name
,dio_getname(dev
->id
));
243 printk(KERN_INFO
"select code %3d: ipl %d: ID %02X", dev
->scode
, dev
->ipl
, prid
);
244 if (DIO_NEEDSSECID(prid
))
245 printk(":%02X", secid
);
246 printk(": %s\n", dev
->name
);
248 if (scode
>= DIOII_SCBASE
)
250 error
= device_register(&dev
->dev
);
252 pr_err("DIO: Error registering device %s\n",
256 error
= dio_create_sysfs_dev_files(dev
);
258 dev_err(&dev
->dev
, "Error creating sysfs files\n");
263 subsys_initcall(dio_init
);
265 /* Bear in mind that this is called in the very early stages of initialisation
266 * in order to get the address of the serial port for the console...
268 unsigned long dio_scodetophysaddr(int scode
)
270 if (scode
>= DIOII_SCBASE
) {
271 return (DIOII_BASE
+ (scode
- 132) * DIOII_DEVSIZE
);
272 } else if (scode
> DIO_SCMAX
|| scode
< 0)
274 else if (DIO_SCINHOLE(scode
))
277 return (DIO_BASE
+ scode
* DIO_DEVSIZE
);