arch/powerpc/platforms/pasemi/msi.c

Source file repositories/reference/linux-study-clean/arch/powerpc/platforms/pasemi/msi.c

File Facts

System
Linux kernel
Corpus path
arch/powerpc/platforms/pasemi/msi.c
Extension
.c
Size
4410 bytes
Lines
163
Domain
Architecture Layer
Bucket
arch/powerpc
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

if (hwirq < 0) {
			pr_debug("pasemi_msi: failed allocating hwirq\n");
			return hwirq;
		}

		virq = irq_create_mapping(msi_mpic->irqhost, hwirq);
		if (!virq) {
			pr_debug("pasemi_msi: failed mapping hwirq 0x%x\n",
				  hwirq);
			msi_bitmap_free_hwirqs(&msi_mpic->msi_bitmap, hwirq,
					       ALLOC_CHUNK);
			return -ENOSPC;
		}

		/* Vector on MSI is really an offset, the hardware adds
		 * it to the value written at the magic address. So set
		 * it to 0 to remain sane.
		 */
		mpic_set_vector(virq, 0);

		irq_set_msi_desc(virq, entry);
		irq_set_chip(virq, &mpic_pasemi_msi_chip);
		irq_set_irq_type(virq, IRQ_TYPE_EDGE_RISING);

		pr_debug("pasemi_msi: allocated virq 0x%x (hw 0x%x) " \
			 "addr 0x%x\n", virq, hwirq, msg.address_lo);

		/* Likewise, the device writes [0...511] into the target
		 * register to generate MSI [512...1023]
		 */
		msg.data = hwirq-0x200;
		pci_write_msi_msg(virq, &msg);
	}

	return 0;
}

int __init mpic_pasemi_msi_init(struct mpic *mpic)
{
	int rc;
	struct pci_controller *phb;
	struct device_node *of_node;

	of_node = irq_domain_get_of_node(mpic->irqhost);
	if (!of_node ||
	    !of_device_is_compatible(of_node,
				     "pasemi,pwrficient-openpic"))
		return -ENODEV;

	rc = mpic_msi_init_allocator(mpic);
	if (rc) {
		pr_debug("pasemi_msi: Error allocating bitmap!\n");
		return rc;
	}

	pr_debug("pasemi_msi: Registering PA Semi MPIC MSI callbacks\n");

	msi_mpic = mpic;
	list_for_each_entry(phb, &hose_list, list_node) {
		WARN_ON(phb->controller_ops.setup_msi_irqs);
		phb->controller_ops.setup_msi_irqs = pasemi_msi_setup_msi_irqs;
		phb->controller_ops.teardown_msi_irqs = pasemi_msi_teardown_msi_irqs;
	}

	return 0;
}

Annotation

Implementation Notes