drivers/macintosh/via-cuda.c

Source file repositories/reference/linux-study-clean/drivers/macintosh/via-cuda.c

File Facts

System
Linux kernel
Corpus path
drivers/macintosh/via-cuda.c
Extension
.c
Size
19635 bytes
Lines
803
Domain
Driver Families
Bucket
drivers/macintosh
Inferred role
Driver Families: exported/initcall integration point
Status
integration implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

device_initcall(via_cuda_start);

#ifdef CONFIG_ADB
static int
cuda_probe(void)
{
#ifdef CONFIG_PPC
    if (sys_ctrler != SYS_CTRLER_CUDA)
	return -ENODEV;
#else
    if (macintosh_config->adb_type != MAC_ADB_CUDA &&
        macintosh_config->adb_type != MAC_ADB_EGRET)
	return -ENODEV;
#endif
    if (via == NULL)
	return -ENODEV;
    return 0;
}
#endif /* CONFIG_ADB */

static int __init sync_egret(void)
{
	if (TREQ_asserted(in_8(&via[B]))) {
		/* Complete the inbound transfer */
		assert_TIP_and_TACK();
		while (1) {
			negate_TACK();
			mdelay(1);
			(void)in_8(&via[SR]);
			assert_TACK();
			if (!TREQ_asserted(in_8(&via[B])))
				break;
		}
		negate_TIP_and_TACK();
	} else if (in_8(&via[B]) & TIP) {
		/* Terminate the outbound transfer */
		negate_TACK();
		assert_TACK();
		mdelay(1);
		negate_TIP_and_TACK();
	}
	/* Clear shift register interrupt */
	if (in_8(&via[IFR]) & SR_INT)
		(void)in_8(&via[SR]);
	return 0;
}

#define WAIT_FOR(cond, what)					\
    do {                                                        \
    	int x;							\
	for (x = 1000; !(cond); --x) {				\
	    if (x == 0) {					\
		pr_err("Timeout waiting for " what "\n");	\
		return -ENXIO;					\
	    }							\
	    udelay(100);					\
	}							\
    } while (0)

static int
__init cuda_init_via(void)
{
#ifdef CONFIG_PPC
    out_8(&via[IER], 0x7f);					/* disable interrupts from VIA */
    (void)in_8(&via[IER]);
#else
    out_8(&via[IER], SR_INT);					/* disable SR interrupt from VIA */
#endif

    out_8(&via[DIRB], (in_8(&via[DIRB]) | TACK | TIP) & ~TREQ);	/* TACK & TIP out */
    out_8(&via[ACR], (in_8(&via[ACR]) & ~SR_CTRL) | SR_EXT);	/* SR data in */
    (void)in_8(&via[SR]);					/* clear any left-over data */

    if (mcu_is_egret)
	return sync_egret();

    negate_TIP_and_TACK();

    /* delay 4ms and then clear any pending interrupt */
    mdelay(4);
    (void)in_8(&via[SR]);
    out_8(&via[IFR], SR_INT);

    /* sync with the CUDA - assert TACK without TIP */
    assert_TACK();

    /* wait for the CUDA to assert TREQ in response */
    WAIT_FOR(TREQ_asserted(in_8(&via[B])), "CUDA response to sync");

    /* wait for the interrupt and then clear it */

Annotation

Implementation Notes