示例#1
0
static int __init
hdpu_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin)
{
	struct pci_controller *hose = pci_bus_to_hose(dev->bus->number);

	if (hose->index == 0) {
		static char pci_irq_table[][4] = {
			{HDPU_PCI_0_IRQ, 0, 0, 0},
			{HDPU_PCI_0_IRQ, 0, 0, 0},
		};

		const long min_idsel = 1, max_idsel = 2, irqs_per_slot = 4;
		return PCI_IRQ_TABLE_LOOKUP;
	} else {
		static char pci_irq_table[][4] = {
			{HDPU_PCI_1_IRQ, 0, 0, 0},
		};

		const long min_idsel = 1, max_idsel = 1, irqs_per_slot = 4;
		return PCI_IRQ_TABLE_LOOKUP;
	}
}
int fdtdec_get_pci_bar32(const void *blob, int node,
		struct fdt_pci_addr *addr, u32 *bar)
{
	pci_dev_t bdf;
	int barnum;
	int ret;

	/* get pci devices's bdf */
	ret = fdtdec_get_pci_bdf(blob, node, addr, &bdf);
	if (ret)
		return ret;

	/* extract the bar number from fdt_pci_addr */
	barnum = addr->phys_hi & 0xff;
	if ((barnum < PCI_BASE_ADDRESS_0) || (barnum > PCI_CARDBUS_CIS))
		return -EINVAL;

	barnum = (barnum - PCI_BASE_ADDRESS_0) / 4;
	*bar = pci_read_bar32(pci_bus_to_hose(PCI_BUS(bdf)), bdf, barnum);

	return 0;
}
示例#3
0
/*
 * Subroutine:  pciinfo
 *
 * Description: Show information about devices on PCI bus.
 *				Depending on the define CONFIG_SYS_SHORT_PCI_LISTING
 *				the output will be more or less exhaustive.
 *
 * Inputs:	bus_no		the number of the bus to be scanned.
 *
 * Return:      None
 *
 */
