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