static int __init sh7786_pcie_init()

in drivers/pci/pcie-sh7786.c [546:608]


static int __init sh7786_pcie_init(void)
{
	struct clk *platclk;
	u32 mm_sel;
	int i;

	printk(KERN_NOTICE "PCI: Starting initialization.\n");

	sh7786_pcie_hwops = &sh7786_65nm_pcie_hwops;

	nr_ports = sh7786_pcie_hwops->core_init();
	BUG_ON(nr_ports > ARRAY_SIZE(sh7786_pci_channels));

	if (unlikely(nr_ports == 0))
		return -ENODEV;

	sh7786_pcie_ports = kcalloc(nr_ports, sizeof(struct sh7786_pcie_port),
				    GFP_KERNEL);
	if (unlikely(!sh7786_pcie_ports))
		return -ENOMEM;

	/*
	 * Fetch any optional platform clock associated with this block.
	 *
	 * This is a rather nasty hack for boards with spec-mocking FPGAs
	 * that have a secondary set of clocks outside of the on-chip
	 * ones that need to be accounted for before there is any chance
	 * of touching the existing MSTP bits or CPG clocks.
	 */
	platclk = clk_get(NULL, "pcie_plat_clk");
	if (IS_ERR(platclk)) {
		/* Sane hardware should probably get a WARN_ON.. */
		platclk = NULL;
	}

	clk_enable(platclk);

	mm_sel = sh7786_mm_sel();

	/*
	 * Depending on the MMSELR register value, the PCIe0 MEM 1
	 * area may not be available. See Table 13.11 of the SH7786
	 * datasheet.
	 */
	if (mm_sel != 1 && mm_sel != 2 && mm_sel != 5 && mm_sel != 6)
		sh7786_pci0_resources[2].flags |= IORESOURCE_DISABLED;

	printk(KERN_NOTICE "PCI: probing %d ports.\n", nr_ports);

	for (i = 0; i < nr_ports; i++) {
		struct sh7786_pcie_port *port = sh7786_pcie_ports + i;

		port->index		= i;
		port->hose		= sh7786_pci_channels + i;
		port->hose->io_map_base	= port->hose->resources[0].start;

		async_schedule(sh7786_pcie_hwops->port_init_hw, port);
	}

	async_synchronize_full();

	return 0;
}