From 2d1c861871d767153538a77c498752b36d4bb4b8 Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Wed, 9 Dec 2009 17:52:13 +1100 Subject: PCI/cardbus: Add a fixup hook and fix powerpc The cardbus code creates PCI devices without ever going through the necessary fixup bits and pieces that normal PCI devices go through. There's in fact a commented out call to pcibios_fixup_bus() in there, it's commented because ... it doesn't work. I could make pcibios_fixup_bus() do the right thing on powerpc easily but I felt it cleaner instead to provide a specific hook pci_fixup_cardbus for which a weak empty implementation is provided by the PCI core. This fixes cardbus on powerbooks and probably all other PowerPC platforms which was broken completely for ever on some platforms and since 2.6.31 on others such as PowerBooks when we made the DMA ops mandatory (since those are setup by the fixups). Acked-by: Dominik Brodowski Signed-off-by: Benjamin Herrenschmidt Signed-off-by: Jesse Barnes --- arch/powerpc/kernel/pci-common.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'arch/powerpc/kernel') diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c index e8dfdbd9327..cadbed679fb 100644 --- a/arch/powerpc/kernel/pci-common.c +++ b/arch/powerpc/kernel/pci-common.c @@ -1107,6 +1107,12 @@ void __devinit pcibios_setup_bus_devices(struct pci_bus *bus) list_for_each_entry(dev, &bus->devices, bus_list) { struct dev_archdata *sd = &dev->dev.archdata; + /* Cardbus can call us to add new devices to a bus, so ignore + * those who are already fully discovered + */ + if (dev->is_added) + continue; + /* Setup OF node pointer in archdata */ sd->of_node = pci_device_to_OF_node(dev); @@ -1147,6 +1153,13 @@ void __devinit pcibios_fixup_bus(struct pci_bus *bus) } EXPORT_SYMBOL(pcibios_fixup_bus); +void __devinit pci_fixup_cardbus(struct pci_bus *bus) +{ + /* Now fixup devices on that bus */ + pcibios_setup_bus_devices(bus); +} + + static int skip_isa_ioresource_align(struct pci_dev *dev) { if ((ppc_pci_flags & PPC_PCI_CAN_SKIP_ISA_ALIGN) && -- cgit v1.2.3-70-g09d2 From 9f4f04ba2b117a5c741d019629d7ffccdc621122 Mon Sep 17 00:00:00 2001 From: Joakim Tjernlund Date: Tue, 29 Dec 2009 05:10:58 +0000 Subject: powerpc/8xx: Always pin kernel instruction TLB Various kernel asm modifies SRR0/SRR1 just before executing a rfi. If such code crosses a page boundary you risk a TLB miss which will clobber SRR0/SRR1. Avoid this by always pinning kernel instruction TLB space. Signed-off-by: Joakim Tjernlund Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/kernel/head_8xx.S | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'arch/powerpc/kernel') diff --git a/arch/powerpc/kernel/head_8xx.S b/arch/powerpc/kernel/head_8xx.S index 678f98cd5e6..a2ed3422fa3 100644 --- a/arch/powerpc/kernel/head_8xx.S +++ b/arch/powerpc/kernel/head_8xx.S @@ -768,12 +768,12 @@ start_here: */ initial_mmu: tlbia /* Invalidate all TLB entries */ -#ifdef CONFIG_PIN_TLB +/* Always pin the first 8 MB ITLB to prevent ITLB + misses while mucking around with SRR0/SRR1 in asm +*/ lis r8, MI_RSV4I@h ori r8, r8, 0x1c00 -#else - li r8, 0 -#endif + mtspr SPRN_MI_CTR, r8 /* Set instruction MMU control */ #ifdef CONFIG_PIN_TLB -- cgit v1.2.3-70-g09d2 From e443ed35606cf921cbf9d6949010a5b36bbe747d Mon Sep 17 00:00:00 2001 From: Anton Vorontsov Date: Wed, 30 Dec 2009 07:40:17 +0000 Subject: powerpc/swsusp_32: Fix TLB invalidation It seems there is a thinko in the TLB invalidation code that makes the tlbie in the loop executed just once. The intended check was probably 'gt', not 'lt'. Signed-off-by: Anton Vorontsov Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/kernel/swsusp_32.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch/powerpc/kernel') diff --git a/arch/powerpc/kernel/swsusp_32.S b/arch/powerpc/kernel/swsusp_32.S index b47d8ceffb5..b0754e23743 100644 --- a/arch/powerpc/kernel/swsusp_32.S +++ b/arch/powerpc/kernel/swsusp_32.S @@ -303,7 +303,7 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_USE_HIGH_BATS) lis r4,0x1000 1: addic. r4,r4,-0x1000 tlbie r4 - blt 1b + bgt 1b sync /* restore the MSR and turn on the MMU */ -- cgit v1.2.3-70-g09d2 From 3e7b484354c8f60c12119c1c5174ef354696c30d Mon Sep 17 00:00:00 2001 From: Stefan Roese Date: Mon, 11 Jan 2010 22:28:54 +0000 Subject: powerpc: Fix decrementer setup on 1GHz boards We noticed that recent kernels didn't boot on our 1GHz Canyonlands 460EX boards anymore. As it seems, patch 8d165db1 [powerpc: Improve decrementer accuracy] introduced this problem. The routine div_sc() overflows with shift = 32 resulting in this incorrect setup: time_init: decrementer frequency = 1000.000012 MHz time_init: processor frequency = 1000.000012 MHz clocksource: timebase mult[400000] shift[22] registered clockevent: decrementer mult[33] shift[32] cpu[0] This patch now introduces a local div_dc64() version of this function so that this overflow doesn't happen anymore. Signed-off-by: Stefan Roese Cc: Benjamin Herrenschmidt Cc: Detlev Zundel Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/kernel/time.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'arch/powerpc/kernel') diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c index 9ba2cc88591..6c6093d67f3 100644 --- a/arch/powerpc/kernel/time.c +++ b/arch/powerpc/kernel/time.c @@ -903,12 +903,21 @@ static void decrementer_set_mode(enum clock_event_mode mode, decrementer_set_next_event(DECREMENTER_MAX, dev); } +static inline uint64_t div_sc64(unsigned long ticks, unsigned long nsec, + int shift) +{ + uint64_t tmp = ((uint64_t)ticks) << shift; + + do_div(tmp, nsec); + return tmp; +} + static void __init setup_clockevent_multiplier(unsigned long hz) { u64 mult, shift = 32; while (1) { - mult = div_sc(hz, NSEC_PER_SEC, shift); + mult = div_sc64(hz, NSEC_PER_SEC, shift); if (mult && (mult >> 32UL) == 0UL) break; -- cgit v1.2.3-70-g09d2 From 061ec9599f7ea515a3f08cd5cb74a03b2f9c56d2 Mon Sep 17 00:00:00 2001 From: Joakim Tjernlund Date: Fri, 8 Jan 2010 06:46:26 +0000 Subject: powerpc/8xx: Fix user space TLB walk in dcbX fixup The newly added fixup for buggy dcbX insn's has a bug that always trigger a kernel TLB walk so a user space dcbX insn will cause a Kernel Machine Check if it hits DTLB error. Signed-off-by: Joakim Tjernlund Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/kernel/head_8xx.S | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch/powerpc/kernel') diff --git a/arch/powerpc/kernel/head_8xx.S b/arch/powerpc/kernel/head_8xx.S index a2ed3422fa3..3ef743fa5d7 100644 --- a/arch/powerpc/kernel/head_8xx.S +++ b/arch/powerpc/kernel/head_8xx.S @@ -542,11 +542,11 @@ DARFixed:/* Return from dcbx instruction bug workaround, r10 holds value of DAR FixupDAR:/* Entry point for dcbx workaround. */ /* fetch instruction from memory. */ mfspr r10, SPRN_SRR0 + andis. r11, r10, 0x8000 /* Address >= 0x80000000 */ DO_8xx_CPU6(0x3780, r3) mtspr SPRN_MD_EPN, r10 mfspr r11, SPRN_M_TWB /* Get level 1 table entry address */ - cmplwi cr0, r11, 0x0800 - blt- 3f /* Branch if user space */ + beq- 3f /* Branch if user space */ lis r11, (swapper_pg_dir-PAGE_OFFSET)@h ori r11, r11, (swapper_pg_dir-PAGE_OFFSET)@l rlwimi r11, r10, 32-20, 0xffc /* r11 = r11&~0xffc|(r10>>20)&0xffc */ -- cgit v1.2.3-70-g09d2 From 9becd2a0d6a7996669a606b9da33cee6d413acb0 Mon Sep 17 00:00:00 2001 From: Nathan Fontenot Date: Thu, 14 Jan 2010 09:45:58 +0000 Subject: powerpc: Move /proc/ppc64 to /proc/powerpc update It looks like the previous patch sent out to move RTAS and other items from /proc/ppc64 to /proc/powerpc missed a few files needed for RAS and DLPAR functionality. Original Patch here: http://lists.ozlabs.org/pipermail/linuxppc-dev/2009-September/076096.html This patch updates the remaining files to be created under /proc/powerpc. Signed-off-by: Nathan Fontenot Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/kernel/rtas-proc.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'arch/powerpc/kernel') diff --git a/arch/powerpc/kernel/rtas-proc.c b/arch/powerpc/kernel/rtas-proc.c index 1be9fe38bcb..8777fb02349 100644 --- a/arch/powerpc/kernel/rtas-proc.c +++ b/arch/powerpc/kernel/rtas-proc.c @@ -262,19 +262,19 @@ static int __init proc_rtas_init(void) if (rtas_node == NULL) return -ENODEV; - proc_create("ppc64/rtas/progress", S_IRUGO|S_IWUSR, NULL, + proc_create("powerpc/rtas/progress", S_IRUGO|S_IWUSR, NULL, &ppc_rtas_progress_operations); - proc_create("ppc64/rtas/clock", S_IRUGO|S_IWUSR, NULL, + proc_create("powerpc/rtas/clock", S_IRUGO|S_IWUSR, NULL, &ppc_rtas_clock_operations); - proc_create("ppc64/rtas/poweron", S_IWUSR|S_IRUGO, NULL, + proc_create("powerpc/rtas/poweron", S_IWUSR|S_IRUGO, NULL, &ppc_rtas_poweron_operations); - proc_create("ppc64/rtas/sensors", S_IRUGO, NULL, + proc_create("powerpc/rtas/sensors", S_IRUGO, NULL, &ppc_rtas_sensors_operations); - proc_create("ppc64/rtas/frequency", S_IWUSR|S_IRUGO, NULL, + proc_create("powerpc/rtas/frequency", S_IWUSR|S_IRUGO, NULL, &ppc_rtas_tone_freq_operations); - proc_create("ppc64/rtas/volume", S_IWUSR|S_IRUGO, NULL, + proc_create("powerpc/rtas/volume", S_IWUSR|S_IRUGO, NULL, &ppc_rtas_tone_volume_operations); - proc_create("ppc64/rtas/rmo_buffer", S_IRUSR, NULL, + proc_create("powerpc/rtas/rmo_buffer", S_IRUSR, NULL, &ppc_rtas_rmo_buf_ops); return 0; } -- cgit v1.2.3-70-g09d2 From d0174c721900ff807b95ac4ab23191ffcb7511c7 Mon Sep 17 00:00:00 2001 From: Nathan Fontenot Date: Thu, 14 Jan 2010 09:52:44 +0000 Subject: powerpc: Move cpu hotplug driver lock from pseries to powerpc Move the defintion and lock helper routines for the cpu hotplug driver lock from pseries to powerpc code to avoid build breaks for platforms other than pseries that use cpu hotplug. Signed-off-by: Nathan Fontenot Acked-by: Michael Ellerman Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/kernel/smp.c | 12 ++++++++++++ arch/powerpc/platforms/pseries/dlpar.c | 14 -------------- 2 files changed, 12 insertions(+), 14 deletions(-) (limited to 'arch/powerpc/kernel') diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c index a521fb8a40e..c2ee1449807 100644 --- a/arch/powerpc/kernel/smp.c +++ b/arch/powerpc/kernel/smp.c @@ -619,4 +619,16 @@ void __cpu_die(unsigned int cpu) if (smp_ops->cpu_die) smp_ops->cpu_die(cpu); } + +static DEFINE_MUTEX(powerpc_cpu_hotplug_driver_mutex); + +void cpu_hotplug_driver_lock() +{ + mutex_lock(&powerpc_cpu_hotplug_driver_mutex); +} + +void cpu_hotplug_driver_unlock() +{ + mutex_unlock(&powerpc_cpu_hotplug_driver_mutex); +} #endif diff --git a/arch/powerpc/platforms/pseries/dlpar.c b/arch/powerpc/platforms/pseries/dlpar.c index 3bd8df8af70..37bce52526d 100644 --- a/arch/powerpc/platforms/pseries/dlpar.c +++ b/arch/powerpc/platforms/pseries/dlpar.c @@ -346,20 +346,6 @@ int dlpar_release_drc(u32 drc_index) #ifdef CONFIG_ARCH_CPU_PROBE_RELEASE -static DEFINE_MUTEX(pseries_cpu_hotplug_mutex); - -void cpu_hotplug_driver_lock(void) -__acquires(pseries_cpu_hotplug_mutex) -{ - mutex_lock(&pseries_cpu_hotplug_mutex); -} - -void cpu_hotplug_driver_unlock(void) -__releases(pseries_cpu_hotplug_mutex) -{ - mutex_unlock(&pseries_cpu_hotplug_mutex); -} - static int dlpar_online_cpu(struct device_node *dn) { int rc = 0; -- cgit v1.2.3-70-g09d2