if (of_address_to_resource(adbs, 0, &r)) return -ENXIO;
adb = ioremap(r.start, sizeof(struct adb_regs)); if (!adb) return -ENOMEM;
out_8(&adb->ctrl.r, 0);
out_8(&adb->intr.r, 0);
out_8(&adb->error.r, 0);
out_8(&adb->active_hi.r, 0xff); /* for now, set all devices active */
out_8(&adb->active_lo.r, 0xff);
out_8(&adb->autopoll.r, APE);
staticint macio_adb_reset_bus(void)
{ unsignedlong flags; int timeout = 1000000;
/* Hrm... we may want to not lock interrupts for so * long ... oh well, who uses that chip anyway ? :) * That function will be seldom used during boot * on rare machines, so...
*/
spin_lock_irqsave(&macio_lock, flags);
out_8(&adb->ctrl.r, in_8(&adb->ctrl.r) | ADB_RST); while ((in_8(&adb->ctrl.r) & ADB_RST) != 0) { if (--timeout == 0) {
out_8(&adb->ctrl.r, in_8(&adb->ctrl.r) & ~ADB_RST);
spin_unlock_irqrestore(&macio_lock, flags); return -1;
}
}
spin_unlock_irqrestore(&macio_lock, flags); return 0;
}
/* Send an ADB command */ staticint macio_send_request(struct adb_request *req, int sync)
{ unsignedlong flags; int i;
if (req->data[0] != ADB_PACKET) return -EINVAL;
for (i = 0; i < req->nbytes - 1; ++i)
req->data[i] = req->data[i+1];
--req->nbytes;
if (sync) { while (!req->complete)
macio_adb_poll();
}
return 0;
}
static irqreturn_t macio_adb_interrupt(int irq, void *arg)
{ int i, n, err; struct adb_request *req = NULL; unsignedchar ibuf[16]; int ibuf_len = 0; int complete = 0; int autopoll = 0; int handled = 0;
spin_lock(&macio_lock); if (in_8(&adb->intr.r) & TAG) {
handled = 1;
req = current_req; if (req) { /* put the current request in */ for (i = 0; i < req->nbytes; ++i)
out_8(&adb->data[i].r, req->data[i]);
out_8(&adb->dcount.r, req->nbytes & HMB);
req->sent = 1; if (req->reply_expected) {
out_8(&adb->ctrl.r, DTB + CRE);
} else {
out_8(&adb->ctrl.r, DTB);
current_req = req->next;
complete = 1; if (current_req)
out_8(&adb->ctrl.r, in_8(&adb->ctrl.r) | TAR);
}
}
out_8(&adb->intr.r, 0);
}
if (in_8(&adb->intr.r) & DFB) {
handled = 1;
err = in_8(&adb->error.r); if (current_req && current_req->sent) { /* this is the response to a command */
req = current_req; if (err == 0) {
req->reply_len = in_8(&adb->dcount.r) & HMB; for (i = 0; i < req->reply_len; ++i)
req->reply[i] = in_8(&adb->data[i].r);
}
current_req = req->next;
complete = 1; if (current_req)
out_8(&adb->ctrl.r, in_8(&adb->ctrl.r) | TAR);
} elseif (err == 0) { /* autopoll data */
n = in_8(&adb->dcount.r) & HMB; for (i = 0; i < n; ++i)
ibuf[i] = in_8(&adb->data[i].r);
ibuf_len = n;
autopoll = (in_8(&adb->dcount.r) & APD) != 0;
}
out_8(&adb->error.r, 0);
out_8(&adb->intr.r, 0);
}
spin_unlock(&macio_lock); if (complete && req) { void (*done)(struct adb_request *) = req->done;
mb();
req->complete = 1; /* Here, we assume that if the request has a done member, the * struct request will survive to setting req->complete to 1
*/ if (done)
(*done)(req);
} if (ibuf_len)
adb_input(ibuf, ibuf_len, autopoll);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.