drivers/parisc/dino.c

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

File Facts

System
Linux kernel
Corpus path
drivers/parisc/dino.c
Extension
.c
Size
32230 bytes
Lines
1092
Domain
Driver Families
Bucket
drivers/parisc
Inferred role
Driver Families: implementation source
Status
source 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

F_EXTEND(0xffffffffUL) &~ _8MB, _8MB) < 0) {
		struct pci_dev *dev, *tmp;

		printk(KERN_ERR "Dino: cannot attach bus %s\n",
		       dev_name(bus->bridge));
		/* kill the bus, we can't do anything with it */
		list_for_each_entry_safe(dev, tmp, &bus->devices, bus_list) {
			list_del(&dev->bus_list);
		}
			
		return;
	}
	bus->resource[1] = res;
	bus->resource[0] = &(dino_dev->hba.io_space);

	/* Now tell dino what range it has */
	for (i = 1; i < 31; i++) {
		if (res->start == F_EXTEND(0xf0000000UL | (i * _8MB)))
			break;
	}
	DBG("DINO GSC WRITE i=%d, start=%lx, dino addr = %p\n",
	    i, res->start, base_addr + DINO_IO_ADDR_EN);
	__raw_writel(1 << i, base_addr + DINO_IO_ADDR_EN);
}

static void __init
dino_card_fixup(struct pci_dev *dev)
{
	u32 irq_pin;

	/*
	** REVISIT: card-mode PCI-PCI expansion chassis do exist.
	**         Not sure they were ever productized.
	**         Die here since we'll die later in dino_inb() anyway.
	*/
	if ((dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) {
		panic("Card-Mode Dino: PCI-PCI Bridge not supported\n");
	}

	/*
	** Set Latency Timer to 0xff (not a shared bus)
	** Set CACHELINE_SIZE.
	*/
	dino_cfg_write(dev->bus, dev->devfn, 
		       PCI_CACHE_LINE_SIZE, 2, 0xff00 | L1_CACHE_BYTES/4); 

	/*
	** Program INT_LINE for card-mode devices.
	** The cards are hardwired according to this algorithm.
	** And it doesn't matter if PPB's are present or not since
	** the IRQ lines bypass the PPB.
	**
	** "-1" converts INTA-D (1-4) to PCIINTA-D (0-3) range.
	** The additional "-1" adjusts for skewing the IRQ<->slot.
	*/
	dino_cfg_read(dev->bus, dev->devfn, PCI_INTERRUPT_PIN, 1, &irq_pin); 
	dev->irq = pci_swizzle_interrupt_pin(dev, irq_pin) - 1;

	/* Shouldn't really need to do this but it's in case someone tries
	** to bypass PCI services and look at the card themselves.
	*/
	dino_cfg_write(dev->bus, dev->devfn, PCI_INTERRUPT_LINE, 1, dev->irq); 
}

/* The alignment contraints for PCI bridges under dino */
#define DINO_BRIDGE_ALIGN 0x100000


static void __init
dino_fixup_bus(struct pci_bus *bus)
{
        struct pci_dev *dev;
        struct dino_device *dino_dev = DINO_DEV(parisc_walk_tree(bus->bridge));

	DBG(KERN_WARNING "%s(0x%px) bus %d platform_data 0x%px\n",
	    __func__, bus, bus->busn_res.start,
	    bus->bridge->platform_data);

	/* Firmware doesn't set up card-mode dino, so we have to */
	if (is_card_dino(&dino_dev->hba.dev->id)) {
		dino_card_setup(bus, dino_dev->hba.base_addr);
	} else if (bus->parent) {
		int i;

		pci_read_bridge_bases(bus);


		for(i = PCI_BRIDGE_RESOURCES; i < PCI_NUM_RESOURCES; i++) {
			if((bus->self->resource[i].flags & 
			    (IORESOURCE_IO | IORESOURCE_MEM)) == 0)

Annotation

Implementation Notes