linux/drivers/macintosh/via-cuda.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * Device driver for the Cuda and Egret system controllers found on PowerMacs
   4 * and 68k Macs.
   5 *
   6 * The Cuda or Egret is a 6805 microcontroller interfaced to the 6522 VIA.
   7 * This MCU controls system power, Parameter RAM, Real Time Clock and the
   8 * Apple Desktop Bus (ADB) that connects to the keyboard and mouse.
   9 *
  10 * Copyright (C) 1996 Paul Mackerras.
  11 */
  12#include <linux/stdarg.h>
  13#include <linux/types.h>
  14#include <linux/errno.h>
  15#include <linux/kernel.h>
  16#include <linux/delay.h>
  17#include <linux/adb.h>
  18#include <linux/cuda.h>
  19#include <linux/spinlock.h>
  20#include <linux/interrupt.h>
  21#ifdef CONFIG_PPC
  22#include <asm/prom.h>
  23#include <asm/machdep.h>
  24#include <asm/pmac_feature.h>
  25#else
  26#include <asm/macintosh.h>
  27#include <asm/macints.h>
  28#include <asm/mac_via.h>
  29#endif
  30#include <asm/io.h>
  31#include <linux/init.h>
  32
  33static volatile unsigned char __iomem *via;
  34static DEFINE_SPINLOCK(cuda_lock);
  35
  36/* VIA registers - spaced 0x200 bytes apart */
  37#define RS              0x200           /* skip between registers */
  38#define B               0               /* B-side data */
  39#define A               RS              /* A-side data */
  40#define DIRB            (2*RS)          /* B-side direction (1=output) */
  41#define DIRA            (3*RS)          /* A-side direction (1=output) */
  42#define T1CL            (4*RS)          /* Timer 1 ctr/latch (low 8 bits) */
  43#define T1CH            (5*RS)          /* Timer 1 counter (high 8 bits) */
  44#define T1LL            (6*RS)          /* Timer 1 latch (low 8 bits) */
  45#define T1LH            (7*RS)          /* Timer 1 latch (high 8 bits) */
  46#define T2CL            (8*RS)          /* Timer 2 ctr/latch (low 8 bits) */
  47#define T2CH            (9*RS)          /* Timer 2 counter (high 8 bits) */
  48#define SR              (10*RS)         /* Shift register */
  49#define ACR             (11*RS)         /* Auxiliary control register */
  50#define PCR             (12*RS)         /* Peripheral control register */
  51#define IFR             (13*RS)         /* Interrupt flag register */
  52#define IER             (14*RS)         /* Interrupt enable register */
  53#define ANH             (15*RS)         /* A-side data, no handshake */
  54
  55/*
  56 * When the Cuda design replaced the Egret, some signal names and
  57 * logic sense changed. They all serve the same purposes, however.
  58 *
  59 *   VIA pin       |  Egret pin
  60 * ----------------+------------------------------------------
  61 *   PB3 (input)   |  Transceiver session   (active low)
  62 *   PB4 (output)  |  VIA full              (active high)
  63 *   PB5 (output)  |  System session        (active high)
  64 *
  65 *   VIA pin       |  Cuda pin
  66 * ----------------+------------------------------------------
  67 *   PB3 (input)   |  Transfer request      (active low)
  68 *   PB4 (output)  |  Byte acknowledge      (active low)
  69 *   PB5 (output)  |  Transfer in progress  (active low)
  70 */
  71
  72/* Bits in Port B data register */
  73#define TREQ            0x08            /* Transfer request */
  74#define TACK            0x10            /* Transfer acknowledge */
  75#define TIP             0x20            /* Transfer in progress */
  76
  77/* Bits in ACR */
  78#define SR_CTRL         0x1c            /* Shift register control bits */
  79#define SR_EXT          0x0c            /* Shift on external clock */
  80#define SR_OUT          0x10            /* Shift out if 1 */
  81
  82/* Bits in IFR and IER */
  83#define IER_SET         0x80            /* set bits in IER */
  84#define IER_CLR         0               /* clear bits in IER */
  85#define SR_INT          0x04            /* Shift register full/empty */
  86
  87/* Duration of byte acknowledgement pulse (us) */
  88#define EGRET_TACK_ASSERTED_DELAY       300
  89#define EGRET_TACK_NEGATED_DELAY        400
  90
  91/* Interval from interrupt to start of session (us) */
  92#define EGRET_SESSION_DELAY             450
  93
  94#ifdef CONFIG_PPC
  95#define mcu_is_egret    false
  96#else
  97static bool mcu_is_egret;
  98#endif
  99
 100static inline bool TREQ_asserted(u8 portb)
 101{
 102        return !(portb & TREQ);
 103}
 104
 105static inline void assert_TIP(void)
 106{
 107        if (mcu_is_egret) {
 108                udelay(EGRET_SESSION_DELAY);
 109                out_8(&via[B], in_8(&via[B]) | TIP);
 110        } else
 111                out_8(&via[B], in_8(&via[B]) & ~TIP);
 112}
 113
 114static inline void assert_TIP_and_TACK(void)
 115{
 116        if (mcu_is_egret) {
 117                udelay(EGRET_SESSION_DELAY);
 118                out_8(&via[B], in_8(&via[B]) | TIP | TACK);
 119        } else
 120                out_8(&via[B], in_8(&via[B]) & ~(TIP | TACK));
 121}
 122
 123static inline void assert_TACK(void)
 124{
 125        if (mcu_is_egret) {
 126                udelay(EGRET_TACK_NEGATED_DELAY);
 127                out_8(&via[B], in_8(&via[B]) | TACK);
 128        } else
 129                out_8(&via[B], in_8(&via[B]) & ~TACK);
 130}
 131
 132static inline void toggle_TACK(void)
 133{
 134        out_8(&via[B], in_8(&via[B]) ^ TACK);
 135}
 136
 137static inline void negate_TACK(void)
 138{
 139        if (mcu_is_egret) {
 140                udelay(EGRET_TACK_ASSERTED_DELAY);
 141                out_8(&via[B], in_8(&via[B]) & ~TACK);
 142        } else
 143                out_8(&via[B], in_8(&via[B]) | TACK);
 144}
 145
 146static inline void negate_TIP_and_TACK(void)
 147{
 148        if (mcu_is_egret) {
 149                udelay(EGRET_TACK_ASSERTED_DELAY);
 150                out_8(&via[B], in_8(&via[B]) & ~(TIP | TACK));
 151        } else
 152                out_8(&via[B], in_8(&via[B]) | TIP | TACK);
 153}
 154
 155static enum cuda_state {
 156    idle,
 157    sent_first_byte,
 158    sending,
 159    reading,
 160    read_done,
 161    awaiting_reply
 162} cuda_state;
 163
 164static struct adb_request *current_req;
 165static struct adb_request *last_req;
 166static unsigned char cuda_rbuf[16];
 167static unsigned char *reply_ptr;
 168static int reading_reply;
 169static int data_index;
 170static int cuda_irq;
 171#ifdef CONFIG_PPC
 172static struct device_node *vias;
 173#endif
 174static int cuda_fully_inited;
 175
 176#ifdef CONFIG_ADB
 177static int cuda_probe(void);
 178static int cuda_send_request(struct adb_request *req, int sync);
 179static int cuda_adb_autopoll(int devs);
 180static int cuda_reset_adb_bus(void);
 181#endif /* CONFIG_ADB */
 182
 183static int cuda_init_via(void);
 184static void cuda_start(void);
 185static irqreturn_t cuda_interrupt(int irq, void *arg);
 186static void cuda_input(unsigned char *buf, int nb);
 187void cuda_poll(void);
 188static int cuda_write(struct adb_request *req);
 189
 190int cuda_request(struct adb_request *req,
 191                 void (*done)(struct adb_request *), int nbytes, ...);
 192
 193#ifdef CONFIG_ADB
 194struct adb_driver via_cuda_driver = {
 195        .name         = "CUDA",
 196        .probe        = cuda_probe,
 197        .send_request = cuda_send_request,
 198        .autopoll     = cuda_adb_autopoll,
 199        .poll         = cuda_poll,
 200        .reset_bus    = cuda_reset_adb_bus,
 201};
 202#endif /* CONFIG_ADB */
 203
 204#ifdef CONFIG_MAC
 205int __init find_via_cuda(void)
 206{
 207    struct adb_request req;
 208    int err;
 209
 210    if (macintosh_config->adb_type != MAC_ADB_CUDA &&
 211        macintosh_config->adb_type != MAC_ADB_EGRET)
 212        return 0;
 213
 214    via = via1;
 215    cuda_state = idle;
 216    mcu_is_egret = macintosh_config->adb_type == MAC_ADB_EGRET;
 217
 218    err = cuda_init_via();
 219    if (err) {
 220        printk(KERN_ERR "cuda_init_via() failed\n");
 221        via = NULL;
 222        return 0;
 223    }
 224
 225    /* enable autopoll */
 226    cuda_request(&req, NULL, 3, CUDA_PACKET, CUDA_AUTOPOLL, 1);
 227    while (!req.complete)
 228        cuda_poll();
 229
 230    return 1;
 231}
 232#else
 233int __init find_via_cuda(void)
 234{
 235    struct adb_request req;
 236    phys_addr_t taddr;
 237    const u32 *reg;
 238    int err;
 239
 240    if (vias != 0)
 241        return 1;
 242    vias = of_find_node_by_name(NULL, "via-cuda");
 243    if (vias == 0)
 244        return 0;
 245
 246    reg = of_get_property(vias, "reg", NULL);
 247    if (reg == NULL) {
 248            printk(KERN_ERR "via-cuda: No \"reg\" property !\n");
 249            goto fail;
 250    }
 251    taddr = of_translate_address(vias, reg);
 252    if (taddr == 0) {
 253            printk(KERN_ERR "via-cuda: Can't translate address !\n");
 254            goto fail;
 255    }
 256    via = ioremap(taddr, 0x2000);
 257    if (via == NULL) {
 258            printk(KERN_ERR "via-cuda: Can't map address !\n");
 259            goto fail;
 260    }
 261
 262    cuda_state = idle;
 263    sys_ctrler = SYS_CTRLER_CUDA;
 264
 265    err = cuda_init_via();
 266    if (err) {
 267        printk(KERN_ERR "cuda_init_via() failed\n");
 268        via = NULL;
 269        return 0;
 270    }
 271
 272    /* Clear and enable interrupts, but only on PPC. On 68K it's done  */
 273    /* for us by the main VIA driver in arch/m68k/mac/via.c        */
 274
 275    out_8(&via[IFR], 0x7f);     /* clear interrupts by writing 1s */
 276    out_8(&via[IER], IER_SET|SR_INT); /* enable interrupt from SR */
 277
 278    /* enable autopoll */
 279    cuda_request(&req, NULL, 3, CUDA_PACKET, CUDA_AUTOPOLL, 1);
 280    while (!req.complete)
 281        cuda_poll();
 282
 283    return 1;
 284
 285 fail:
 286    of_node_put(vias);
 287    vias = NULL;
 288    return 0;
 289}
 290#endif /* !defined CONFIG_MAC */
 291
 292static int __init via_cuda_start(void)
 293{
 294    if (via == NULL)
 295        return -ENODEV;
 296
 297#ifdef CONFIG_MAC
 298    cuda_irq = IRQ_MAC_ADB;
 299#else
 300    cuda_irq = irq_of_parse_and_map(vias, 0);
 301    if (!cuda_irq) {
 302        printk(KERN_ERR "via-cuda: can't map interrupts for %pOF\n",
 303               vias);
 304        return -ENODEV;
 305    }
 306#endif
 307
 308    if (request_irq(cuda_irq, cuda_interrupt, 0, "ADB", cuda_interrupt)) {
 309        printk(KERN_ERR "via-cuda: can't request irq %d\n", cuda_irq);
 310        return -EAGAIN;
 311    }
 312
 313    pr_info("Macintosh Cuda and Egret driver.\n");
 314
 315    cuda_fully_inited = 1;
 316    return 0;
 317}
 318
 319device_initcall(via_cuda_start);
 320
 321#ifdef CONFIG_ADB
 322static int
 323cuda_probe(void)
 324{
 325#ifdef CONFIG_PPC
 326    if (sys_ctrler != SYS_CTRLER_CUDA)
 327        return -ENODEV;
 328#else
 329    if (macintosh_config->adb_type != MAC_ADB_CUDA &&
 330        macintosh_config->adb_type != MAC_ADB_EGRET)
 331        return -ENODEV;
 332#endif
 333    if (via == NULL)
 334        return -ENODEV;
 335    return 0;
 336}
 337#endif /* CONFIG_ADB */
 338
 339static int __init sync_egret(void)
 340{
 341        if (TREQ_asserted(in_8(&via[B]))) {
 342                /* Complete the inbound transfer */
 343                assert_TIP_and_TACK();
 344                while (1) {
 345                        negate_TACK();
 346                        mdelay(1);
 347                        (void)in_8(&via[SR]);
 348                        assert_TACK();
 349                        if (!TREQ_asserted(in_8(&via[B])))
 350                                break;
 351                }
 352                negate_TIP_and_TACK();
 353        } else if (in_8(&via[B]) & TIP) {
 354                /* Terminate the outbound transfer */
 355                negate_TACK();
 356                assert_TACK();
 357                mdelay(1);
 358                negate_TIP_and_TACK();
 359        }
 360        /* Clear shift register interrupt */
 361        if (in_8(&via[IFR]) & SR_INT)
 362                (void)in_8(&via[SR]);
 363        return 0;
 364}
 365
 366#define WAIT_FOR(cond, what)                                    \
 367    do {                                                        \
 368        int x;                                                  \
 369        for (x = 1000; !(cond); --x) {                          \
 370            if (x == 0) {                                       \
 371                pr_err("Timeout waiting for " what "\n");       \
 372                return -ENXIO;                                  \
 373            }                                                   \
 374            udelay(100);                                        \
 375        }                                                       \
 376    } while (0)
 377
 378static int
 379__init cuda_init_via(void)
 380{
 381#ifdef CONFIG_PPC
 382    out_8(&via[IER], 0x7f);                                     /* disable interrupts from VIA */
 383    (void)in_8(&via[IER]);
 384#else
 385    out_8(&via[IER], SR_INT);                                   /* disable SR interrupt from VIA */
 386#endif
 387
 388    out_8(&via[DIRB], (in_8(&via[DIRB]) | TACK | TIP) & ~TREQ); /* TACK & TIP out */
 389    out_8(&via[ACR], (in_8(&via[ACR]) & ~SR_CTRL) | SR_EXT);    /* SR data in */
 390    (void)in_8(&via[SR]);                                       /* clear any left-over data */
 391
 392    if (mcu_is_egret)
 393        return sync_egret();
 394
 395    negate_TIP_and_TACK();
 396
 397    /* delay 4ms and then clear any pending interrupt */
 398    mdelay(4);
 399    (void)in_8(&via[SR]);
 400    out_8(&via[IFR], SR_INT);
 401
 402    /* sync with the CUDA - assert TACK without TIP */
 403    assert_TACK();
 404
 405    /* wait for the CUDA to assert TREQ in response */
 406    WAIT_FOR(TREQ_asserted(in_8(&via[B])), "CUDA response to sync");
 407
 408    /* wait for the interrupt and then clear it */
 409    WAIT_FOR(in_8(&via[IFR]) & SR_INT, "CUDA response to sync (2)");
 410    (void)in_8(&via[SR]);
 411    out_8(&via[IFR], SR_INT);
 412
 413    /* finish the sync by negating TACK */
 414    negate_TACK();
 415
 416    /* wait for the CUDA to negate TREQ and the corresponding interrupt */
 417    WAIT_FOR(!TREQ_asserted(in_8(&via[B])), "CUDA response to sync (3)");
 418    WAIT_FOR(in_8(&via[IFR]) & SR_INT, "CUDA response to sync (4)");
 419    (void)in_8(&via[SR]);
 420    out_8(&via[IFR], SR_INT);
 421
 422    return 0;
 423}
 424
 425#ifdef CONFIG_ADB
 426/* Send an ADB command */
 427static int
 428cuda_send_request(struct adb_request *req, int sync)
 429{
 430    int i;
 431
 432    if ((via == NULL) || !cuda_fully_inited) {
 433        req->complete = 1;
 434        return -ENXIO;
 435    }
 436  
 437    req->reply_expected = 1;
 438
 439    i = cuda_write(req);
 440    if (i)
 441        return i;
 442
 443    if (sync) {
 444        while (!req->complete)
 445            cuda_poll();
 446    }
 447    return 0;
 448}
 449
 450
 451/* Enable/disable autopolling */
 452static int
 453cuda_adb_autopoll(int devs)
 454{
 455    struct adb_request req;
 456
 457    if ((via == NULL) || !cuda_fully_inited)
 458        return -ENXIO;
 459
 460    cuda_request(&req, NULL, 3, CUDA_PACKET, CUDA_AUTOPOLL, (devs? 1: 0));
 461    while (!req.complete)
 462        cuda_poll();
 463    return 0;
 464}
 465
 466/* Reset adb bus - how do we do this?? */
 467static int
 468cuda_reset_adb_bus(void)
 469{
 470    struct adb_request req;
 471
 472    if ((via == NULL) || !cuda_fully_inited)
 473        return -ENXIO;
 474
 475    cuda_request(&req, NULL, 2, ADB_PACKET, 0);         /* maybe? */
 476    while (!req.complete)
 477        cuda_poll();
 478    return 0;
 479}
 480#endif /* CONFIG_ADB */
 481
 482/* Construct and send a cuda request */
 483int
 484cuda_request(struct adb_request *req, void (*done)(struct adb_request *),
 485             int nbytes, ...)
 486{
 487    va_list list;
 488    int i;
 489
 490    if (via == NULL) {
 491        req->complete = 1;
 492        return -ENXIO;
 493    }
 494
 495    req->nbytes = nbytes;
 496    req->done = done;
 497    va_start(list, nbytes);
 498    for (i = 0; i < nbytes; ++i)
 499        req->data[i] = va_arg(list, int);
 500    va_end(list);
 501    req->reply_expected = 1;
 502    return cuda_write(req);
 503}
 504EXPORT_SYMBOL(cuda_request);
 505
 506static int
 507cuda_write(struct adb_request *req)
 508{
 509    unsigned long flags;
 510
 511    if (req->nbytes < 2 || req->data[0] > CUDA_PACKET) {
 512        req->complete = 1;
 513        return -EINVAL;
 514    }
 515    req->next = NULL;
 516    req->sent = 0;
 517    req->complete = 0;
 518    req->reply_len = 0;
 519
 520    spin_lock_irqsave(&cuda_lock, flags);
 521    if (current_req != 0) {
 522        last_req->next = req;
 523        last_req = req;
 524    } else {
 525        current_req = req;
 526        last_req = req;
 527        if (cuda_state == idle)
 528            cuda_start();
 529    }
 530    spin_unlock_irqrestore(&cuda_lock, flags);
 531
 532    return 0;
 533}
 534
 535static void
 536cuda_start(void)
 537{
 538    /* assert cuda_state == idle */
 539    if (current_req == NULL)
 540        return;
 541    data_index = 0;
 542    if (TREQ_asserted(in_8(&via[B])))
 543        return;                 /* a byte is coming in from the CUDA */
 544
 545    /* set the shift register to shift out and send a byte */
 546    out_8(&via[ACR], in_8(&via[ACR]) | SR_OUT);
 547    out_8(&via[SR], current_req->data[data_index++]);
 548    if (mcu_is_egret)
 549        assert_TIP_and_TACK();
 550    else
 551        assert_TIP();
 552    cuda_state = sent_first_byte;
 553}
 554
 555void
 556cuda_poll(void)
 557{
 558        cuda_interrupt(0, NULL);
 559}
 560EXPORT_SYMBOL(cuda_poll);
 561
 562#define ARRAY_FULL(a, p)        ((p) - (a) == ARRAY_SIZE(a))
 563
 564static irqreturn_t
 565cuda_interrupt(int irq, void *arg)
 566{
 567    unsigned long flags;
 568    u8 status;
 569    struct adb_request *req = NULL;
 570    unsigned char ibuf[16];
 571    int ibuf_len = 0;
 572    int complete = 0;
 573    bool full;
 574    
 575    spin_lock_irqsave(&cuda_lock, flags);
 576
 577    /* On powermacs, this handler is registered for the VIA IRQ. But they use
 578     * just the shift register IRQ -- other VIA interrupt sources are disabled.
 579     * On m68k macs, the VIA IRQ sources are dispatched individually. Unless
 580     * we are polling, the shift register IRQ flag has already been cleared.
 581     */
 582
 583#ifdef CONFIG_MAC
 584    if (!arg)
 585#endif
 586    {
 587        if ((in_8(&via[IFR]) & SR_INT) == 0) {
 588            spin_unlock_irqrestore(&cuda_lock, flags);
 589            return IRQ_NONE;
 590        } else {
 591            out_8(&via[IFR], SR_INT);
 592        }
 593    }
 594
 595    status = in_8(&via[B]) & (TIP | TACK | TREQ);
 596
 597    switch (cuda_state) {
 598    case idle:
 599        /* System controller has unsolicited data for us */
 600        (void)in_8(&via[SR]);
 601idle_state:
 602        assert_TIP();
 603        cuda_state = reading;
 604        reply_ptr = cuda_rbuf;
 605        reading_reply = 0;
 606        break;
 607
 608    case awaiting_reply:
 609        /* System controller has reply data for us */
 610        (void)in_8(&via[SR]);
 611        assert_TIP();
 612        cuda_state = reading;
 613        reply_ptr = current_req->reply;
 614        reading_reply = 1;
 615        break;
 616
 617    case sent_first_byte:
 618        if (TREQ_asserted(status)) {
 619            /* collision */
 620            out_8(&via[ACR], in_8(&via[ACR]) & ~SR_OUT);
 621            (void)in_8(&via[SR]);
 622            negate_TIP_and_TACK();
 623            cuda_state = idle;
 624            /* Egret does not raise an "aborted" interrupt */
 625            if (mcu_is_egret)
 626                goto idle_state;
 627        } else {
 628            out_8(&via[SR], current_req->data[data_index++]);
 629            toggle_TACK();
 630            if (mcu_is_egret)
 631                assert_TACK();
 632            cuda_state = sending;
 633        }
 634        break;
 635
 636    case sending:
 637        req = current_req;
 638        if (data_index >= req->nbytes) {
 639            out_8(&via[ACR], in_8(&via[ACR]) & ~SR_OUT);
 640            (void)in_8(&via[SR]);
 641            negate_TIP_and_TACK();
 642            req->sent = 1;
 643            if (req->reply_expected) {
 644                cuda_state = awaiting_reply;
 645            } else {
 646                current_req = req->next;
 647                complete = 1;
 648                /* not sure about this */
 649                cuda_state = idle;
 650                cuda_start();
 651            }
 652        } else {
 653            out_8(&via[SR], req->data[data_index++]);
 654            toggle_TACK();
 655            if (mcu_is_egret)
 656                assert_TACK();
 657        }
 658        break;
 659
 660    case reading:
 661        full = reading_reply ? ARRAY_FULL(current_req->reply, reply_ptr)
 662                             : ARRAY_FULL(cuda_rbuf, reply_ptr);
 663        if (full)
 664            (void)in_8(&via[SR]);
 665        else
 666            *reply_ptr++ = in_8(&via[SR]);
 667        if (!TREQ_asserted(status) || full) {
 668            if (mcu_is_egret)
 669                assert_TACK();
 670            /* that's all folks */
 671            negate_TIP_and_TACK();
 672            cuda_state = read_done;
 673            /* Egret does not raise a "read done" interrupt */
 674            if (mcu_is_egret)
 675                goto read_done_state;
 676        } else {
 677            toggle_TACK();
 678            if (mcu_is_egret)
 679                negate_TACK();
 680        }
 681        break;
 682
 683    case read_done:
 684        (void)in_8(&via[SR]);
 685read_done_state:
 686        if (reading_reply) {
 687            req = current_req;
 688            req->reply_len = reply_ptr - req->reply;
 689            if (req->data[0] == ADB_PACKET) {
 690                /* Have to adjust the reply from ADB commands */
 691                if (req->reply_len <= 2 || (req->reply[1] & 2) != 0) {
 692                    /* the 0x2 bit indicates no response */
 693                    req->reply_len = 0;
 694                } else {
 695                    /* leave just the command and result bytes in the reply */
 696                    req->reply_len -= 2;
 697                    memmove(req->reply, req->reply + 2, req->reply_len);
 698                }
 699            }
 700            current_req = req->next;
 701            complete = 1;
 702            reading_reply = 0;
 703        } else {
 704            /* This is tricky. We must break the spinlock to call
 705             * cuda_input. However, doing so means we might get
 706             * re-entered from another CPU getting an interrupt
 707             * or calling cuda_poll(). I ended up using the stack
 708             * (it's only for 16 bytes) and moving the actual
 709             * call to cuda_input to outside of the lock.
 710             */
 711            ibuf_len = reply_ptr - cuda_rbuf;
 712            memcpy(ibuf, cuda_rbuf, ibuf_len);
 713        }
 714        reply_ptr = cuda_rbuf;
 715        cuda_state = idle;
 716        cuda_start();
 717        if (cuda_state == idle && TREQ_asserted(in_8(&via[B]))) {
 718            assert_TIP();
 719            cuda_state = reading;
 720        }
 721        break;
 722
 723    default:
 724        pr_err("cuda_interrupt: unknown cuda_state %d?\n", cuda_state);
 725    }
 726    spin_unlock_irqrestore(&cuda_lock, flags);
 727    if (complete && req) {
 728        void (*done)(struct adb_request *) = req->done;
 729        mb();
 730        req->complete = 1;
 731        /* Here, we assume that if the request has a done member, the
 732         * struct request will survive to setting req->complete to 1
 733         */
 734        if (done)
 735                (*done)(req);
 736    }
 737    if (ibuf_len)
 738        cuda_input(ibuf, ibuf_len);
 739    return IRQ_HANDLED;
 740}
 741
 742static void
 743cuda_input(unsigned char *buf, int nb)
 744{
 745    switch (buf[0]) {
 746    case ADB_PACKET:
 747#ifdef CONFIG_XMON
 748        if (nb == 5 && buf[2] == 0x2c) {
 749            extern int xmon_wants_key, xmon_adb_keycode;
 750            if (xmon_wants_key) {
 751                xmon_adb_keycode = buf[3];
 752                return;
 753            }
 754        }
 755#endif /* CONFIG_XMON */
 756#ifdef CONFIG_ADB
 757        adb_input(buf+2, nb-2, buf[1] & 0x40);
 758#endif /* CONFIG_ADB */
 759        break;
 760
 761    case TIMER_PACKET:
 762        /* Egret sends these periodically. Might be useful as a 'heartbeat'
 763         * to trigger a recovery for the VIA shift register errata.
 764         */
 765        break;
 766
 767    default:
 768        print_hex_dump(KERN_INFO, "cuda_input: ", DUMP_PREFIX_NONE, 32, 1,
 769                       buf, nb, false);
 770    }
 771}
 772
 773/* Offset between Unix time (1970-based) and Mac time (1904-based) */
 774#define RTC_OFFSET      2082844800
 775
 776time64_t cuda_get_time(void)
 777{
 778        struct adb_request req;
 779        u32 now;
 780
 781        if (cuda_request(&req, NULL, 2, CUDA_PACKET, CUDA_GET_TIME) < 0)
 782                return 0;
 783        while (!req.complete)
 784                cuda_poll();
 785        if (req.reply_len != 7)
 786                pr_err("%s: got %d byte reply\n", __func__, req.reply_len);
 787        now = (req.reply[3] << 24) + (req.reply[4] << 16) +
 788              (req.reply[5] << 8) + req.reply[6];
 789        return (time64_t)now - RTC_OFFSET;
 790}
 791
 792int cuda_set_rtc_time(struct rtc_time *tm)
 793{
 794        u32 now;
 795        struct adb_request req;
 796
 797        now = lower_32_bits(rtc_tm_to_time64(tm) + RTC_OFFSET);
 798        if (cuda_request(&req, NULL, 6, CUDA_PACKET, CUDA_SET_TIME,
 799                         now >> 24, now >> 16, now >> 8, now) < 0)
 800                return -ENXIO;
 801        while (!req.complete)
 802                cuda_poll();
 803        if ((req.reply_len != 3) && (req.reply_len != 7))
 804                pr_err("%s: got %d byte reply\n", __func__, req.reply_len);
 805        return 0;
 806}
 807