arch/m68k/mac/iop.c

Source file repositories/reference/linux-study-clean/arch/m68k/mac/iop.c

File Facts

System
Linux kernel
Corpus path
arch/m68k/mac/iop.c
Extension
.c
Size
17812 bytes
Lines
591
Domain
Architecture Layer
Bucket
arch/m68k
Inferred role
Architecture Layer: implementation source
Status
source implementation candidate

Why This File Exists

CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.

Dependency Surface

Detected Declarations

Annotated Snippet

struct listener {
	const char *devname;
	void (*handler)(struct iop_msg *);
};

/*
 * IOP structures for the two IOPs
 *
 * The SCC IOP controls both serial ports (A and B) as its two functions.
 * The ISM IOP controls the SWIM (floppy drive) and ADB.
 */

static volatile struct mac_iop *iop_base[NUM_IOPS];

/*
 * IOP message queues
 */

static struct iop_msg iop_msg_pool[NUM_IOP_MSGS];
static struct iop_msg *iop_send_queue[NUM_IOPS][NUM_IOP_CHAN];
static struct listener iop_listeners[NUM_IOPS][NUM_IOP_CHAN];

irqreturn_t iop_ism_irq(int, void *);

/*
 * Private access functions
 */

static __inline__ void iop_loadaddr(volatile struct mac_iop *iop, __u16 addr)
{
	iop->ram_addr_lo = addr;
	iop->ram_addr_hi = addr >> 8;
}

static __inline__ __u8 iop_readb(volatile struct mac_iop *iop, __u16 addr)
{
	iop->ram_addr_lo = addr;
	iop->ram_addr_hi = addr >> 8;
	return iop->ram_data;
}

static __inline__ void iop_writeb(volatile struct mac_iop *iop, __u16 addr, __u8 data)
{
	iop->ram_addr_lo = addr;
	iop->ram_addr_hi = addr >> 8;
	iop->ram_data = data;
}

static __inline__ void iop_stop(volatile struct mac_iop *iop)
{
	iop->status_ctrl = IOP_AUTOINC;
}

static __inline__ void iop_start(volatile struct mac_iop *iop)
{
	iop->status_ctrl = IOP_RUN | IOP_AUTOINC;
}

static __inline__ void iop_interrupt(volatile struct mac_iop *iop)
{
	iop->status_ctrl = IOP_IRQ | IOP_RUN | IOP_AUTOINC;
}

static int iop_alive(volatile struct mac_iop *iop)
{
	int retval;

	retval = (iop_readb(iop, IOP_ADDR_ALIVE) == 0xFF);
	iop_writeb(iop, IOP_ADDR_ALIVE, 0);
	return retval;
}

static struct iop_msg *iop_get_unused_msg(void)
{
	int i;
	unsigned long flags;

	local_irq_save(flags);

	for (i = 0 ; i < NUM_IOP_MSGS ; i++) {
		if (iop_msg_pool[i].status == IOP_MSGSTATUS_UNUSED) {
			iop_msg_pool[i].status = IOP_MSGSTATUS_WAITING;
			local_irq_restore(flags);
			return &iop_msg_pool[i];
		}
	}

	local_irq_restore(flags);
	return NULL;
}

Annotation

Implementation Notes