drivers/macintosh/via-pmu.c

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

File Facts

System
Linux kernel
Corpus path
drivers/macintosh/via-pmu.c
Extension
.c
Size
64918 bytes
Lines
2670
Domain
Driver Families
Bucket
drivers/macintosh
Inferred role
Driver Families: operation-table or driver-model contract
Status
pattern 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

static const struct file_operations pmu_device_fops = {
	.read		= pmu_read,
	.write		= pmu_write,
	.poll		= pmu_fpoll,
	.unlocked_ioctl	= pmu_unlocked_ioctl,
#ifdef CONFIG_COMPAT
	.compat_ioctl	= compat_pmu_ioctl,
#endif
	.open		= pmu_open,
	.release	= pmu_release,
	.llseek		= noop_llseek,
};

static struct miscdevice pmu_device = {
	PMU_MINOR, "pmu", &pmu_device_fops
};

static int pmu_device_init(void)
{
	if (pmu_state == uninitialized)
		return 0;
	if (misc_register(&pmu_device) < 0)
		printk(KERN_ERR "via-pmu: cannot register misc device.\n");
	return 0;
}
device_initcall(pmu_device_init);


#ifdef DEBUG_SLEEP
static inline void 
polled_handshake(void)
{
	via2[B] &= ~TREQ; eieio();
	while ((via2[B] & TACK) != 0)
		;
	via2[B] |= TREQ; eieio();
	while ((via2[B] & TACK) == 0)
		;
}

static inline void 
polled_send_byte(int x)
{
	via1[ACR] |= SR_OUT | SR_EXT; eieio();
	via1[SR] = x; eieio();
	polled_handshake();
}

static inline int
polled_recv_byte(void)
{
	int x;

	via1[ACR] = (via1[ACR] & ~SR_OUT) | SR_EXT; eieio();
	x = via1[SR]; eieio();
	polled_handshake();
	x = via1[SR]; eieio();
	return x;
}

int
pmu_polled_request(struct adb_request *req)
{
	unsigned long flags;
	int i, l, c;

	req->complete = 1;
	c = req->data[0];
	l = pmu_data_len[c][0];
	if (l >= 0 && req->nbytes != l + 1)
		return -EINVAL;

	local_irq_save(flags);
	while (pmu_state != idle)
		pmu_poll();

	while ((via2[B] & TACK) == 0)
		;
	polled_send_byte(c);
	if (l < 0) {
		l = req->nbytes - 1;
		polled_send_byte(l);
	}
	for (i = 1; i <= l; ++i)
		polled_send_byte(req->data[i]);

	l = pmu_data_len[c][1];
	if (l < 0)
		l = polled_recv_byte();
	for (i = 0; i < l; ++i)

Annotation

Implementation Notes