int iosapic_serial_irq()

in iosapic.c [803:877]


int iosapic_serial_irq(struct parisc_device *dev)
{
	struct iosapic_info *isi;
	struct irt_entry *irte;
	struct vector_info *vi;
	int cnt;
	int intin;

	intin = (dev->mod_info >> 24) & 15;

	/* lookup IRT entry for isi/slot/pin set */
	for (cnt = 0; cnt < irt_num_entry; cnt++) {
		irte = &irt_cell[cnt];
		if (COMPARE_IRTE_ADDR(irte, dev->mod0) &&
		    irte->dest_iosapic_intin == intin)
			break;
	}
	if (cnt >= irt_num_entry)
		return 0; /* no irq found, force polling */

	DBG_IRT("iosapic_serial_irq(): irte %p %x %x %x %x %x %x %x %x\n",
		irte,
		irte->entry_type,
		irte->entry_length,
		irte->polarity_trigger,
		irte->src_bus_irq_devno,
		irte->src_bus_id,
		irte->src_seg_id,
		irte->dest_iosapic_intin,
		(u32) irte->dest_iosapic_addr);

	/* search for iosapic */
	for (isi = iosapic_list; isi; isi = isi->isi_next)
		if (isi->isi_hpa == dev->mod0)
			break;
	if (!isi)
		return 0; /* no iosapic found, force polling */

	/* get vector info for this input line */
	vi = isi->isi_vector + intin;
	DBG_IRT("iosapic_serial_irq:  line %d vi 0x%p\n", iosapic_intin, vi);

	/* If this IRQ line has already been setup, skip it */
	if (vi->irte)
		goto out;

	vi->irte = irte;

	/*
	 * Allocate processor IRQ
	 *
	 * XXX/FIXME The txn_alloc_irq() code and related code should be
	 * moved to enable_irq(). That way we only allocate processor IRQ
	 * bits for devices that actually have drivers claiming them.
	 * Right now we assign an IRQ to every PCI device present,
	 * regardless of whether it's used or not.
	 */
	vi->txn_irq = txn_alloc_irq(8);

	if (vi->txn_irq < 0)
		panic("I/O sapic: couldn't get TXN IRQ\n");

	/* enable_irq() will use txn_* to program IRdT */
	vi->txn_addr = txn_alloc_addr(vi->txn_irq);
	vi->txn_data = txn_alloc_data(vi->txn_irq);

	vi->eoi_addr = isi->addr + IOSAPIC_REG_EOI;
	vi->eoi_data = cpu_to_le32(vi->txn_data);

	cpu_claim_irq(vi->txn_irq, &iosapic_interrupt_type, vi);

 out:

	return vi->txn_irq;
}