diff options
Diffstat (limited to 'arch/powerpc/platforms/powernv')
| -rw-r--r-- | arch/powerpc/platforms/powernv/pci-ioda.c | 41 | ||||
| -rw-r--r-- | arch/powerpc/platforms/powernv/smp.c | 10 | 
2 files changed, 41 insertions, 10 deletions
diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c index 9cda6a1ad0c..0e7eccc0f88 100644 --- a/arch/powerpc/platforms/powernv/pci-ioda.c +++ b/arch/powerpc/platforms/powernv/pci-ioda.c @@ -855,7 +855,7 @@ static void __devinit pnv_ioda_setup_PEs(struct pci_bus *bus)  		if (pe == NULL)  			continue;  		/* Leaving the PCIe domain ... single PE# */ -		if (dev->pcie_type == PCI_EXP_TYPE_PCI_BRIDGE) +		if (pci_pcie_type(dev) == PCI_EXP_TYPE_PCI_BRIDGE)  			pnv_ioda_setup_bus_PE(dev, pe);  		else if (dev->subordinate)  			pnv_ioda_setup_PEs(dev->subordinate); @@ -1139,6 +1139,44 @@ static void __devinit pnv_pci_ioda_fixup_phb(struct pci_controller *hose)  	}  } +/* + * Returns the alignment for I/O or memory windows for P2P + * bridges. That actually depends on how PEs are segmented. + * For now, we return I/O or M32 segment size for PE sensitive + * P2P bridges. Otherwise, the default values (4KiB for I/O, + * 1MiB for memory) will be returned. + * + * The current PCI bus might be put into one PE, which was + * create against the parent PCI bridge. For that case, we + * needn't enlarge the alignment so that we can save some + * resources. + */ +static resource_size_t pnv_pci_window_alignment(struct pci_bus *bus, +						unsigned long type) +{ +	struct pci_dev *bridge; +	struct pci_controller *hose = pci_bus_to_host(bus); +	struct pnv_phb *phb = hose->private_data; +	int num_pci_bridges = 0; + +	bridge = bus->self; +	while (bridge) { +		if (pci_pcie_type(bridge) == PCI_EXP_TYPE_PCI_BRIDGE) { +			num_pci_bridges++; +			if (num_pci_bridges >= 2) +				return 1; +		} + +		bridge = bridge->bus->self; +	} + +	/* We need support prefetchable memory window later */ +	if (type & IORESOURCE_MEM) +		return phb->ioda.m32_segsize; + +	return phb->ioda.io_segsize; +} +  /* Prevent enabling devices for which we couldn't properly   * assign a PE   */ @@ -1306,6 +1344,7 @@ void __init pnv_pci_init_ioda1_phb(struct device_node *np)  	 */  	ppc_md.pcibios_fixup_phb = pnv_pci_ioda_fixup_phb;  	ppc_md.pcibios_enable_device_hook = pnv_pci_enable_device_hook; +	ppc_md.pcibios_window_alignment = pnv_pci_window_alignment;  	pci_add_flags(PCI_PROBE_ONLY | PCI_REASSIGN_ALL_RSRC);  	/* Reset IODA tables to a clean state */ diff --git a/arch/powerpc/platforms/powernv/smp.c b/arch/powerpc/platforms/powernv/smp.c index 3ef46254c35..7698b6e13c5 100644 --- a/arch/powerpc/platforms/powernv/smp.c +++ b/arch/powerpc/platforms/powernv/smp.c @@ -106,14 +106,6 @@ static void pnv_smp_cpu_kill_self(void)  {  	unsigned int cpu; -	/* If powersave_nap is enabled, use NAP mode, else just -	 * spin aimlessly -	 */ -	if (!powersave_nap) { -		generic_mach_cpu_die(); -		return; -	} -  	/* Standard hot unplug procedure */  	local_irq_disable();  	idle_task_exit(); @@ -128,7 +120,7 @@ static void pnv_smp_cpu_kill_self(void)  	 */  	mtspr(SPRN_LPCR, mfspr(SPRN_LPCR) & ~(u64)LPCR_PECE1);  	while (!generic_check_cpu_restart(cpu)) { -		power7_idle(); +		power7_nap();  		if (!generic_check_cpu_restart(cpu)) {  			DBG("CPU%d Unexpected exit while offline !\n", cpu);  			/* We may be getting an IPI, so we re-enable  |