drivers/parisc/eisa.c

Source file repositories/reference/linux-study-clean/drivers/parisc/eisa.c

File Facts

System
Linux kernel
Corpus path
drivers/parisc/eisa.c
Extension
.c
Size
11869 bytes
Lines
464
Domain
Driver Families
Bucket
drivers/parisc
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

if (irq & 8) {
		slave_mask |= (1 << (irq&7));
		eisa_out8(slave_mask, 0xa1);
	} else {
		master_mask |= (1 << (irq&7));
		eisa_out8(master_mask, 0x21);
	}
	spin_unlock_irqrestore(&eisa_irq_lock, flags);
	EISA_DBG("pic0 mask %02x\n", eisa_in8(0x21));
	EISA_DBG("pic1 mask %02x\n", eisa_in8(0xa1));
}

/* called by request irq */
static void eisa_unmask_irq(struct irq_data *d)
{
	unsigned int irq = d->irq;
	unsigned long flags;
	EISA_DBG("enable irq %d\n", irq);

	spin_lock_irqsave(&eisa_irq_lock, flags);
        if (irq & 8) {
		slave_mask &= ~(1 << (irq&7));
		eisa_out8(slave_mask, 0xa1);
	} else {
		master_mask &= ~(1 << (irq&7));
		eisa_out8(master_mask, 0x21);
	}
	spin_unlock_irqrestore(&eisa_irq_lock, flags);
	EISA_DBG("pic0 mask %02x\n", eisa_in8(0x21));
	EISA_DBG("pic1 mask %02x\n", eisa_in8(0xa1));
}

static struct irq_chip eisa_interrupt_type = {
	.name		=	"EISA",
	.irq_unmask	=	eisa_unmask_irq,
	.irq_mask	=	eisa_mask_irq,
};

static irqreturn_t eisa_irq(int wax_irq, void *intr_dev)
{
	int irq = gsc_readb(0xfc01f000); /* EISA supports 16 irqs */
	unsigned long flags;

	spin_lock_irqsave(&eisa_irq_lock, flags);
	/* read IRR command */
	eisa_out8(0x0a, 0x20);
	eisa_out8(0x0a, 0xa0);

	EISA_DBG("irq IAR %02x 8259-1 irr %02x 8259-2 irr %02x\n",
		   irq, eisa_in8(0x20), eisa_in8(0xa0));

	/* read ISR command */
	eisa_out8(0x0a, 0x20);
	eisa_out8(0x0a, 0xa0);
	EISA_DBG("irq 8259-1 isr %02x imr %02x 8259-2 isr %02x imr %02x\n",
		 eisa_in8(0x20), eisa_in8(0x21), eisa_in8(0xa0), eisa_in8(0xa1));

	irq &= 0xf;

	/* mask irq and write eoi */
	if (irq & 8) {
		slave_mask |= (1 << (irq&7));
		eisa_out8(slave_mask, 0xa1);
		eisa_out8(0x60 | (irq&7),0xa0);/* 'Specific EOI' to slave */
		eisa_out8(0x62, 0x20);	/* 'Specific EOI' to master-IRQ2 */

	} else {
		master_mask |= (1 << (irq&7));
		eisa_out8(master_mask, 0x21);
		eisa_out8(0x60|irq, 0x20);	/* 'Specific EOI' to master */
	}
	spin_unlock_irqrestore(&eisa_irq_lock, flags);

	generic_handle_irq(irq);

	spin_lock_irqsave(&eisa_irq_lock, flags);
	/* unmask */
        if (irq & 8) {
		slave_mask &= ~(1 << (irq&7));
		eisa_out8(slave_mask, 0xa1);
	} else {
		master_mask &= ~(1 << (irq&7));
		eisa_out8(master_mask, 0x21);
	}
	spin_unlock_irqrestore(&eisa_irq_lock, flags);
	return IRQ_HANDLED;
}

static irqreturn_t dummy_irq2_handler(int _, void *dev)
{

Annotation

Implementation Notes