perf tools: Update powerpc's syscall.tbl copy from the kernel sources
[linux-2.6-microblaze.git] / drivers / macintosh / adb-iop.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * I/O Processor (IOP) ADB Driver
4  * Written and (C) 1999 by Joshua M. Thompson (funaho@jurai.org)
5  * Based on via-cuda.c by Paul Mackerras.
6  *
7  * 1999-07-01 (jmt) - First implementation for new driver architecture.
8  *
9  * 1999-07-31 (jmt) - First working version.
10  */
11
12 #include <linux/types.h>
13 #include <linux/kernel.h>
14 #include <linux/mm.h>
15 #include <linux/delay.h>
16 #include <linux/init.h>
17
18 #include <asm/macintosh.h>
19 #include <asm/macints.h>
20 #include <asm/mac_iop.h>
21 #include <asm/adb_iop.h>
22
23 #include <linux/adb.h>
24
25 static struct adb_request *current_req;
26 static struct adb_request *last_req;
27 static unsigned int autopoll_devs;
28 static u8 autopoll_addr;
29
30 static enum adb_iop_state {
31         idle,
32         sending,
33         awaiting_reply
34 } adb_iop_state;
35
36 static void adb_iop_start(void);
37 static int adb_iop_probe(void);
38 static int adb_iop_init(void);
39 static int adb_iop_send_request(struct adb_request *, int);
40 static int adb_iop_write(struct adb_request *);
41 static int adb_iop_autopoll(int);
42 static void adb_iop_poll(void);
43 static int adb_iop_reset_bus(void);
44
45 /* ADB command byte structure */
46 #define ADDR_MASK       0xF0
47 #define OP_MASK         0x0C
48 #define TALK            0x0C
49
50 struct adb_driver adb_iop_driver = {
51         .name         = "ISM IOP",
52         .probe        = adb_iop_probe,
53         .init         = adb_iop_init,
54         .send_request = adb_iop_send_request,
55         .autopoll     = adb_iop_autopoll,
56         .poll         = adb_iop_poll,
57         .reset_bus    = adb_iop_reset_bus
58 };
59
60 static void adb_iop_done(void)
61 {
62         struct adb_request *req = current_req;
63
64         adb_iop_state = idle;
65
66         req->complete = 1;
67         current_req = req->next;
68         if (req->done)
69                 (*req->done)(req);
70
71         if (adb_iop_state == idle)
72                 adb_iop_start();
73 }
74
75 /*
76  * Completion routine for ADB commands sent to the IOP.
77  *
78  * This will be called when a packet has been successfully sent.
79  */
80
81 static void adb_iop_complete(struct iop_msg *msg)
82 {
83         unsigned long flags;
84
85         local_irq_save(flags);
86
87         adb_iop_state = awaiting_reply;
88
89         local_irq_restore(flags);
90 }
91
92 /*
93  * Listen for ADB messages from the IOP.
94  *
95  * This will be called when unsolicited IOP messages are received.
96  * These IOP messages can carry ADB autopoll responses and also occur
97  * after explicit ADB commands.
98  */
99
100 static void adb_iop_listen(struct iop_msg *msg)
101 {
102         struct adb_iopmsg *amsg = (struct adb_iopmsg *)msg->message;
103         u8 addr = (amsg->cmd & ADDR_MASK) >> 4;
104         u8 op = amsg->cmd & OP_MASK;
105         unsigned long flags;
106         bool req_done = false;
107
108         local_irq_save(flags);
109
110         /* Responses to Talk commands may be unsolicited as they are
111          * produced when the IOP polls devices. They are mostly timeouts.
112          */
113         if (op == TALK && ((1 << addr) & autopoll_devs))
114                 autopoll_addr = addr;
115
116         switch (amsg->flags & (ADB_IOP_EXPLICIT |
117                                ADB_IOP_AUTOPOLL |
118                                ADB_IOP_TIMEOUT)) {
119         case ADB_IOP_EXPLICIT:
120         case ADB_IOP_EXPLICIT | ADB_IOP_TIMEOUT:
121                 if (adb_iop_state == awaiting_reply) {
122                         struct adb_request *req = current_req;
123
124                         if (req->reply_expected) {
125                                 req->reply_len = amsg->count + 1;
126                                 memcpy(req->reply, &amsg->cmd, req->reply_len);
127                         }
128
129                         req_done = true;
130                 }
131                 break;
132         case ADB_IOP_AUTOPOLL:
133                 if (((1 << addr) & autopoll_devs) &&
134                     amsg->cmd == ADB_READREG(addr, 0))
135                         adb_input(&amsg->cmd, amsg->count + 1, 1);
136                 break;
137         }
138         msg->reply[0] = autopoll_addr ? ADB_IOP_AUTOPOLL : 0;
139         msg->reply[1] = 0;
140         msg->reply[2] = autopoll_addr ? ADB_READREG(autopoll_addr, 0) : 0;
141         iop_complete_message(msg);
142
143         if (req_done)
144                 adb_iop_done();
145
146         local_irq_restore(flags);
147 }
148
149 /*
150  * Start sending an ADB packet, IOP style
151  *
152  * There isn't much to do other than hand the packet over to the IOP
153  * after encapsulating it in an adb_iopmsg.
154  */
155
156 static void adb_iop_start(void)
157 {
158         struct adb_request *req;
159         struct adb_iopmsg amsg;
160
161         /* get the packet to send */
162         req = current_req;
163         if (!req)
164                 return;
165
166         /* The IOP takes MacII-style packets, so strip the initial
167          * ADB_PACKET byte.
168          */
169         amsg.flags = ADB_IOP_EXPLICIT;
170         amsg.count = req->nbytes - 2;
171
172         /* amsg.data immediately follows amsg.cmd, effectively making
173          * &amsg.cmd a pointer to the beginning of a full ADB packet.
174          */
175         memcpy(&amsg.cmd, req->data + 1, req->nbytes - 1);
176
177         req->sent = 1;
178         adb_iop_state = sending;
179
180         /* Now send it. The IOP manager will call adb_iop_complete
181          * when the message has been sent.
182          */
183         iop_send_message(ADB_IOP, ADB_CHAN, req, sizeof(amsg), (__u8 *)&amsg,
184                          adb_iop_complete);
185 }
186
187 static int adb_iop_probe(void)
188 {
189         if (!iop_ism_present)
190                 return -ENODEV;
191         return 0;
192 }
193
194 static int adb_iop_init(void)
195 {
196         pr_info("adb: IOP ISM driver v0.4 for Unified ADB\n");
197         iop_listen(ADB_IOP, ADB_CHAN, adb_iop_listen, "ADB");
198         return 0;
199 }
200
201 static int adb_iop_send_request(struct adb_request *req, int sync)
202 {
203         int err;
204
205         err = adb_iop_write(req);
206         if (err)
207                 return err;
208
209         if (sync) {
210                 while (!req->complete)
211                         adb_iop_poll();
212         }
213         return 0;
214 }
215
216 static int adb_iop_write(struct adb_request *req)
217 {
218         unsigned long flags;
219
220         if ((req->nbytes < 2) || (req->data[0] != ADB_PACKET)) {
221                 req->complete = 1;
222                 return -EINVAL;
223         }
224
225         req->next = NULL;
226         req->sent = 0;
227         req->complete = 0;
228         req->reply_len = 0;
229
230         local_irq_save(flags);
231
232         if (current_req) {
233                 last_req->next = req;
234                 last_req = req;
235         } else {
236                 current_req = req;
237                 last_req = req;
238         }
239
240         if (adb_iop_state == idle)
241                 adb_iop_start();
242
243         local_irq_restore(flags);
244
245         return 0;
246 }
247
248 static void adb_iop_set_ap_complete(struct iop_msg *msg)
249 {
250         struct adb_iopmsg *amsg = (struct adb_iopmsg *)msg->message;
251
252         autopoll_devs = (amsg->data[1] << 8) | amsg->data[0];
253         if (autopoll_devs & (1 << autopoll_addr))
254                 return;
255         autopoll_addr = autopoll_devs ? (ffs(autopoll_devs) - 1) : 0;
256 }
257
258 static int adb_iop_autopoll(int devs)
259 {
260         struct adb_iopmsg amsg;
261         unsigned long flags;
262         unsigned int mask = (unsigned int)devs & 0xFFFE;
263
264         local_irq_save(flags);
265
266         amsg.flags = ADB_IOP_SET_AUTOPOLL | (mask ? ADB_IOP_AUTOPOLL : 0);
267         amsg.count = 2;
268         amsg.cmd = 0;
269         amsg.data[0] = mask & 0xFF;
270         amsg.data[1] = (mask >> 8) & 0xFF;
271
272         iop_send_message(ADB_IOP, ADB_CHAN, NULL, sizeof(amsg), (__u8 *)&amsg,
273                          adb_iop_set_ap_complete);
274
275         local_irq_restore(flags);
276
277         return 0;
278 }
279
280 static void adb_iop_poll(void)
281 {
282         iop_ism_irq_poll(ADB_IOP);
283 }
284
285 static int adb_iop_reset_bus(void)
286 {
287         struct adb_request req;
288
289         /* Command = 0, Address = ignored */
290         adb_request(&req, NULL, ADBREQ_NOSEND, 1, ADB_BUSRESET);
291         adb_iop_send_request(&req, 1);
292
293         /* Don't want any more requests during the Global Reset low time. */
294         mdelay(3);
295
296         return 0;
297 }