void pciinfo(int BusNum, int ShortPCIListing)
{
	struct pci_controller *hose = pci_bus_to_hose(BusNum);
	int Device;
	int Function;
	unsigned char HeaderType;
	unsigned short VendorID;
	pci_dev_t dev;
	int ret;

	if (!hose)
		return;

	printf("Scanning PCI devices on bus %d\n", BusNum);

	if (ShortPCIListing) {
		printf("BusDevFun  VendorId   DeviceId   Device Class       Sub-Class\n");
		printf("_____________________________________________________________\n");
	}

	for (Device = 0; Device < PCI_MAX_PCI_DEVICES; Device++) {
		HeaderType = 0;
		VendorID = 0;
		for (Function = 0; Function < PCI_MAX_PCI_FUNCTIONS; Function++) {
			/*
			 * If this is not a multi-function device, we skip the rest.
			 */
			if (Function && !(HeaderType & 0x80))
				break;

			dev = PCI_BDF(BusNum, Device, Function);

			if (pci_skip_dev(hose, dev))
				continue;

			ret = pci_read_config_word(dev, PCI_VENDOR_ID,
						   &VendorID);
			if (ret)
				goto error;
			if ((VendorID == 0xFFFF) || (VendorID == 0x0000))
				continue;

			if (!Function) pci_read_config_byte(dev, PCI_HEADER_TYPE, &HeaderType);

			if (ShortPCIListing)
			{
				printf("%02x.%02x.%02x   ", BusNum, Device, Function);
				pci_header_show_brief(dev);
			}
			else
			{
				printf("\nFound PCI device %02x.%02x.%02x:\n",
				       BusNum, Device, Function);
				pci_header_show(dev);
			}
		}
	}

	return;
error:
	printf("Cannot read bus configuration: %d\n", ret);
}
示例#4
0
文件: pplus.c 项目: 1x23/unifi-gpl
static void __init pplus_setup_arch(void)
{
	struct pci_controller *hose;

	if (ppc_md.progress)
		ppc_md.progress("pplus_setup_arch: enter", 0);

	/* init to some ~sane value until calibrate_delay() runs */
	loops_per_jiffy = 50000000;

	if (ppc_md.progress)
		ppc_md.progress("pplus_setup_arch: find_bridges", 0);

	/* Setup PCI host bridge */
	pplus_find_bridges();

	hose = pci_bus_to_hose(0);
	isa_io_base = (ulong) hose->io_base_virt;

	if (ppc_md.progress)
		ppc_md.progress("pplus_setup_arch: set_board_type", 0);

	pplus_set_board_type();

	/* Enable L2.  Assume we don't need to flush -- Cort */
	*(unsigned char *)(PPLUS_L2_CONTROL_REG) |= 3;

#ifdef CONFIG_BLK_DEV_INITRD
	if (initrd_start)
		ROOT_DEV = Root_RAM0;
	else
#endif
#ifdef CONFIG_ROOT_NFS
		ROOT_DEV = Root_NFS;
#else
		ROOT_DEV = Root_SDA2;
#endif

	printk(KERN_INFO "Motorola PowerPlus Platform\n");
	printk(KERN_INFO
	       "Port by MontaVista Software, Inc. ([email protected])\n");

#ifdef CONFIG_VGA_CONSOLE
	/* remap the VGA memory */
	vgacon_remap_base = (unsigned long)ioremap(PPLUS_ISA_MEM_BASE,
						   0x08000000);
	conswitchp = &vga_con;
#endif
#ifdef CONFIG_PPCBUG_NVRAM
	/* Read in NVRAM data */
	init_prep_nvram();

	/* if no bootargs, look in NVRAM */
	if (cmd_line[0] == '\0') {
		char *bootargs;
		bootargs = prep_nvram_get_var("bootargs");
		if (bootargs != NULL) {
			strcpy(cmd_line, bootargs);
			/* again.. */
			strcpy(saved_command_line, cmd_line);
		}
	}
#endif
	if (ppc_md.progress)
		ppc_md.progress("pplus_setup_arch: exit", 0);
}
示例#5
0
static inline int __init
adir_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin)
{
#define	PCIIRQ(a,b,c,d)	{ADIR_IRQ_##a,ADIR_IRQ_##b,ADIR_IRQ_##c,ADIR_IRQ_##d},
	struct pci_controller *hose = pci_bus_to_hose(dev->bus->number);
	/*
	 * The three PCI devices on the motherboard have dedicated lines to the
	 * CPLD interrupt controller, bypassing the standard PCI INTA-D and the
	 * PC interrupt controller. All other PCI devices (slots) have usual
	 * staggered INTA-D lines, resulting in 8 lines total (PCI0 INTA-D and
	 * PCI1 INTA-D). All 8 go to the CPLD interrupt controller. PCI0 INTA-D
	 * also go to the south bridge, so we have the option of taking them
	 * via the CPLD interrupt controller or via the south bridge 8259
	 * 8258 thingy. PCI1 INTA-D can only be taken via the CPLD interrupt
	 * controller. We take all PCI interrupts via the CPLD interrupt
	 * controller as recommended by SBS.
	 *
	 * We also have some monkey business with the PCI devices within the
	 * VT82C686B south bridge itself. This chip actually has 7 functions on
	 * its IDSEL. Function 0 is the actual south bridge, function 1 is IDE,
	 * and function 4 is some special stuff. The other 4 functions are just
	 * regular PCI devices bundled in the chip. 2 and 3 are USB UHCIs and 5
	 * and 6 are audio (not supported on the Adirondack).
	 *
	 * This is where the monkey business begins. PCI devices are supposed
	 * to signal normal PCI interrupts. But the 4 functions in question are
	 * located in the south bridge chip, which is designed with the
	 * assumption that it will be fielding PCI INTA-D interrupts rather
	 * than generating them. Here's what it does. Each of the functions in
	 * question routes its interrupt to one of the IRQs on the 8259 thingy.
	 * Which one? It looks at the Interrupt Line register in the PCI config
	 * space, even though the PCI spec says it's for BIOS/OS interaction
	 * only.
	 *
	 * How do we deal with this? We take these interrupts via 8259 IRQs as
	 * we have to. We return the desired IRQ numbers from this routine when
	 * called for the functions in question. The PCI scan code will then
	 * stick our return value into the Interrupt Line register in the PCI
	 * config space, and the interrupt will actually go there. We identify
	 * these functions within the south bridge IDSEL by their interrupt pin
	 * numbers, as the VT82C686B has 04 in the Interrupt Pin register for
	 * USB and 03 for audio.
	 */
	if (!hose->index) {
		static char pci_irq_table[][4] =
		/*
		 *             PCI IDSEL/INTPIN->INTLINE 
		 *             A          B          C          D
		 */
		{
    /* south bridge */	PCIIRQ(IDE0,      NONE,      VIA_AUDIO, VIA_USB)
    /* Ethernet 0 */	PCIIRQ(MBETH0,    MBETH0,    MBETH0,    MBETH0)
    /* PCI0 slot 1 */	PCIIRQ(PCI0_INTB, PCI0_INTC, PCI0_INTD, PCI0_INTA)
    /* PCI0 slot 2 */	PCIIRQ(PCI0_INTC, PCI0_INTD, PCI0_INTA, PCI0_INTB)
    /* PCI0 slot 3 */	PCIIRQ(PCI0_INTD, PCI0_INTA, PCI0_INTB, PCI0_INTC)
		};
		const long min_idsel = 3, max_idsel = 7, irqs_per_slot = 4;
		return PCI_IRQ_TABLE_LOOKUP;
	} else {
		static char pci_irq_table[][4] =
		/*
		 *             PCI IDSEL/INTPIN->INTLINE 
		 *             A          B          C          D
		 */
		{
    /* Ethernet 1 */	PCIIRQ(MBETH1,    MBETH1,    MBETH1,    MBETH1)
    /* SCSI */		PCIIRQ(MBSCSI,    MBSCSI,    MBSCSI,    MBSCSI)
    /* PCI1 slot 1 */	PCIIRQ(PCI1_INTB, PCI1_INTC, PCI1_INTD, PCI1_INTA)
    /* PCI1 slot 2 */	PCIIRQ(PCI1_INTC, PCI1_INTD, PCI1_INTA, PCI1_INTB)
    /* PCI1 slot 3 */	PCIIRQ(PCI1_INTD, PCI1_INTA, PCI1_INTB, PCI1_INTC)
		};
		const long min_idsel = 3, max_idsel = 7, irqs_per_slot = 4;
		return PCI_IRQ_TABLE_LOOKUP;
	}
#undef PCIIRQ
}