| /* | 
 |  * Corenet based SoC DS Setup | 
 |  * | 
 |  * Maintained by Kumar Gala (see MAINTAINERS for contact information) | 
 |  * | 
 |  * Copyright 2009-2011 Freescale Semiconductor Inc. | 
 |  * | 
 |  * This program is free software; you can redistribute  it and/or modify it | 
 |  * under  the terms of  the GNU General  Public License as published by the | 
 |  * Free Software Foundation;  either version 2 of the  License, or (at your | 
 |  * option) any later version. | 
 |  */ | 
 |  | 
 | #include <linux/kernel.h> | 
 | #include <linux/pci.h> | 
 | #include <linux/kdev_t.h> | 
 | #include <linux/delay.h> | 
 | #include <linux/interrupt.h> | 
 |  | 
 | #include <asm/time.h> | 
 | #include <asm/machdep.h> | 
 | #include <asm/pci-bridge.h> | 
 | #include <asm/pgtable.h> | 
 | #include <asm/ppc-pci.h> | 
 | #include <mm/mmu_decl.h> | 
 | #include <asm/prom.h> | 
 | #include <asm/udbg.h> | 
 | #include <asm/mpic.h> | 
 | #include <asm/ehv_pic.h> | 
 | #include <asm/qe_ic.h> | 
 |  | 
 | #include <linux/of_platform.h> | 
 | #include <sysdev/fsl_soc.h> | 
 | #include <sysdev/fsl_pci.h> | 
 | #include "smp.h" | 
 | #include "mpc85xx.h" | 
 |  | 
 | void __init corenet_gen_pic_init(void) | 
 | { | 
 | 	struct mpic *mpic; | 
 | 	unsigned int flags = MPIC_BIG_ENDIAN | MPIC_SINGLE_DEST_CPU | | 
 | 		MPIC_NO_RESET; | 
 |  | 
 | 	struct device_node *np; | 
 |  | 
 | 	if (ppc_md.get_irq == mpic_get_coreint_irq) | 
 | 		flags |= MPIC_ENABLE_COREINT; | 
 |  | 
 | 	mpic = mpic_alloc(NULL, 0, flags, 0, 512, " OpenPIC  "); | 
 | 	BUG_ON(mpic == NULL); | 
 |  | 
 | 	mpic_init(mpic); | 
 |  | 
 | 	np = of_find_compatible_node(NULL, NULL, "fsl,qe-ic"); | 
 | 	if (np) { | 
 | 		qe_ic_init(np, 0, qe_ic_cascade_low_mpic, | 
 | 				qe_ic_cascade_high_mpic); | 
 | 		of_node_put(np); | 
 | 	} | 
 | } | 
 |  | 
 | /* | 
 |  * Setup the architecture | 
 |  */ | 
 | void __init corenet_gen_setup_arch(void) | 
 | { | 
 | 	mpc85xx_smp_init(); | 
 |  | 
 | 	swiotlb_detect_4g(); | 
 |  | 
 | #if defined(CONFIG_FSL_PCI) && defined(CONFIG_ZONE_DMA32) | 
 | 	/* | 
 | 	 * Inbound windows don't cover the full lower 4 GiB | 
 | 	 * due to conflicts with PCICSRBAR and outbound windows, | 
 | 	 * so limit the DMA32 zone to 2 GiB, to allow consistent | 
 | 	 * allocations to succeed. | 
 | 	 */ | 
 | 	limit_zone_pfn(ZONE_DMA32, 1UL << (31 - PAGE_SHIFT)); | 
 | #endif | 
 |  | 
 | 	pr_info("%s board\n", ppc_md.name); | 
 |  | 
 | 	mpc85xx_qe_init(); | 
 | } | 
 |  | 
 | static const struct of_device_id of_device_ids[] = { | 
 | 	{ | 
 | 		.compatible	= "simple-bus" | 
 | 	}, | 
 | 	{ | 
 | 		.compatible	= "mdio-mux-gpio" | 
 | 	}, | 
 | 	{ | 
 | 		.compatible	= "fsl,fpga-ngpixis" | 
 | 	}, | 
 | 	{ | 
 | 		.compatible	= "fsl,fpga-qixis" | 
 | 	}, | 
 | 	{ | 
 | 		.compatible	= "fsl,srio", | 
 | 	}, | 
 | 	{ | 
 | 		.compatible	= "fsl,p4080-pcie", | 
 | 	}, | 
 | 	{ | 
 | 		.compatible	= "fsl,qoriq-pcie-v2.2", | 
 | 	}, | 
 | 	{ | 
 | 		.compatible	= "fsl,qoriq-pcie-v2.3", | 
 | 	}, | 
 | 	{ | 
 | 		.compatible	= "fsl,qoriq-pcie-v2.4", | 
 | 	}, | 
 | 	{ | 
 | 		.compatible	= "fsl,qoriq-pcie-v3.0", | 
 | 	}, | 
 | 	{ | 
 | 		.compatible	= "fsl,qe", | 
 | 	}, | 
 | 	{ | 
 | 		.compatible    = "fsl,fman", | 
 | 	}, | 
 | 	/* The following two are for the Freescale hypervisor */ | 
 | 	{ | 
 | 		.name		= "hypervisor", | 
 | 	}, | 
 | 	{ | 
 | 		.name		= "handles", | 
 | 	}, | 
 | 	{} | 
 | }; | 
 |  | 
 | int __init corenet_gen_publish_devices(void) | 
 | { | 
 | 	return of_platform_bus_probe(NULL, of_device_ids, NULL); | 
 | } | 
 |  | 
 | static const char * const boards[] __initconst = { | 
 | 	"fsl,P2041RDB", | 
 | 	"fsl,P3041DS", | 
 | 	"fsl,OCA4080", | 
 | 	"fsl,P4080DS", | 
 | 	"fsl,P5020DS", | 
 | 	"fsl,P5040DS", | 
 | 	"fsl,T2080QDS", | 
 | 	"fsl,T2080RDB", | 
 | 	"fsl,T2081QDS", | 
 | 	"fsl,T4240QDS", | 
 | 	"fsl,T4240RDB", | 
 | 	"fsl,B4860QDS", | 
 | 	"fsl,B4420QDS", | 
 | 	"fsl,B4220QDS", | 
 | 	"fsl,T1040QDS", | 
 | 	"fsl,T1042QDS", | 
 | 	"fsl,T1040RDB", | 
 | 	"fsl,T1042RDB", | 
 | 	"fsl,T1042RDB_PI", | 
 | 	"keymile,kmcoge4", | 
 | 	NULL | 
 | }; | 
 |  | 
 | /* | 
 |  * Called very early, device-tree isn't unflattened | 
 |  */ | 
 | static int __init corenet_generic_probe(void) | 
 | { | 
 | 	unsigned long root = of_get_flat_dt_root(); | 
 | 	char hv_compat[24]; | 
 | 	int i; | 
 | #ifdef CONFIG_SMP | 
 | 	extern struct smp_ops_t smp_85xx_ops; | 
 | #endif | 
 |  | 
 | 	if (of_flat_dt_match(root, boards)) | 
 | 		return 1; | 
 |  | 
 | 	/* Check if we're running under the Freescale hypervisor */ | 
 | 	for (i = 0; boards[i]; i++) { | 
 | 		snprintf(hv_compat, sizeof(hv_compat), "%s-hv", boards[i]); | 
 | 		if (of_flat_dt_is_compatible(root, hv_compat)) { | 
 | 			ppc_md.init_IRQ = ehv_pic_init; | 
 |  | 
 | 			ppc_md.get_irq = ehv_pic_get_irq; | 
 | 			ppc_md.restart = fsl_hv_restart; | 
 | 			pm_power_off = fsl_hv_halt; | 
 | 			ppc_md.halt = fsl_hv_halt; | 
 | #ifdef CONFIG_SMP | 
 | 			/* | 
 | 			 * Disable the timebase sync operations because we | 
 | 			 * can't write to the timebase registers under the | 
 | 			 * hypervisor. | 
 | 			 */ | 
 | 			smp_85xx_ops.give_timebase = NULL; | 
 | 			smp_85xx_ops.take_timebase = NULL; | 
 | #endif | 
 | 			return 1; | 
 | 		} | 
 | 	} | 
 |  | 
 | 	return 0; | 
 | } | 
 |  | 
 | define_machine(corenet_generic) { | 
 | 	.name			= "CoreNet Generic", | 
 | 	.probe			= corenet_generic_probe, | 
 | 	.setup_arch		= corenet_gen_setup_arch, | 
 | 	.init_IRQ		= corenet_gen_pic_init, | 
 | #ifdef CONFIG_PCI | 
 | 	.pcibios_fixup_bus	= fsl_pcibios_fixup_bus, | 
 | 	.pcibios_fixup_phb      = fsl_pcibios_fixup_phb, | 
 | #endif | 
 | 	.get_irq		= mpic_get_coreint_irq, | 
 | 	.restart		= fsl_rstcr_restart, | 
 | 	.calibrate_decr		= generic_calibrate_decr, | 
 | 	.progress		= udbg_progress, | 
 | #ifdef CONFIG_PPC64 | 
 | 	.power_save		= book3e_idle, | 
 | #else | 
 | 	.power_save		= e500_idle, | 
 | #endif | 
 | }; | 
 |  | 
 | machine_arch_initcall(corenet_generic, corenet_gen_publish_devices); | 
 |  | 
 | #ifdef CONFIG_SWIOTLB | 
 | machine_arch_initcall(corenet_generic, swiotlb_setup_bus_notifier); | 
 | #endif |