^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) * Driver for the ADB controller in the Mac I/O (Hydra) chip.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) #include <stdarg.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/spinlock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/pgtable.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <asm/prom.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/adb.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <asm/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <asm/hydra.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <asm/irq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/ioport.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) struct preg {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) unsigned char r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) char pad[15];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) struct adb_regs {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) struct preg intr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) struct preg data[9];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) struct preg intr_enb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) struct preg dcount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) struct preg error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) struct preg ctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) struct preg autopoll;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) struct preg active_hi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) struct preg active_lo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) struct preg test;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) /* Bits in intr and intr_enb registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #define DFB 1 /* data from bus */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #define TAG 2 /* transfer access grant */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) /* Bits in dcount register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #define HMB 0x0f /* how many bytes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #define APD 0x10 /* auto-poll data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) /* Bits in error register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #define NRE 1 /* no response error */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #define DLE 2 /* data lost error */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) /* Bits in ctrl register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #define TAR 1 /* transfer access request */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #define DTB 2 /* data to bus */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) #define CRE 4 /* command response expected */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) #define ADB_RST 8 /* ADB reset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) /* Bits in autopoll register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) #define APE 1 /* autopoll enable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) static volatile struct adb_regs __iomem *adb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) static struct adb_request *current_req, *last_req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) static DEFINE_SPINLOCK(macio_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) static int macio_probe(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) static int macio_init(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) static irqreturn_t macio_adb_interrupt(int irq, void *arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) static int macio_send_request(struct adb_request *req, int sync);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) static int macio_adb_autopoll(int devs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) static void macio_adb_poll(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) static int macio_adb_reset_bus(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) struct adb_driver macio_adb_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) .name = "MACIO",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) .probe = macio_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) .init = macio_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) .send_request = macio_send_request,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) .autopoll = macio_adb_autopoll,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) .poll = macio_adb_poll,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) .reset_bus = macio_adb_reset_bus,
^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) int macio_probe(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) struct device_node *np;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) np = of_find_compatible_node(NULL, "adb", "chrp,adb0");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) if (np) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) of_node_put(np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) return -ENODEV;
^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) int macio_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) struct device_node *adbs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) struct resource r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) unsigned int irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) adbs = of_find_compatible_node(NULL, "adb", "chrp,adb0");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) if (adbs == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) return -ENXIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) if (of_address_to_resource(adbs, 0, &r)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) of_node_put(adbs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) return -ENXIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) adb = ioremap(r.start, sizeof(struct adb_regs));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) out_8(&adb->ctrl.r, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) out_8(&adb->intr.r, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) out_8(&adb->error.r, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) out_8(&adb->active_hi.r, 0xff); /* for now, set all devices active */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) out_8(&adb->active_lo.r, 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) out_8(&adb->autopoll.r, APE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) irq = irq_of_parse_and_map(adbs, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) of_node_put(adbs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) if (request_irq(irq, macio_adb_interrupt, 0, "ADB", (void *)0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) printk(KERN_ERR "ADB: can't get irq %d\n", irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) return -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) out_8(&adb->intr_enb.r, DFB | TAG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) printk("adb: mac-io driver 1.0 for unified ADB\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) return 0;
^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) static int macio_adb_autopoll(int devs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) spin_lock_irqsave(&macio_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) out_8(&adb->active_hi.r, devs >> 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) out_8(&adb->active_lo.r, devs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) out_8(&adb->autopoll.r, devs? APE: 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) spin_unlock_irqrestore(&macio_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) static int macio_adb_reset_bus(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) int timeout = 1000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) /* Hrm... we may want to not lock interrupts for so
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) * long ... oh well, who uses that chip anyway ? :)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) * That function will be seldom used during boot
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) * on rare machines, so...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) spin_lock_irqsave(&macio_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) out_8(&adb->ctrl.r, in_8(&adb->ctrl.r) | ADB_RST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) while ((in_8(&adb->ctrl.r) & ADB_RST) != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) if (--timeout == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) out_8(&adb->ctrl.r, in_8(&adb->ctrl.r) & ~ADB_RST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) spin_unlock_irqrestore(&macio_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) spin_unlock_irqrestore(&macio_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) /* Send an ADB command */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) static int macio_send_request(struct adb_request *req, int sync)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) if (req->data[0] != ADB_PACKET)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) for (i = 0; i < req->nbytes - 1; ++i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) req->data[i] = req->data[i+1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) --req->nbytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) req->next = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) req->sent = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) req->complete = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) req->reply_len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) spin_lock_irqsave(&macio_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) if (current_req != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) last_req->next = req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) last_req = req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) current_req = last_req = req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) out_8(&adb->ctrl.r, in_8(&adb->ctrl.r) | TAR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) spin_unlock_irqrestore(&macio_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) if (sync) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) while (!req->complete)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) macio_adb_poll();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) static irqreturn_t macio_adb_interrupt(int irq, void *arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) int i, n, err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) struct adb_request *req = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) unsigned char ibuf[16];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) int ibuf_len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) int complete = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) int autopoll = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) int handled = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) spin_lock(&macio_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) if (in_8(&adb->intr.r) & TAG) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) handled = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) if ((req = current_req) != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) /* put the current request in */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) for (i = 0; i < req->nbytes; ++i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) out_8(&adb->data[i].r, req->data[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) out_8(&adb->dcount.r, req->nbytes & HMB);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) req->sent = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) if (req->reply_expected) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) out_8(&adb->ctrl.r, DTB + CRE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) out_8(&adb->ctrl.r, DTB);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) current_req = req->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) complete = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) if (current_req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) out_8(&adb->ctrl.r, in_8(&adb->ctrl.r) | TAR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) out_8(&adb->intr.r, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) if (in_8(&adb->intr.r) & DFB) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) handled = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) err = in_8(&adb->error.r);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) if (current_req && current_req->sent) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) /* this is the response to a command */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) req = current_req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) if (err == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) req->reply_len = in_8(&adb->dcount.r) & HMB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) for (i = 0; i < req->reply_len; ++i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) req->reply[i] = in_8(&adb->data[i].r);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) current_req = req->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) complete = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) if (current_req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) out_8(&adb->ctrl.r, in_8(&adb->ctrl.r) | TAR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) } else if (err == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) /* autopoll data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) n = in_8(&adb->dcount.r) & HMB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) for (i = 0; i < n; ++i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) ibuf[i] = in_8(&adb->data[i].r);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) ibuf_len = n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) autopoll = (in_8(&adb->dcount.r) & APD) != 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) out_8(&adb->error.r, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) out_8(&adb->intr.r, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) spin_unlock(&macio_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) if (complete && req) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) void (*done)(struct adb_request *) = req->done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) mb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) req->complete = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) /* Here, we assume that if the request has a done member, the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) * struct request will survive to setting req->complete to 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) if (done)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) (*done)(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) if (ibuf_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) adb_input(ibuf, ibuf_len, autopoll);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) return IRQ_RETVAL(handled);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) static void macio_adb_poll(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) local_irq_save(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) if (in_8(&adb->intr.r) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) macio_adb_interrupt(0, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) local_irq_restore(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) }