RE: [4/4] powerpc/85xx: Update mpc85xx_defconfig for C293PCIE
-Original Message- From: Wood Scott-B07421 Sent: Tuesday, July 23, 2013 7:00 AM To: Liu Po-B43644 Cc: linuxppc-...@ozlabs.org; Hu Mingkai-B21284 Subject: Re: [4/4] powerpc/85xx: Update mpc85xx_defconfig for C293PCIE On Thu, Apr 25, 2013 at 09:54:17AM +0800, Po Liu wrote: From: Mingkai Hu mingkai...@freescale.com Signed-off-by: Mingkai Hu mingkai...@freescale.com --- Base on git://git.am.freescale.net/gitolite/mirrors/linux-2.6.git arch/powerpc/configs/mpc85xx_defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/powerpc/configs/mpc85xx_defconfig b/arch/powerpc/configs/mpc85xx_defconfig index cf815e8..ddc33a2 100644 --- a/arch/powerpc/configs/mpc85xx_defconfig +++ b/arch/powerpc/configs/mpc85xx_defconfig @@ -28,6 +28,7 @@ CONFIG_MPC85xx_MDS=y CONFIG_MPC8536_DS=y CONFIG_MPC85xx_DS=y CONFIG_MPC85xx_RDB=y +CONFIG_C293_PCIE=y CONFIG_P1010_RDB=y CONFIG_P1022_DS=y CONFIG_P1022_RDK=y Also, why only mpc85xx_defconfig and mpc85xx_smp_defconfig? Just because this board isn't SMP doesn't mean it can't be supported by an SMP kernel. Action: I will add configure to mpc85xx_smp_defconfig. And merge it to Add-C293PCIE-board-support.patch. -Scott ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
RE: [3/4] powerpc/85xx: Add C293PCIE board support
-Original Message- From: Wood Scott-B07421 Sent: Tuesday, July 23, 2013 6:59 AM To: Liu Po-B43644 Cc: linuxppc-...@ozlabs.org; Hu Mingkai-B21284 Subject: Re: [3/4] powerpc/85xx: Add C293PCIE board support On Thu, Apr 25, 2013 at 09:54:16AM +0800, Po Liu wrote: From: Mingkai Hu mingkai...@freescale.com C293PCIE board is a series of Freescale PCIe add-in cards to perform as public key crypto accelerator or secure key management module. - 512KB platform SRAM in addition to 512K L2 Cache/SRAM - 512MB soldered DDR3 32bit memory - CPLD System Logic - 64MB x16 NOR flash and 4GB x8 NAND flash - 16MB SPI flash Signed-off-by: Mingkai Hu mingkai...@freescale.com Singed-off-by: Po Liu po@freescale.com Signed + partition@90 { + /* 33MB for rootfs */ + reg = 0x0090 0x0210; + label = NOR Rootfs Image; + }; + + partition@2a0 { + /* 20MB for JFFS2 based Root file System */ + reg = 0x02a0 0x0140; + label = NOR JFFS2 Root File System; + }; Don't specify JFFS2. Combine these two partitions into one. Ok, I'll merge up two partition. + partition@60 { + /* 4MB for Compressed Root file System Image */ + reg = 0x0060 0x0040; + label = NAND Compressed RFS Image; + }; + + partition@a0 { + /* 15MB for JFFS2 based Root file System */ + reg = 0x00a0 0x00f0; + label = NAND JFFS2 Root File System; + }; Likewise. + partition@190 { + /* 7MB for User Area */ + reg = 0x0190 0x0070; + label = NAND User area; + }; Above you say there's 4 GiB of NAND, but here you define partitions that only cover 32 MiB. Can I set one partion include all other space(4GB- 32MB) with label name Others? + }; + + cpld@2,0 { + #address-cells = 1; + #size-cells = 1; + compatible = fsl,c293pcie-cpld; + reg = 0x2 0x0 0x020; + bank-width = 1; + device-width = 1; + }; What do bank-width and device-width mean here? I will remove these two lines? I thought I copy from other platform. Why all the leading zeroes in 0x020? I'll change to 0x20 from 0x020. + partition@58 { + /* 4MB for Compressed RFS Image */ + reg = 0x0058 0x0040; + label = SPI Flash Compressed RFSImage; + }; + + partition@98 { + /* 6.5MB for JFFS2 based RFS */ + reg = 0x0098 0x0068; + label = SPI Flash JFFS2 RFS; + }; Again, merge these two and don't specify JFFS2. Ok, thanks diff --git a/arch/powerpc/platforms/85xx/Kconfig b/arch/powerpc/platforms/85xx/Kconfig index a0dcd57..df26b21 100644 --- a/arch/powerpc/platforms/85xx/Kconfig +++ b/arch/powerpc/platforms/85xx/Kconfig @@ -32,6 +32,13 @@ config BSC9131_RDB StarCore SC3850 DSP Manufacturer : Freescale Semiconductor, Inc +config C293_PCIE +bool Freescale C293PCIE +select DEFAULT_UIMAGE +select SWIOTLB +help +This option enables support for the C293PCIE board Why do you need SWIOTLB if the board has 512 MiB soldered RAM? I'll remove it. diff --git a/arch/powerpc/platforms/85xx/c293pcie.c b/arch/powerpc/platforms/85xx/c293pcie.c new file mode 100644 index 000..75dda12 --- /dev/null +++ b/arch/powerpc/platforms/85xx/c293pcie.c @@ -0,0 +1,82 @@ +/* + * C293PCIE Board Setup + * + * Copyright 2013 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/stddef.h +#include linux/kernel.h +#include linux/pci.h +#include linux/delay.h +#include linux/interrupt.h +#include linux/of_platform.h + +#include asm/time.h +#include asm/machdep.h +#include asm/pci-bridge.h +#include mm/mmu_decl.h +#include asm/prom.h +#include asm/udbg.h +#include asm/mpic.h + +#include sysdev/fsl_soc.h +#include sysdev/fsl_pci.h + +#include mpc85xx.h Are you sure you need all of these? I don't see any delays, for example. Thanks, I'll test and
Re: [PATCH] hashtable: add hash_for_each_possible_rcu_notrace()
On Mon, 2013-07-22 at 19:53 -0700, Joe Perches wrote: Anyway, you cc'd all the right people already. If no one responds after a couple weeks, either send it to Jiri or directly to Linus. Or I'll just merge it with the rest of the series. Cheers, Ben. ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
RE: [1/4] powerpc/85xx: Add SEC6.0 device tree
-Original Message- From: Wood Scott-B07421 Sent: Tuesday, July 23, 2013 6:41 AM To: Liu Po-B43644 Cc: linuxppc-...@ozlabs.org; Hu Mingkai-B21284 Subject: Re: [1/4] powerpc/85xx: Add SEC6.0 device tree On Thu, Apr 25, 2013 at 09:54:14AM +0800, Po Liu wrote: From: Mingkai Hu mingkai...@freescale.com Add device tree for SEC 6.0 used on C29x silicon. Signed-off-by: Mingkai Hu mingkai...@freescale.com Singed-off-by: Po Liu po@freescale.com I've heard of patches being flamed, but here we want signing, not singeing. :-) Don't forget that you can use the -s option to have git add the signoff for you. --- Base on git://git.am.freescale.net/gitolite/mirrors/linux-2.6.git This URL is not accessible outside Freescale, so don't reference it when posting patches publicly. If your patch is against the latest upstream code, you don't need to say anything special about that. You only need to make a note when it's against some other yet-to-be-merged tree or patch. + compatible = fsl,sec-v6.0, fsl,sec-v5.2, + fsl,sec-v5.0, fsl,sec-v4.4, + fsl,sec-v4.0; + fsl,sec-era = 6; + #address-cells = 1; + #size-cells = 1; + + jr@1000 { + compatible = fsl,sec-v6.0-job-ring, + fsl,sec-v5.2-job-ring, + fsl,sec-v5.0-job-ring, + fsl,sec-v4.4-job-ring, + fsl,sec-v4.0-job-ring; + reg= 0x1000 0x1000; + }; + + jr@2000 { + compatible = fsl,sec-v6.0-job-ring, + fsl,sec-v5.2-job-ring, + fsl,sec-v5.0-job-ring, + fsl,sec-v4.4-job-ring, + fsl,sec-v4.0-job-ring; + reg= 0x2000 0x1000; + }; You claim compatibility with a bunch of prior SECs, but sec-v5.2 has four job rings and an rtic node. Likewise for the previous compatibles listed. This has two job rings and no rtic. So, shall I remove fsl,sec-v5.2,fsl,sec-v5.0, fsl,sec-v4.4, fsl,sec-v4.0 since all other SEC with 4 job rings? and only leave fsl,sec-v6.0? Can you point to where in the SEC v4.0 binding (I don't see a binding for the subsequent versions), it says that these are optional? I found SEC V4.0 in file qoriq-sec4.0-0.dtsi. If fsl,sec-v4.0 not in the compatible list, it is no use in this compatible list. But seems keep the fsl,sec-v4.0-job-ring job ring compatible is ok. Is that what you were ask? -Scott ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH] powerpc/perf: Export PERF_EVENT_CONFIG_EBB_SHIFT to userspace
We use bit 63 of the event code for userspace to request that the event be counted using EBB (Event Based Branches). Export this value, making it part of the API - though only on processors that support EBB. Signed-off-by: Michael Ellerman mich...@ellerman.id.au --- arch/powerpc/include/asm/perf_event_server.h | 6 +- arch/powerpc/include/uapi/asm/Kbuild | 1 + arch/powerpc/include/uapi/asm/perf_event.h | 18 ++ arch/powerpc/perf/core-book3s.c | 2 +- arch/powerpc/perf/power8-pmu.c | 6 +++--- 5 files changed, 24 insertions(+), 9 deletions(-) create mode 100644 arch/powerpc/include/uapi/asm/perf_event.h diff --git a/arch/powerpc/include/asm/perf_event_server.h b/arch/powerpc/include/asm/perf_event_server.h index 2dd7bfc..8b24926 100644 --- a/arch/powerpc/include/asm/perf_event_server.h +++ b/arch/powerpc/include/asm/perf_event_server.h @@ -12,6 +12,7 @@ #include linux/types.h #include asm/hw_irq.h #include linux/device.h +#include uapi/asm/perf_event.h #define MAX_HWEVENTS 8 #define MAX_EVENT_ALTERNATIVES 8 @@ -69,11 +70,6 @@ struct power_pmu { #define PPMU_LIMITED_PMC_REQD 2 /* have to put this on a limited PMC */ #define PPMU_ONLY_COUNT_RUN4 /* only counting in run state */ -/* - * We use the event config bit 63 as a flag to request EBB. - */ -#define EVENT_CONFIG_EBB_SHIFT 63 - extern int register_power_pmu(struct power_pmu *); struct pt_regs; diff --git a/arch/powerpc/include/uapi/asm/Kbuild b/arch/powerpc/include/uapi/asm/Kbuild index 5182c86..48be855 100644 --- a/arch/powerpc/include/uapi/asm/Kbuild +++ b/arch/powerpc/include/uapi/asm/Kbuild @@ -20,6 +20,7 @@ header-y += mman.h header-y += msgbuf.h header-y += nvram.h header-y += param.h +header-y += perf_event.h header-y += poll.h header-y += posix_types.h header-y += ps3fb.h diff --git a/arch/powerpc/include/uapi/asm/perf_event.h b/arch/powerpc/include/uapi/asm/perf_event.h new file mode 100644 index 000..80a4d40 --- /dev/null +++ b/arch/powerpc/include/uapi/asm/perf_event.h @@ -0,0 +1,18 @@ +/* + * Copyright 2013 Michael Ellerman, IBM Corp. + * + * 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; version 2 of the + * License. + */ + +#ifndef _UAPI_ASM_POWERPC_PERF_EVENT_H +#define _UAPI_ASM_POWERPC_PERF_EVENT_H + +/* + * We use bit 63 of perf_event_attr.config as a flag to request EBB. + */ +#define PERF_EVENT_CONFIG_EBB_SHIFT63 + +#endif /* _UAPI_ASM_POWERPC_PERF_EVENT_H */ diff --git a/arch/powerpc/perf/core-book3s.c b/arch/powerpc/perf/core-book3s.c index a3985ae..2981f73 100644 --- a/arch/powerpc/perf/core-book3s.c +++ b/arch/powerpc/perf/core-book3s.c @@ -484,7 +484,7 @@ static bool is_ebb_event(struct perf_event *event) * use bit 63 of the event code for something else if they wish. */ return (ppmu-flags PPMU_EBB) - ((event-attr.config EVENT_CONFIG_EBB_SHIFT) 1); + ((event-attr.config PERF_EVENT_CONFIG_EBB_SHIFT) 1); } static int ebb_event_check(struct perf_event *event) diff --git a/arch/powerpc/perf/power8-pmu.c b/arch/powerpc/perf/power8-pmu.c index 96a64d6..5b49e78 100644 --- a/arch/powerpc/perf/power8-pmu.c +++ b/arch/powerpc/perf/power8-pmu.c @@ -118,7 +118,7 @@ (EVENT_UNIT_MASK EVENT_UNIT_SHIFT) | \ (EVENT_COMBINE_MASKEVENT_COMBINE_SHIFT) | \ (EVENT_MARKED_MASK EVENT_MARKED_SHIFT) | \ -(EVENT_EBB_MASKEVENT_CONFIG_EBB_SHIFT) | \ +(EVENT_EBB_MASKPERF_EVENT_CONFIG_EBB_SHIFT) | \ EVENT_PSEL_MASK) /* MMCRA IFM bits - POWER8 */ @@ -233,10 +233,10 @@ static int power8_get_constraint(u64 event, unsigned long *maskp, unsigned long pmc = (event EVENT_PMC_SHIFT) EVENT_PMC_MASK; unit = (event EVENT_UNIT_SHIFT)EVENT_UNIT_MASK; cache = (event EVENT_CACHE_SEL_SHIFT) EVENT_CACHE_SEL_MASK; - ebb = (event EVENT_CONFIG_EBB_SHIFT) EVENT_EBB_MASK; + ebb = (event PERF_EVENT_CONFIG_EBB_SHIFT) EVENT_EBB_MASK; /* Clear the EBB bit in the event, so event checks work below */ - event = ~(EVENT_EBB_MASK EVENT_CONFIG_EBB_SHIFT); + event = ~(EVENT_EBB_MASK PERF_EVENT_CONFIG_EBB_SHIFT); if (pmc) { if (pmc 6) -- 1.8.1.2 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 0/3] cpuidle: (powernv) cpuidle driver.
Following patch series ports the cpuidle framework for powernv platform and also implements a cpuidle back-end powernv idle driver calling on to power7_nap and snooze idle states. Moving the idle states over to cpuidle framework can take advantage of advanced heuristics, tunables and features provided by cpuidle framework. Additional idle states can be exploited using the cpuidle framework. The statistics and tracing infrastructure provided by the cpuidle framework also helps in enabling power management related tools and help tune the system and applications. This series aims to maintain compatibility and functionality to existing powernv idle cpu management code. There are no new functions or idle states added as part of this series. This can be extended by adding more states to this existing framework. With this patch series the powernv cpuidle functionalities are on-par with pSeries idle management. For POWERNV platform to hook into CPUIDLE framework, one needs to enable CONFIG_POWERNV_IDLE and disable CONFIG_PSERIES_IDLE Deepthi Dharwar (3): cpuidle/powernv: cpuidle backend driver for powernv cpuidle/powernv: Enable idle powernv cpu to call into the cpuidle framework. cpuidle/powernv: Support smt-snooze-delay parameter in powernv idle. arch/powerpc/include/asm/processor.h|2 arch/powerpc/platforms/powernv/Kconfig |9 + arch/powerpc/platforms/powernv/Makefile |1 arch/powerpc/platforms/powernv/powernv.h|3 arch/powerpc/platforms/powernv/processor_idle.c | 275 +++ arch/powerpc/platforms/powernv/setup.c | 12 + 6 files changed, 300 insertions(+), 2 deletions(-) create mode 100644 arch/powerpc/platforms/powernv/processor_idle.c -- Deepthi ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 1/3] cpuidle/powernv: cpuidle backend driver for powernv
This patch implements a back-end cpuidle driver for powernv calling power7_nap and snooze idle states. This can be extended by adding more idle states in the future to the existing framework. Signed-off-by: Deepthi Dharwar deep...@linux.vnet.ibm.com --- arch/powerpc/platforms/powernv/Kconfig |9 + arch/powerpc/platforms/powernv/Makefile |1 arch/powerpc/platforms/powernv/processor_idle.c | 239 +++ 3 files changed, 249 insertions(+) create mode 100644 arch/powerpc/platforms/powernv/processor_idle.c diff --git a/arch/powerpc/platforms/powernv/Kconfig b/arch/powerpc/platforms/powernv/Kconfig index c24684c..ace2d22 100644 --- a/arch/powerpc/platforms/powernv/Kconfig +++ b/arch/powerpc/platforms/powernv/Kconfig @@ -20,3 +20,12 @@ config PPC_POWERNV_RTAS default y select PPC_ICS_RTAS select PPC_RTAS + +config POWERNV_IDLE + bool CPUIdle driver for powernv platform + depends on CPU_IDLE + depends on PPC_POWERNV + default y + help + Select this option to enable processor idle state management + through cpuidle subsystem. diff --git a/arch/powerpc/platforms/powernv/Makefile b/arch/powerpc/platforms/powernv/Makefile index 7fe5951..c0e44eb 100644 --- a/arch/powerpc/platforms/powernv/Makefile +++ b/arch/powerpc/platforms/powernv/Makefile @@ -4,3 +4,4 @@ obj-y += opal-rtc.o opal-nvram.o obj-$(CONFIG_SMP) += smp.o obj-$(CONFIG_PCI) += pci.o pci-p5ioc2.o pci-ioda.o obj-$(CONFIG_EEH) += eeh-ioda.o eeh-powernv.o +obj-$(CONFIG_POWERNV_IDLE) += processor_idle.o diff --git a/arch/powerpc/platforms/powernv/processor_idle.c b/arch/powerpc/platforms/powernv/processor_idle.c new file mode 100644 index 000..f43ad91a --- /dev/null +++ b/arch/powerpc/platforms/powernv/processor_idle.c @@ -0,0 +1,239 @@ +/* + * processor_idle - idle state cpuidle driver. + */ + +#include linux/kernel.h +#include linux/module.h +#include linux/init.h +#include linux/moduleparam.h +#include linux/cpuidle.h +#include linux/cpu.h +#include linux/notifier.h + +#include asm/machdep.h +#include asm/runlatch.h + +struct cpuidle_driver powernv_idle_driver = { + .name = powernv_idle, + .owner =THIS_MODULE, +}; + +#define MAX_IDLE_STATE_COUNT 2 + +static int max_idle_state = MAX_IDLE_STATE_COUNT - 1; +static struct cpuidle_device __percpu *powernv_cpuidle_devices; +static struct cpuidle_state *cpuidle_state_table; + +static int snooze_loop(struct cpuidle_device *dev, + struct cpuidle_driver *drv, + int index) +{ + int cpu = dev-cpu; + + local_irq_enable(); + set_thread_flag(TIF_POLLING_NRFLAG); + + while ((!need_resched()) cpu_online(cpu)) { + ppc64_runlatch_off(); + HMT_very_low(); + } + + HMT_medium(); + clear_thread_flag(TIF_POLLING_NRFLAG); + smp_mb(); + return index; +} + + +static int nap_loop(struct cpuidle_device *dev, + struct cpuidle_driver *drv, + int index) +{ + ppc64_runlatch_off(); + power7_idle(); + return index; +} + +/* + * States for dedicated partition case. + */ +static struct cpuidle_state powernv_states[MAX_IDLE_STATE_COUNT] = { + { /* Snooze */ + .name = snooze, + .desc = snooze, + .flags = CPUIDLE_FLAG_TIME_VALID, + .exit_latency = 0, + .target_residency = 0, + .enter = snooze_loop }, +{ /* Nap */ + .name = Nap, + .desc = Nap, + .flags = CPUIDLE_FLAG_TIME_VALID, + .exit_latency = 10, + .target_residency = 100, + .enter = nap_loop }, +}; + +static int powernv_cpuidle_add_cpu_notifier(struct notifier_block *n, + unsigned long action, void *hcpu) +{ + int hotcpu = (unsigned long)hcpu; + struct cpuidle_device *dev = + per_cpu_ptr(powernv_cpuidle_devices, hotcpu); + + if (dev cpuidle_get_driver()) { + switch (action) { + case CPU_ONLINE: + case CPU_ONLINE_FROZEN: + cpuidle_pause_and_lock(); + cpuidle_enable_device(dev); + cpuidle_resume_and_unlock(); + break; + + case CPU_DEAD: + case CPU_DEAD_FROZEN: + cpuidle_pause_and_lock(); + cpuidle_disable_device(dev); + cpuidle_resume_and_unlock(); + break; + + default: + return NOTIFY_DONE; + } + } + return NOTIFY_OK; +} + +static struct notifier_block setup_hotplug_notifier = { + .notifier_call = powernv_cpuidle_add_cpu_notifier, +}; + +/* + *
[PATCH 2/3] cpuidle/powernv: Enable idle powernv cpu to call into the cpuidle framework.
This patch enables idle powernv cpu to hook on to the cpuidle framework, if available, else call on to default idle platform code. Signed-off-by: Deepthi Dharwar deep...@linux.vnet.ibm.com --- arch/powerpc/platforms/powernv/setup.c | 12 +++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/arch/powerpc/platforms/powernv/setup.c b/arch/powerpc/platforms/powernv/setup.c index 84438af..97d0951 100644 --- a/arch/powerpc/platforms/powernv/setup.c +++ b/arch/powerpc/platforms/powernv/setup.c @@ -25,6 +25,7 @@ #include linux/of.h #include linux/interrupt.h #include linux/bug.h +#include linux/cpuidle.h #include asm/machdep.h #include asm/firmware.h @@ -196,6 +197,15 @@ static int __init pnv_probe(void) return 1; } +void powernv_idle(void) +{ + /* Hook to cpuidle framework if available, else +* call on default platform idle code +*/ + if (cpuidle_idle_call()) + power7_idle(); +} + define_machine(powernv) { .name = PowerNV, .probe = pnv_probe, @@ -205,7 +215,7 @@ define_machine(powernv) { .show_cpuinfo = pnv_show_cpuinfo, .progress = pnv_progress, .machine_shutdown = pnv_shutdown, - .power_save = power7_idle, + .power_save = powernv_idle, .calibrate_decr = generic_calibrate_decr, #ifdef CONFIG_KEXEC .kexec_cpu_down = pnv_kexec_cpu_down, ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 3/3] cpuidle/powernv: Support smt-snooze-delay parameter in powernv idle.
smt-snooze-delay is a tunable that is supported on powerpc platform to delay the entry to nap state. This can be set either via sysfs, kernel commandline or pp64_cpu util. Signed-off-by: Deepthi Dharwar deep...@linux.vnet.ibm.com --- arch/powerpc/include/asm/processor.h|2 + arch/powerpc/platforms/powernv/powernv.h|3 ++ arch/powerpc/platforms/powernv/processor_idle.c | 36 +++ 3 files changed, 40 insertions(+), 1 deletion(-) diff --git a/arch/powerpc/include/asm/processor.h b/arch/powerpc/include/asm/processor.h index 47a35b0..5700c3c 100644 --- a/arch/powerpc/include/asm/processor.h +++ b/arch/powerpc/include/asm/processor.h @@ -426,7 +426,7 @@ enum idle_boot_override {IDLE_NO_OVERRIDE = 0, IDLE_POWERSAVE_OFF}; extern int powersave_nap; /* set if nap mode can be used in idle loop */ extern void power7_nap(void); -#ifdef CONFIG_PSERIES_IDLE +#if defined(CONFIG_PSERIES_IDLE) || defined(CONFIG_POWERNV_IDLE) extern void update_smt_snooze_delay(int cpu, int residency); #else static inline void update_smt_snooze_delay(int cpu, int residency) {} diff --git a/arch/powerpc/platforms/powernv/powernv.h b/arch/powerpc/platforms/powernv/powernv.h index a1c6f83..558ee69 100644 --- a/arch/powerpc/platforms/powernv/powernv.h +++ b/arch/powerpc/platforms/powernv/powernv.h @@ -15,4 +15,7 @@ static inline void pnv_pci_init(void) { } static inline void pnv_pci_shutdown(void) { } #endif +/* Idle variable */ +DECLARE_PER_CPU(long, smt_snooze_delay); + #endif /* _POWERNV_H */ diff --git a/arch/powerpc/platforms/powernv/processor_idle.c b/arch/powerpc/platforms/powernv/processor_idle.c index f43ad91a..505fea4 100644 --- a/arch/powerpc/platforms/powernv/processor_idle.c +++ b/arch/powerpc/platforms/powernv/processor_idle.c @@ -13,6 +13,8 @@ #include asm/machdep.h #include asm/runlatch.h +#include powernv.h + struct cpuidle_driver powernv_idle_driver = { .name = powernv_idle, .owner =THIS_MODULE, @@ -193,6 +195,38 @@ static int powernv_idle_probe(void) return 0; } +void update_smt_snooze_delay(int cpu, int residency) +{ + struct cpuidle_driver *drv = cpuidle_get_driver(); + struct cpuidle_device *dev; + + if (!drv) + return; + + if (cpu == -1) { + if (residency 0) { + /* Disable NAP on all cpus */ + drv-states[1].disabled = true; + } else { + drv-states[1].target_residency = residency; + drv-states[1].disabled = false; + } + return; + } + + dev = per_cpu(cpuidle_devices, cpu); + if (!dev) + return; + + if (residency 0) + dev-states_usage[1].disable = 1; + else { + drv-states[1].target_residency = residency; + drv-states[1].disabled = false; + dev-states_usage[1].disable = 0; + } +} + static int __init powernv_processor_idle_init(void) { int retval; @@ -208,6 +242,8 @@ static int __init powernv_processor_idle_init(void) return retval; } + update_smt_snooze_delay(-1, per_cpu(smt_snooze_delay, 0)); + retval = powernv_idle_devices_init(); if (retval) { powernv_idle_devices_uninit(); ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH 03/10] vfio: add external user support
On 07/23/2013 12:23 PM, Alex Williamson wrote: On Tue, 2013-07-16 at 10:53 +1000, Alexey Kardashevskiy wrote: VFIO is designed to be used via ioctls on file descriptors returned by VFIO. However in some situations support for an external user is required. The first user is KVM on PPC64 (SPAPR TCE protocol) which is going to use the existing VFIO groups for exclusive access in real/virtual mode on a host to avoid passing map/unmap requests to the user space which would made things pretty slow. The protocol includes: 1. do normal VFIO init operation: - opening a new container; - attaching group(s) to it; - setting an IOMMU driver for a container. When IOMMU is set for a container, all groups in it are considered ready to use by an external user. 2. User space passes a group fd to an external user. The external user calls vfio_group_get_external_user() to verify that: - the group is initialized; - IOMMU is set for it. If both checks passed, vfio_group_get_external_user() increments the container user counter to prevent the VFIO group from disposal before KVM exits. 3. The external user calls vfio_external_user_iommu_id() to know an IOMMU ID. PPC64 KVM uses it to link logical bus number (LIOBN) with IOMMU ID. 4. When the external KVM finishes, it calls vfio_group_put_external_user() to release the VFIO group. This call decrements the container user counter. Everything gets released. The vfio: Limit group opens patch is also required for the consistency. Signed-off-by: Alexey Kardashevskiy a...@ozlabs.ru This looks fine to me. Is the plan to add this through the ppc tree again? Thanks, Nope, better to add this through your tree. And faster for sure :) Thanks! -- Alexey ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 1/2] cpuidle: fix cpu idle driver as a module can not remove
From: Wang Dongsheng dongsheng.w...@freescale.com The module can not be removed when execute rmmod. rmmod not use --force. Log: root:~# rmmod cpuidle-e500 incs[9], decs[1] rmmod: can't unload 'cpuidle_e500': Resource temporarily unavailable Signed-off-by: Wang Dongsheng dongsheng.w...@freescale.com --- Branch: pm-cpuidle drivers/cpuidle/cpuidle.c | 7 +++ 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c index fdc432f..534320a 100644 --- a/drivers/cpuidle/cpuidle.c +++ b/drivers/cpuidle/cpuidle.c @@ -386,6 +386,9 @@ static int __cpuidle_register_device(struct cpuidle_device *dev) goto err_coupled; dev-registered = 1; + + module_put(drv-owner); + return 0; err_coupled: @@ -432,8 +435,6 @@ EXPORT_SYMBOL_GPL(cpuidle_register_device); */ void cpuidle_unregister_device(struct cpuidle_device *dev) { - struct cpuidle_driver *drv = cpuidle_get_cpu_driver(dev); - if (dev-registered == 0) return; @@ -448,8 +449,6 @@ void cpuidle_unregister_device(struct cpuidle_device *dev) cpuidle_coupled_unregister_device(dev); cpuidle_resume_and_unlock(); - - module_put(drv-owner); } EXPORT_SYMBOL_GPL(cpuidle_unregister_device); -- 1.8.0 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 2/2] cpuidle: export cpuidle_idle_call symbol
From: Wang Dongsheng dongsheng.w...@freescale.com Export cpuidle_idle_call symbol, make this function can be invoked in the module. Signed-off-by: Wang Dongsheng dongsheng.w...@freescale.com --- Branch: pm-cpuidle drivers/cpuidle/cpuidle.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c index 534320a..d0a61d6 100644 --- a/drivers/cpuidle/cpuidle.c +++ b/drivers/cpuidle/cpuidle.c @@ -168,6 +168,7 @@ int cpuidle_idle_call(void) return 0; } +EXPORT_SYMBOL_GPL(cpuidle_idle_call); /** * cpuidle_install_idle_handler - installs the cpuidle idle loop handler -- 1.8.0 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 02/11] powerpc/eeh: Export functions for hotplug
Make some functions public in order to support hotplug on either specific PCI bus or PCI device in future. Signed-off-by: Gavin Shan sha...@linux.vnet.ibm.com --- arch/powerpc/include/asm/eeh.h |9 + arch/powerpc/kernel/eeh.c |6 +++--- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/arch/powerpc/include/asm/eeh.h b/arch/powerpc/include/asm/eeh.h index 09a8743..d9d35c2 100644 --- a/arch/powerpc/include/asm/eeh.h +++ b/arch/powerpc/include/asm/eeh.h @@ -209,9 +209,12 @@ unsigned long eeh_check_failure(const volatile void __iomem *token, unsigned long val); int eeh_dev_check_failure(struct eeh_dev *edev); void eeh_addr_cache_build(void); +void eeh_add_device_early(struct device_node *); void eeh_add_device_tree_early(struct device_node *); +void eeh_add_device_late(struct pci_dev *); void eeh_add_device_tree_late(struct pci_bus *); void eeh_add_sysfs_files(struct pci_bus *); +void eeh_remove_device(struct pci_dev *, int); void eeh_remove_bus_device(struct pci_dev *, int); /** @@ -252,12 +255,18 @@ static inline unsigned long eeh_check_failure(const volatile void __iomem *token static inline void eeh_addr_cache_build(void) { } +static inline void eeh_add_device_early(struct device_node *dn) { } + static inline void eeh_add_device_tree_early(struct device_node *dn) { } +static inline void eeh_add_device_late(struct pci_dev *dev) { } + static inline void eeh_add_device_tree_late(struct pci_bus *bus) { } static inline void eeh_add_sysfs_files(struct pci_bus *bus) { } +static inline void eeh_remove_device(struct pci_dev *dev, int purge_pe) { } + static inline void eeh_remove_bus_device(struct pci_dev *dev, int purge_pe) { } #define EEH_POSSIBLE_ERROR(val, type) (0) diff --git a/arch/powerpc/kernel/eeh.c b/arch/powerpc/kernel/eeh.c index b5c425e..582ad1e 100644 --- a/arch/powerpc/kernel/eeh.c +++ b/arch/powerpc/kernel/eeh.c @@ -836,7 +836,7 @@ core_initcall_sync(eeh_init); * on the CEC architecture, type of the device, on earlier boot * command-line arguments etc. */ -static void eeh_add_device_early(struct device_node *dn) +void eeh_add_device_early(struct device_node *dn) { struct pci_controller *phb; @@ -884,7 +884,7 @@ EXPORT_SYMBOL_GPL(eeh_add_device_tree_early); * This routine must be used to complete EEH initialization for PCI * devices that were added after system boot (e.g. hotplug, dlpar). */ -static void eeh_add_device_late(struct pci_dev *dev) +void eeh_add_device_late(struct pci_dev *dev) { struct device_node *dn; struct eeh_dev *edev; @@ -972,7 +972,7 @@ EXPORT_SYMBOL_GPL(eeh_add_sysfs_files); * this device will no longer be detected after this call; thus, * i/o errors affecting this slot may leave this device unusable. */ -static void eeh_remove_device(struct pci_dev *dev, int purge_pe) +void eeh_remove_device(struct pci_dev *dev, int purge_pe) { struct eeh_dev *edev; -- 1.7.5.4 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 03/11] powerpc/pci: Override pcibios_release_device()
The patch overrides pcibios_release_device() to release EEH resources (EEH cache, unbinding EEH device) for the indicated PCI device. Signed-off-by: Gavin Shan sha...@linux.vnet.ibm.com --- arch/powerpc/kernel/pci-hotplug.c | 11 +++ 1 files changed, 11 insertions(+), 0 deletions(-) diff --git a/arch/powerpc/kernel/pci-hotplug.c b/arch/powerpc/kernel/pci-hotplug.c index 3f60880..3dab2f2 100644 --- a/arch/powerpc/kernel/pci-hotplug.c +++ b/arch/powerpc/kernel/pci-hotplug.c @@ -22,6 +22,17 @@ #include asm/eeh.h /** + * pcibios_release_device - release PCI device + * @dev: PCI device + * + * The function is called before releasing the indicated PCI device. + */ +void pcibios_release_device(struct pci_dev *dev) +{ + eeh_remove_device(dev, 1); +} + +/** * __pcibios_remove_pci_devices - remove all devices under this bus * @bus: the indicated PCI bus * @purge_pe: destroy the PE on removal of PCI devices -- 1.7.5.4 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 05/11] powerpc/eeh: Keep PE during hotplug
When we do normal hotplug, the PE shouldn't be kept. However, we need the PE if the hotplug caused by EEH errors. Since we remove EEH device through the PCI hook pcibios_stop_dev(), the flag purge_pe passed to various functions is meaningless. So the patch removes the meaningless flag and introduce new flag EEH_PE_KEEP to save the PE while doing hotplug during EEH error recovery. Signed-off-by: Gavin Shan sha...@linux.vnet.ibm.com --- arch/powerpc/include/asm/eeh.h| 11 +-- arch/powerpc/include/asm/pci-bridge.h |1 - arch/powerpc/kernel/eeh.c | 28 ++-- arch/powerpc/kernel/eeh_driver.c |7 +-- arch/powerpc/kernel/eeh_pe.c |7 +++ arch/powerpc/kernel/pci-hotplug.c | 26 +- 6 files changed, 20 insertions(+), 60 deletions(-) diff --git a/arch/powerpc/include/asm/eeh.h b/arch/powerpc/include/asm/eeh.h index d9d35c2..2ce22d7 100644 --- a/arch/powerpc/include/asm/eeh.h +++ b/arch/powerpc/include/asm/eeh.h @@ -55,6 +55,8 @@ struct device_node; #define EEH_PE_RECOVERING (1 1)/* Recovering PE*/ #define EEH_PE_PHB_DEAD(1 2)/* Dead PHB */ +#define EEH_PE_KEEP(1 8)/* Keep PE on hotplug */ + struct eeh_pe { int type; /* PE type: PHB/Bus/Device */ int state; /* PE EEH dependent mode*/ @@ -193,7 +195,7 @@ int eeh_phb_pe_create(struct pci_controller *phb); struct eeh_pe *eeh_phb_pe_get(struct pci_controller *phb); struct eeh_pe *eeh_pe_get(struct eeh_dev *edev); int eeh_add_to_parent_pe(struct eeh_dev *edev); -int eeh_rmv_from_parent_pe(struct eeh_dev *edev, int purge_pe); +int eeh_rmv_from_parent_pe(struct eeh_dev *edev); void eeh_pe_update_time_stamp(struct eeh_pe *pe); void *eeh_pe_dev_traverse(struct eeh_pe *root, eeh_traverse_func fn, void *flag); @@ -214,8 +216,7 @@ void eeh_add_device_tree_early(struct device_node *); void eeh_add_device_late(struct pci_dev *); void eeh_add_device_tree_late(struct pci_bus *); void eeh_add_sysfs_files(struct pci_bus *); -void eeh_remove_device(struct pci_dev *, int); -void eeh_remove_bus_device(struct pci_dev *, int); +void eeh_remove_device(struct pci_dev *); /** * EEH_POSSIBLE_ERROR() -- test for possible MMIO failure. @@ -265,9 +266,7 @@ static inline void eeh_add_device_tree_late(struct pci_bus *bus) { } static inline void eeh_add_sysfs_files(struct pci_bus *bus) { } -static inline void eeh_remove_device(struct pci_dev *dev, int purge_pe) { } - -static inline void eeh_remove_bus_device(struct pci_dev *dev, int purge_pe) { } +static inline void eeh_remove_device(struct pci_dev *dev) { } #define EEH_POSSIBLE_ERROR(val, type) (0) #define EEH_IO_ERROR_VALUE(size) (-1UL) diff --git a/arch/powerpc/include/asm/pci-bridge.h b/arch/powerpc/include/asm/pci-bridge.h index 2c1d8cb..32d0d20 100644 --- a/arch/powerpc/include/asm/pci-bridge.h +++ b/arch/powerpc/include/asm/pci-bridge.h @@ -209,7 +209,6 @@ static inline struct eeh_dev *of_node_to_eeh_dev(struct device_node *dn) extern struct pci_bus *pcibios_find_pci_bus(struct device_node *dn); /** Remove all of the PCI devices under this bus */ -extern void __pcibios_remove_pci_devices(struct pci_bus *bus, int purge_pe); extern void pcibios_remove_pci_devices(struct pci_bus *bus); /** Discover new pci devices under this bus, and add them */ diff --git a/arch/powerpc/kernel/eeh.c b/arch/powerpc/kernel/eeh.c index 582ad1e..ce81477 100644 --- a/arch/powerpc/kernel/eeh.c +++ b/arch/powerpc/kernel/eeh.c @@ -964,7 +964,6 @@ EXPORT_SYMBOL_GPL(eeh_add_sysfs_files); /** * eeh_remove_device - Undo EEH setup for the indicated pci device * @dev: pci device to be removed - * @purge_pe: remove the PE or not * * This routine should be called when a device is removed from * a running system (e.g. by hotplug or dlpar). It unregisters @@ -972,7 +971,7 @@ EXPORT_SYMBOL_GPL(eeh_add_sysfs_files); * this device will no longer be detected after this call; thus, * i/o errors affecting this slot may leave this device unusable. */ -void eeh_remove_device(struct pci_dev *dev, int purge_pe) +void eeh_remove_device(struct pci_dev *dev) { struct eeh_dev *edev; @@ -990,34 +989,11 @@ void eeh_remove_device(struct pci_dev *dev, int purge_pe) edev-pdev = NULL; dev-dev.archdata.edev = NULL; - eeh_rmv_from_parent_pe(edev, purge_pe); + eeh_rmv_from_parent_pe(edev); eeh_addr_cache_rmv_dev(dev); eeh_sysfs_remove_device(dev); } -/** - * eeh_remove_bus_device - Undo EEH setup for the indicated PCI device - * @dev: PCI device - * @purge_pe: remove the corresponding PE or not - * - * This routine must be called when a device is removed from the - * running system through hotplug or dlpar. The corresponding - * PCI address cache will be removed. - */ -void
[PATCH 01/11] powerpc/eeh: Remove reference to PCI device
We will rely on pcibios_release_device() to remove the EEH cache and unbind EEH device for the specific PCI device. So we shouldn't hold the reference to the PCI device from EEH cache and EEH device. Otherwise, pcibios_release_device() won't be called as we expected. The patch removes the reference to the PCI device in EEH core. Signed-off-by: Gavin Shan sha...@linux.vnet.ibm.com --- arch/powerpc/kernel/eeh.c |4 arch/powerpc/kernel/eeh_cache.c | 18 +- 2 files changed, 5 insertions(+), 17 deletions(-) diff --git a/arch/powerpc/kernel/eeh.c b/arch/powerpc/kernel/eeh.c index 39954fe..b5c425e 100644 --- a/arch/powerpc/kernel/eeh.c +++ b/arch/powerpc/kernel/eeh.c @@ -499,8 +499,6 @@ unsigned long eeh_check_failure(const volatile void __iomem *token, unsigned lon } eeh_dev_check_failure(edev); - - pci_dev_put(eeh_dev_to_pci_dev(edev)); return val; } @@ -904,7 +902,6 @@ static void eeh_add_device_late(struct pci_dev *dev) } WARN_ON(edev-pdev); - pci_dev_get(dev); edev-pdev = dev; dev-dev.archdata.edev = edev; @@ -992,7 +989,6 @@ static void eeh_remove_device(struct pci_dev *dev, int purge_pe) } edev-pdev = NULL; dev-dev.archdata.edev = NULL; - pci_dev_put(dev); eeh_rmv_from_parent_pe(edev, purge_pe); eeh_addr_cache_rmv_dev(dev); diff --git a/arch/powerpc/kernel/eeh_cache.c b/arch/powerpc/kernel/eeh_cache.c index f9ac123..e8c9fd5 100644 --- a/arch/powerpc/kernel/eeh_cache.c +++ b/arch/powerpc/kernel/eeh_cache.c @@ -68,16 +68,12 @@ static inline struct eeh_dev *__eeh_addr_cache_get_device(unsigned long addr) struct pci_io_addr_range *piar; piar = rb_entry(n, struct pci_io_addr_range, rb_node); - if (addr piar-addr_lo) { + if (addr piar-addr_lo) n = n-rb_left; - } else { - if (addr piar-addr_hi) { - n = n-rb_right; - } else { - pci_dev_get(piar-pcidev); - return piar-edev; - } - } + else if (addr piar-addr_hi) + n = n-rb_right; + else + return piar-edev; } return NULL; @@ -156,7 +152,6 @@ eeh_addr_cache_insert(struct pci_dev *dev, unsigned long alo, if (!piar) return NULL; - pci_dev_get(dev); piar-addr_lo = alo; piar-addr_hi = ahi; piar-edev = pci_dev_to_eeh_dev(dev); @@ -250,7 +245,6 @@ restart: if (piar-pcidev == dev) { rb_erase(n, pci_io_addr_cache_root.rb_root); - pci_dev_put(piar-pcidev); kfree(piar); goto restart; } @@ -302,12 +296,10 @@ void eeh_addr_cache_build(void) if (!edev) continue; - pci_dev_get(dev); /* matching put is in eeh_remove_device() */ dev-dev.archdata.edev = edev; edev-pdev = dev; eeh_addr_cache_insert_dev(dev); - eeh_sysfs_add_device(dev); } -- 1.7.5.4 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 04/11] PCI/hotplug: Needn't remove EEH cache again
Since pcibios_release_device() called by pci_stop_and_remove_bus_device() has removed the EEH cache, we needn't do that again. Cc: Bjorn Helgaas bhelg...@google.com Acked-by: Bjorn Helgaas bhelg...@google.com Signed-off-by: Gavin Shan sha...@linux.vnet.ibm.com --- drivers/pci/hotplug/rpadlpar_core.c |1 - 1 files changed, 0 insertions(+), 1 deletions(-) diff --git a/drivers/pci/hotplug/rpadlpar_core.c b/drivers/pci/hotplug/rpadlpar_core.c index b29e20b..bb7af78 100644 --- a/drivers/pci/hotplug/rpadlpar_core.c +++ b/drivers/pci/hotplug/rpadlpar_core.c @@ -388,7 +388,6 @@ int dlpar_remove_pci_slot(char *drc_name, struct device_node *dn) /* Remove the EADS bridge device itself */ BUG_ON(!bus-self); pr_debug(PCI: Now removing bridge device %s\n, pci_name(bus-self)); - eeh_remove_bus_device(bus-self, true); pci_stop_and_remove_bus_device(bus-self); return 0; -- 1.7.5.4 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 09/11] powerpc/eeh: Don't use pci_dev during BAR restore
While restoring BARs for one specific PCI device, the pci_dev instance should have been released. So it's not reliable to use the pci_dev instance on restoring BARs. However, we still need some information (e.g. PCIe capability position, header type) from the pci_dev instance. So we have to store those information to EEH device in advance. Signed-off-by: Gavin Shan sha...@linux.vnet.ibm.com --- arch/powerpc/include/asm/eeh.h |8 +++- arch/powerpc/kernel/eeh_pe.c | 25 +- arch/powerpc/platforms/powernv/eeh-powernv.c | 11 + arch/powerpc/platforms/pseries/eeh_pseries.c | 63 +- 4 files changed, 91 insertions(+), 16 deletions(-) diff --git a/arch/powerpc/include/asm/eeh.h b/arch/powerpc/include/asm/eeh.h index f54a601..4199d99 100644 --- a/arch/powerpc/include/asm/eeh.h +++ b/arch/powerpc/include/asm/eeh.h @@ -84,8 +84,11 @@ struct eeh_pe { * another tree except the currently existing tree of PCI * buses and PCI devices */ -#define EEH_DEV_IRQ_DISABLED (1 0)/* Interrupt disabled */ -#define EEH_DEV_DISCONNECTED (1 1)/* Removing from PE */ +#define EEH_DEV_BRIDGE (1 0)/* PCI bridge */ +#define EEH_DEV_ROOT_PORT (1 1)/* PCIe root port */ +#define EEH_DEV_DS_PORT(1 2)/* Downstream port */ +#define EEH_DEV_IRQ_DISABLED (1 3)/* Interrupt disabled */ +#define EEH_DEV_DISCONNECTED (1 4)/* Removing from PE */ struct eeh_dev { int mode; /* EEH mode */ @@ -93,6 +96,7 @@ struct eeh_dev { int config_addr;/* Config address */ int pe_config_addr; /* PE config address*/ u32 config_space[16]; /* Saved PCI config space */ + u8 pcie_cap;/* Saved PCIe capability*/ struct eeh_pe *pe; /* Associated PE*/ struct list_head list; /* Form link list in the PE */ struct pci_controller *phb; /* Associated PHB */ diff --git a/arch/powerpc/kernel/eeh_pe.c b/arch/powerpc/kernel/eeh_pe.c index 2aa955a..f945053 100644 --- a/arch/powerpc/kernel/eeh_pe.c +++ b/arch/powerpc/kernel/eeh_pe.c @@ -578,7 +578,7 @@ void eeh_pe_state_clear(struct eeh_pe *pe, int state) * blocked on normal path during the stage. So we need utilize * eeh operations, which is always permitted. */ -static void eeh_bridge_check_link(struct pci_dev *pdev, +static void eeh_bridge_check_link(struct eeh_dev *edev, struct device_node *dn) { int cap; @@ -589,16 +589,17 @@ static void eeh_bridge_check_link(struct pci_dev *pdev, * We only check root port and downstream ports of * PCIe switches */ - if (!pci_is_pcie(pdev) || - (pci_pcie_type(pdev) != PCI_EXP_TYPE_ROOT_PORT -pci_pcie_type(pdev) != PCI_EXP_TYPE_DOWNSTREAM)) + if (!(edev-mode (EEH_DEV_ROOT_PORT | EEH_DEV_DS_PORT))) return; - pr_debug(%s: Check PCIe link for %s ...\n, -__func__, pci_name(pdev)); + pr_debug(%s: Check PCIe link for %04x:%02x:%02x.%01x ...\n, +__func__, edev-phb-global_number, +edev-config_addr 8, +PCI_SLOT(edev-config_addr 0xFF), +PCI_FUNC(edev-config_addr 0xFF)); /* Check slot status */ - cap = pdev-pcie_cap; + cap = edev-pcie_cap; eeh_ops-read_config(dn, cap + PCI_EXP_SLTSTA, 2, val); if (!(val PCI_EXP_SLTSTA_PDS)) { pr_debug( No card in the slot (0x%04x) !\n, val); @@ -652,8 +653,7 @@ static void eeh_bridge_check_link(struct pci_dev *pdev, #define BYTE_SWAP(OFF) (8*((OFF)/4)+3-(OFF)) #define SAVED_BYTE(OFF)(((u8 *)(edev-config_space))[BYTE_SWAP(OFF)]) -static void eeh_restore_bridge_bars(struct pci_dev *pdev, - struct eeh_dev *edev, +static void eeh_restore_bridge_bars(struct eeh_dev *edev, struct device_node *dn) { int i; @@ -679,7 +679,7 @@ static void eeh_restore_bridge_bars(struct pci_dev *pdev, eeh_ops-write_config(dn, PCI_COMMAND, 4, edev-config_space[1]); /* Check the PCIe link is ready */ - eeh_bridge_check_link(pdev, dn); + eeh_bridge_check_link(edev, dn); } static void eeh_restore_device_bars(struct eeh_dev *edev, @@ -729,12 +729,11 @@ static void eeh_restore_device_bars(struct eeh_dev *edev, static void *eeh_restore_one_device_bars(void *data, void *flag) { struct eeh_dev *edev = (struct eeh_dev *)data; - struct pci_dev *pdev = eeh_dev_to_pci_dev(edev); struct device_node *dn = eeh_dev_to_of_node(edev); /* Do special restore for bridges */ - if (pdev-hdr_type ==
[PATCH 07/11] powerpc/pci: Partial hotplug support
When EEH error happens to one specific PE, the device drivers of its attached EEH devices (PCI devices) are checked to see the further action: reset with complete hotplug, or reset without hotplug. However, that's not enough for those PCI devices whose drivers can't support EEH, or those PCI devices without driver. So we need do so-called partial hotplug on basis of PCI devices. In the situation, part of PCI devices of the specific PE are unplugged and plugged again after PE reset. The patch changes pcibios_add_pci_devices() so that it can support full hotplug and so-called partial hotplug based on device-tree or real hardware. It's notable that pci_of_scan.c has been changed for a bit in order to support the partial hotplug based on dev-tree. Signed-off-by: Gavin Shan sha...@linux.vnet.ibm.com --- arch/powerpc/kernel/pci-common.c |1 + arch/powerpc/kernel/pci-hotplug.c |6 +-- arch/powerpc/kernel/pci_of_scan.c | 56 ++-- 3 files changed, 43 insertions(+), 20 deletions(-) diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c index f46914a..f80a4f4 100644 --- a/arch/powerpc/kernel/pci-common.c +++ b/arch/powerpc/kernel/pci-common.c @@ -1462,6 +1462,7 @@ void pcibios_finish_adding_to_bus(struct pci_bus *bus) /* Allocate bus and devices resources */ pcibios_allocate_bus_resources(bus); pcibios_claim_one_bus(bus); + pci_assign_unassigned_bus_resources(bus); /* Fixup EEH */ eeh_add_device_tree_late(bus); diff --git a/arch/powerpc/kernel/pci-hotplug.c b/arch/powerpc/kernel/pci-hotplug.c index fc0831d..8e9b1c2 100644 --- a/arch/powerpc/kernel/pci-hotplug.c +++ b/arch/powerpc/kernel/pci-hotplug.c @@ -71,7 +71,7 @@ EXPORT_SYMBOL_GPL(pcibios_remove_pci_devices); */ void pcibios_add_pci_devices(struct pci_bus * bus) { - int slotno, num, mode, pass, max; + int slotno, mode, pass, max; struct pci_dev *dev; struct device_node *dn = pci_bus_to_OF_node(bus); @@ -87,9 +87,7 @@ void pcibios_add_pci_devices(struct pci_bus * bus) } else if (mode == PCI_PROBE_NORMAL) { /* use legacy probe */ slotno = PCI_SLOT(PCI_DN(dn-child)-devfn); - num = pci_scan_slot(bus, PCI_DEVFN(slotno, 0)); - if (!num) - return; + pci_scan_slot(bus, PCI_DEVFN(slotno, 0)); pcibios_setup_bus_devices(bus); max = bus-busn_res.start; for (pass = 0; pass 2; pass++) { diff --git a/arch/powerpc/kernel/pci_of_scan.c b/arch/powerpc/kernel/pci_of_scan.c index 6b0ba58..15d9105 100644 --- a/arch/powerpc/kernel/pci_of_scan.c +++ b/arch/powerpc/kernel/pci_of_scan.c @@ -230,11 +230,14 @@ void of_scan_pci_bridge(struct pci_dev *dev) return; } - bus = pci_add_new_bus(dev-bus, dev, busrange[0]); + bus = pci_find_bus(pci_domain_nr(dev-bus), busrange[0]); if (!bus) { - printk(KERN_ERR Failed to create pci bus for %s\n, - node-full_name); - return; + bus = pci_add_new_bus(dev-bus, dev, busrange[0]); + if (!bus) { + printk(KERN_ERR Failed to create pci bus for %s\n, + node-full_name); + return; + } } bus-primary = dev-bus-number; @@ -292,6 +295,38 @@ void of_scan_pci_bridge(struct pci_dev *dev) } EXPORT_SYMBOL(of_scan_pci_bridge); +static struct pci_dev *of_scan_pci_dev(struct pci_bus *bus, + struct device_node *dn) +{ + struct pci_dev *dev = NULL; + const u32 *reg; + int reglen, devfn; + + pr_debug( * %s\n, dn-full_name); + if (!of_device_is_available(dn)) + return NULL; + + reg = of_get_property(dn, reg, reglen); + if (reg == NULL || reglen 20) + return NULL; + devfn = (reg[0] 8) 0xff; + + /* Check if the PCI device is already there */ + dev = pci_get_slot(bus, devfn); + if (dev) { + pci_dev_put(dev); + return dev; + } + + /* create a new pci_dev for this device */ + dev = of_create_pci_dev(dn, bus, devfn); + if (!dev) + return NULL; + + pr_debug( dev header type: %x\n, dev-hdr_type); + return dev; +} + /** * __of_scan_bus - given a PCI bus node, setup bus and scan for child devices * @node: device tree node for the PCI bus @@ -302,8 +337,6 @@ static void __of_scan_bus(struct device_node *node, struct pci_bus *bus, int rescan_existing) { struct device_node *child; - const u32 *reg; - int reglen, devfn; struct pci_dev *dev; pr_debug(of_scan_bus(%s) bus no %d...\n, @@ -311,16 +344,7 @@ static void __of_scan_bus(struct device_node *node, struct pci_bus *bus, /*
[PATCH 08/11] powerpc/eeh: Support partial hotplug
When EEH error happens to one specific PE, some devices with drivers supporting EEH won't except hotplug on the deivce. However, there might have other deivces without driver, or with driver without EEH support. For the case, we need do partial hotplug in order to make sure that the PE becomes absolutely quite during reset. Otherise, the PE reset might fail and leads to failure of error recovery. The patch intends to support so-called partial hotplug for EEH: Before we do reset, we stop and remove those PCI devices without EEH sensitive driver. The corresponding EEH devices are not detached from its PE, but with special flag. After the reset is done, those EEH devices with the special flag will be scanned one by one. Signed-off-by: Gavin Shan sha...@linux.vnet.ibm.com --- arch/powerpc/include/asm/eeh.h |6 ++- arch/powerpc/kernel/eeh.c| 30 +- arch/powerpc/kernel/eeh_driver.c | 74 -- arch/powerpc/kernel/eeh_pe.c | 20 +++- arch/powerpc/kernel/eeh_sysfs.c |7 +++ arch/powerpc/platforms/powernv/eeh-powernv.c |2 +- arch/powerpc/platforms/pseries/eeh_pseries.c |2 +- 7 files changed, 117 insertions(+), 24 deletions(-) diff --git a/arch/powerpc/include/asm/eeh.h b/arch/powerpc/include/asm/eeh.h index e8c411b..f54a601 100644 --- a/arch/powerpc/include/asm/eeh.h +++ b/arch/powerpc/include/asm/eeh.h @@ -84,7 +84,8 @@ struct eeh_pe { * another tree except the currently existing tree of PCI * buses and PCI devices */ -#define EEH_DEV_IRQ_DISABLED (10) /* Interrupt disabled */ +#define EEH_DEV_IRQ_DISABLED (1 0)/* Interrupt disabled */ +#define EEH_DEV_DISCONNECTED (1 1)/* Removing from PE */ struct eeh_dev { int mode; /* EEH mode */ @@ -97,6 +98,7 @@ struct eeh_dev { struct pci_controller *phb; /* Associated PHB */ struct device_node *dn; /* Associated device node */ struct pci_dev *pdev; /* Associated PCI device*/ + struct pci_bus *bus;/* PCI bus for partial hotplug */ }; static inline struct device_node *eeh_dev_to_of_node(struct eeh_dev *edev) @@ -197,6 +199,8 @@ struct eeh_pe *eeh_pe_get(struct eeh_dev *edev); int eeh_add_to_parent_pe(struct eeh_dev *edev); int eeh_rmv_from_parent_pe(struct eeh_dev *edev); void eeh_pe_update_time_stamp(struct eeh_pe *pe); +void *eeh_pe_traverse(struct eeh_pe *root, + eeh_traverse_func fn, void *flag); void *eeh_pe_dev_traverse(struct eeh_pe *root, eeh_traverse_func fn, void *flag); void eeh_pe_restore_bars(struct eeh_pe *pe); diff --git a/arch/powerpc/kernel/eeh.c b/arch/powerpc/kernel/eeh.c index 56bd458..a5783f1 100644 --- a/arch/powerpc/kernel/eeh.c +++ b/arch/powerpc/kernel/eeh.c @@ -900,7 +900,21 @@ void eeh_add_device_late(struct pci_dev *dev) pr_debug(EEH: Already referenced !\n); return; } - WARN_ON(edev-pdev); + + /* +* The EEH cache might not be removed correctly because of +* unbalanced kref to the device during unplug time, which +* relies on pcibios_release_device(). So we have to remove +* that here explicitly. +*/ + if (edev-pdev) { + eeh_rmv_from_parent_pe(edev); + eeh_addr_cache_rmv_dev(edev-pdev); + eeh_sysfs_remove_device(edev-pdev); + + edev-pdev = NULL; + dev-dev.archdata.edev = NULL; + } edev-pdev = dev; dev-dev.archdata.edev = edev; @@ -982,14 +996,24 @@ void eeh_remove_device(struct pci_dev *dev) /* Unregister the device with the EEH/PCI address search system */ pr_debug(EEH: Removing device %s\n, pci_name(dev)); - if (!edev || !edev-pdev) { + if (!edev || !edev-pdev || !edev-pe) { pr_debug(EEH: Not referenced !\n); return; } + + /* +* During the hotplug for EEH error recovery, we need the EEH +* device attached to the parent PE in order for BAR restore +* a bit later. So we keep it for BAR restore and remove it +* from the parent PE during the BAR resotre. +*/ edev-pdev = NULL; dev-dev.archdata.edev = NULL; + if (!(edev-pe-state EEH_PE_KEEP)) + eeh_rmv_from_parent_pe(edev); + else + edev-mode |= EEH_DEV_DISCONNECTED; - eeh_rmv_from_parent_pe(edev); eeh_addr_cache_rmv_dev(dev); eeh_sysfs_remove_device(dev); } diff --git a/arch/powerpc/kernel/eeh_driver.c b/arch/powerpc/kernel/eeh_driver.c index 9ef3bbb..9fda75d 100644 --- a/arch/powerpc/kernel/eeh_driver.c +++ b/arch/powerpc/kernel/eeh_driver.c @@ -338,6 +338,54 @@ static void *eeh_report_failure(void *data, void *userdata) return NULL; } +static
[PATCH 11/11] powerpc/eeh: Introdce flag to protect sysfs
The patch introduces flag EEH_DEV_SYSFS to trace that the sysfs for the corresponding EEH device (then PCI device) has been added or removed, in order to avoid race condition. Signed-off-by: Gavin Shan sha...@linux.vnet.ibm.com --- arch/powerpc/include/asm/eeh.h |2 ++ arch/powerpc/kernel/eeh.c|2 ++ arch/powerpc/kernel/eeh_sysfs.c | 16 +++- arch/powerpc/platforms/powernv/eeh-powernv.c |4 ++-- arch/powerpc/platforms/pseries/eeh_pseries.c |2 +- 5 files changed, 22 insertions(+), 4 deletions(-) diff --git a/arch/powerpc/include/asm/eeh.h b/arch/powerpc/include/asm/eeh.h index 4199d99..d3e5e9b 100644 --- a/arch/powerpc/include/asm/eeh.h +++ b/arch/powerpc/include/asm/eeh.h @@ -90,6 +90,8 @@ struct eeh_pe { #define EEH_DEV_IRQ_DISABLED (1 3)/* Interrupt disabled */ #define EEH_DEV_DISCONNECTED (1 4)/* Removing from PE */ +#define EEH_DEV_SYSFS (1 8)/* Sysfs created*/ + struct eeh_dev { int mode; /* EEH mode */ int class_code; /* Class code of the device */ diff --git a/arch/powerpc/kernel/eeh.c b/arch/powerpc/kernel/eeh.c index a5783f1..ea9414c8 100644 --- a/arch/powerpc/kernel/eeh.c +++ b/arch/powerpc/kernel/eeh.c @@ -911,6 +911,7 @@ void eeh_add_device_late(struct pci_dev *dev) eeh_rmv_from_parent_pe(edev); eeh_addr_cache_rmv_dev(edev-pdev); eeh_sysfs_remove_device(edev-pdev); + edev-mode = ~EEH_DEV_SYSFS; edev-pdev = NULL; dev-dev.archdata.edev = NULL; @@ -1016,6 +1017,7 @@ void eeh_remove_device(struct pci_dev *dev) eeh_addr_cache_rmv_dev(dev); eeh_sysfs_remove_device(dev); + edev-mode = ~EEH_DEV_SYSFS; } static int proc_eeh_show(struct seq_file *m, void *v) diff --git a/arch/powerpc/kernel/eeh_sysfs.c b/arch/powerpc/kernel/eeh_sysfs.c index 61e2a14..5d753d4 100644 --- a/arch/powerpc/kernel/eeh_sysfs.c +++ b/arch/powerpc/kernel/eeh_sysfs.c @@ -56,26 +56,40 @@ EEH_SHOW_ATTR(eeh_pe_config_addr, pe_config_addr, 0x%x); void eeh_sysfs_add_device(struct pci_dev *pdev) { + struct eeh_dev *edev = pci_dev_to_eeh_dev(pdev); int rc=0; + if (edev (edev-mode EEH_DEV_SYSFS)) + return; + rc += device_create_file(pdev-dev, dev_attr_eeh_mode); rc += device_create_file(pdev-dev, dev_attr_eeh_config_addr); rc += device_create_file(pdev-dev, dev_attr_eeh_pe_config_addr); if (rc) printk(KERN_WARNING EEH: Unable to create sysfs entries\n); + else if (edev) + edev-mode |= EEH_DEV_SYSFS; } void eeh_sysfs_remove_device(struct pci_dev *pdev) { + struct eeh_dev *edev = pci_dev_to_eeh_dev(pdev); + /* * The parent directory might have been removed. We needn't * continue for that case. */ - if (!pdev-dev.kobj.sd) + if (!pdev-dev.kobj.sd) { + if (edev) + edev-mode = ~EEH_DEV_SYSFS; return; + } device_remove_file(pdev-dev, dev_attr_eeh_mode); device_remove_file(pdev-dev, dev_attr_eeh_config_addr); device_remove_file(pdev-dev, dev_attr_eeh_pe_config_addr); + + if (edev) + edev-mode = ~EEH_DEV_SYSFS; } diff --git a/arch/powerpc/platforms/powernv/eeh-powernv.c b/arch/powerpc/platforms/powernv/eeh-powernv.c index 4361a5c..79663d2 100644 --- a/arch/powerpc/platforms/powernv/eeh-powernv.c +++ b/arch/powerpc/platforms/powernv/eeh-powernv.c @@ -122,8 +122,8 @@ static int powernv_eeh_dev_probe(struct pci_dev *dev, void *flag) return 0; /* Initialize eeh device */ - edev-class_code= dev-class; - edev-mode = 0; + edev-class_code = dev-class; + edev-mode = 0xFF00; if (dev-hdr_type == PCI_HEADER_TYPE_BRIDGE) edev-mode |= EEH_DEV_BRIDGE; if (pci_is_pcie(dev)) { diff --git a/arch/powerpc/platforms/pseries/eeh_pseries.c b/arch/powerpc/platforms/pseries/eeh_pseries.c index 9e80f0a..7fbc25b 100644 --- a/arch/powerpc/platforms/pseries/eeh_pseries.c +++ b/arch/powerpc/platforms/pseries/eeh_pseries.c @@ -218,7 +218,7 @@ static void *pseries_eeh_of_probe(struct device_node *dn, void *flag) */ edev-class_code = *class_code; edev-pcie_cap = pseries_eeh_find_cap(dn, PCI_CAP_ID_EXP); - edev-mode = 0; + edev-mode = 0xFF00; if ((edev-class_code 8) == PCI_CLASS_BRIDGE_PCI) { edev-mode |= EEH_DEV_BRIDGE; if (edev-pcie_cap) { -- 1.7.5.4 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH v3 0/11] EEH Followup Fixes (II)
The series of patches bases on linux-poerpc-next initially and intends to resolve the following problems: - On pSeries platform, the EEH doesn't work after PHB hotplug with drmgr. The root cause is that the EEH resources ( EEH devices, EEH caches) aren't released correctly. For the problem, we add one hook (pcibios_stop_dev), which is called on pci_stop_and_remove_device(). In pcibios_stop_dev(), we release the EEH resources. - Another issue is that we need put the domain (PE or PHB) into quite state while doing reset on that domain. However, some deivces in the domain might not have EEH sensitive drivers, or even don't have driver. Those deivces can't be put into quite state and possibly keep issuing PCI-CFG or MMIO request during resetting the domain. That possibly causes the failure of reset and eventually failure of EEH recovery. For the issue, we introduces so-called partial hotplug. That means, those devices without driver or without EEH sensitive driver are removed before doing reset, and plugged (probed) into the system after reset. - We need traverse EEH devices of one specific PE with safe variant of list tranverse function. The EEH device might be removed while doing iteration. - When doing plug for PCI bus, we need check if we need reassign the resources for subordinate devices (PCI_REASSIGN_ALL_RSRC) and do that accordingly. The patchset is verified on pSeires and PowerNV platforms: pSeries Platform: drmgr -c phb -r -s PHB 513 drmgr -c phb -a -s PHB 513 errinjct eeh -f 1 -s net/eth2 PowerNV Platform: cd /sys/devices/pci0005:00/0005:00:00.0/0005:01:00.0/0005:02:08.0/0005:80:00.0/0005:90:01.0 while true; do od -x config /dev/null; sleep 1; done echo 1 /sys/kernel/debug/powerpc/PCI0005/err_injct --- v2 - v3: * Make pcibios_add_pci_devices() to support partial hotplug according to Ben's comments. arch/powerpc/kernel/pci_of_scan.c has been adjusted for that. * Use pcibios_add_pci_devices() to do partial hotplug inside eeh_reset_device(). * Introduce flag EEH_DEV_SYSFS to trace the state of sysfs entries of the EEH device (then PCI device) to avoid race condition during partial hotplug. v1 - v2: * Rebase to 3.11.rc1 in order to use pcibios_release_device(). * Use pcibios_release_device() to release EEH cache and detach EEH device from PCI device. * Remove reference to PCI device in EEH cache since we're relying on pcibios_release_device(). * PCI device instance (struct pci_dev) isn't available during BAR restore and avoid use the instance that time. * Fix unbalanced enable for IRQ in eeh_driver.c * Retest the series of patches on Firebird-L/VPL3/VPL4 --- arch/powerpc/include/asm/eeh.h | 30 -- arch/powerpc/include/asm/pci-bridge.h|1 - arch/powerpc/kernel/eeh.c| 70 +++ arch/powerpc/kernel/eeh_cache.c | 18 ++ arch/powerpc/kernel/eeh_driver.c | 77 +- arch/powerpc/kernel/eeh_pe.c | 58 --- arch/powerpc/kernel/eeh_sysfs.c | 21 +++ arch/powerpc/kernel/pci-common.c |1 + arch/powerpc/kernel/pci-hotplug.c| 41 ++ arch/powerpc/kernel/pci_of_scan.c| 56 +- arch/powerpc/platforms/powernv/eeh-powernv.c | 17 +- arch/powerpc/platforms/pseries/eeh_pseries.c | 67 +- drivers/pci/hotplug/rpadlpar_core.c |1 - 13 files changed, 319 insertions(+), 139 deletions(-) Thanks, Gavin ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 10/11] powerpc/eeh: Fix unbalanced enable for IRQ
The patch fixes following issue: Unbalanced enable for IRQ 23 [ cut here ] WARNING: at kernel/irq/manage.c:437 : NIP [c016de8c] .__enable_irq+0x11c/0x140 LR [c016de88] .__enable_irq+0x118/0x140 Call Trace: [c03ea1f23880] [c016de88] .__enable_irq+0x118/0x140 (unreliable) [c03ea1f23910] [c016df08] .enable_irq+0x58/0xa0 [c03ea1f239a0] [c00388b4] .eeh_enable_irq+0xc4/0xe0 [c03ea1f23a30] [c0038a28] .eeh_report_reset+0x78/0x130 [c03ea1f23ac0] [c0037508] .eeh_pe_dev_traverse+0x98/0x170 [c03ea1f23b60] [c00391ac] .eeh_handle_normal_event+0x2fc/0x3d0 [c03ea1f23bf0] [c0039538] .eeh_handle_event+0x2b8/0x2c0 [c03ea1f23c90] [c0039600] .eeh_event_handler+0xc0/0x170 [c03ea1f23d30] [c00da9a0] .kthread+0xf0/0x100 [c03ea1f23e30] [c000a1dc] .ret_from_kernel_thread+0x5c/0x80 Signed-off-by: Gavin Shan sha...@linux.vnet.ibm.com --- arch/powerpc/kernel/eeh_driver.c |6 +- 1 files changed, 5 insertions(+), 1 deletions(-) diff --git a/arch/powerpc/kernel/eeh_driver.c b/arch/powerpc/kernel/eeh_driver.c index 9fda75d..36bed5a 100644 --- a/arch/powerpc/kernel/eeh_driver.c +++ b/arch/powerpc/kernel/eeh_driver.c @@ -143,10 +143,14 @@ static void eeh_disable_irq(struct pci_dev *dev) static void eeh_enable_irq(struct pci_dev *dev) { struct eeh_dev *edev = pci_dev_to_eeh_dev(dev); + struct irq_desc *desc; if ((edev-mode) EEH_DEV_IRQ_DISABLED) { edev-mode = ~EEH_DEV_IRQ_DISABLED; - enable_irq(dev-irq); + + desc = irq_to_desc(dev-irq); + if (desc desc-depth 0) + enable_irq(dev-irq); } } -- 1.7.5.4 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH v3 11/31] net: can: mscan: improve clock API use
On Mon, Jul 22, 2013 at 14:31 +0200, Marc Kleine-Budde wrote: On 07/22/2013 02:14 PM, Gerhard Sittig wrote: the .get_clock() callback is run from probe() and might allocate resources, introduce a .put_clock() callback that is run from remove() to undo any allocation activities looks good use devm_get_clk() upon lookup (for SYS and REF) to have the clocks put upon driver unload fine assume that resources get prepared but not necessarily enabled in the setup phase, make the open() and close() callbacks of the CAN network device enable and disable a previously acquired and prepared clock I think you should call prepare_enable and disable_unprepare in the open/close functions. After more local research, which totally eliminated the need to pre-enable the CAN related clocks, but might need more discussion as it touches the common gate support, I've learned something more: The CAN clock needs to get enabled during probe() already, since registers get accessed between probe() for the driver and open() for the network device -- while access to peripheral registers crashes the kernel when clocks still are disabled (other hardware may just hang or provide fake data, neither of this is OK). But I see the point in your suggestion to prepare _and_ enable the clock during open() as well -- to have open() cope with whatever probe() did, after all the driver is shared among platforms, which may differ in what they do during probe(). So I will: - make open() of the network device prepare _and_ enable the clock for the peripheral (if acquired during probe()) - adjust open() because ATM it leaves the clock enabled when the network device operation fails (the error path is incomplete in v3) - make the MPC512x specific probe() time .get_clock() routine not just prepare but enable the clock as well - and of course address all the shutdown counter parts of the above setup paths This results in: - specific chip drivers only need to balance their private get and put clock routines which are called from probe and remove, common paths DTRT for all of them - correct operation for MPC512x, where common clock is used - still everything is neutral for MPC5200 where common clock isn't used, behaviour is identical to before the change - no assumptions are made about what occurs or doesn't occur during probe(), when the network device is used then the clock is fully setup and operational - when the CAN network device isn't setup (because device tree doesn't describe it, or disables that node), then its clock remains idle (neither gets setup nor enabled) - complete preparation for future improvement wrt power consumption, where potential changes remain isolated to the specific chip (probe() time setup, get_clock() routine) while the ndo part need not get touched any more So this is the most appropriate approach I can come up with. Removing unnecessary devm_put_clk() calls is orthogonal to that. Putting these in isn't totally wrong (they won't harm, and they do signal visual balance more clearly such that the next person won't stop and wonder), but it's true that they are redundant. Trained persons will wonder as much about their presence as untrained persons wonder about their absence. :) Apparently I'm not well trained yet. I thought that being explicit and cautious would be good, but the feedback I got suggests that encoding unnecessary instructions isn't desirable. So I will remove those devm_put_clk() in v4. To save us one more iteration, shall I remove those calls only from error paths during setup? Or shall I remove them from regular shutdown paths as well? How much pain does the community feel with harmless yet unnecessary instructions? :) virtually yours Gerhard Sittig -- DENX Software Engineering GmbH, MD: Wolfgang Denk Detlev Zundel HRB 165235 Munich, Office: Kirchenstr. 5, D-82194 Groebenzell, Germany Phone: +49-8142-66989-0 Fax: +49-8142-66989-80 Email: off...@denx.de ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH v3 01/31] spi: mpc512x: cleanup clock API use
[ devicetree@vger adjusted ] On Mon, Jul 22, 2013 at 15:09 +0100, Mark Brown wrote: On Mon, Jul 22, 2013 at 02:14:28PM +0200, Gerhard Sittig wrote: + ret = clk_prepare_enable(clk); + if (ret) { + devm_clk_put(dev, clk); + goto free_irq; The main point of the devm_ APIs is to avoid the need for explicit freeing so you should just remove these puts. OK, will do in v4. Shall these get removed everywhere including regular shutdown paths, or just from error paths during setup? [ the same topic came up for the CAN patch, might answer there ] virtually yours Gerhard Sittig -- DENX Software Engineering GmbH, MD: Wolfgang Denk Detlev Zundel HRB 165235 Munich, Office: Kirchenstr. 5, D-82194 Groebenzell, Germany Phone: +49-8142-66989-0 Fax: +49-8142-66989-80 Email: off...@denx.de ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH v3 27/31] net: can: mscan: add common clock support for mpc512x
[ adjusted devtree to use the vger address ] On Mon, Jul 22, 2013 at 15:04 +0200, Marc Kleine-Budde wrote: On 07/22/2013 02:14 PM, Gerhard Sittig wrote: implement a .get_clock() callback for the MPC512x platform which uses the common clock infrastructure (eliminating direct access to the clock control registers from within the CAN network driver), and provide the corresponding .put_clock() callback to release resources after use keep the previous implementation of MPC512x support in place during migration, since common clock support is optional this change is neutral to the MPC5200 platform Signed-off-by: Gerhard Sittig g...@denx.de --- drivers/net/can/mscan/mpc5xxx_can.c | 169 +++ 1 file changed, 169 insertions(+) diff --git a/drivers/net/can/mscan/mpc5xxx_can.c b/drivers/net/can/mscan/mpc5xxx_can.c index e59b3a3..4897929 100644 --- a/drivers/net/can/mscan/mpc5xxx_can.c +++ b/drivers/net/can/mscan/mpc5xxx_can.c @@ -109,6 +109,167 @@ static u32 mpc52xx_can_get_clock(struct platform_device *ofdev, #endif /* CONFIG_PPC_MPC52xx */ #ifdef CONFIG_PPC_MPC512x + +#if IS_ENABLED(CONFIG_COMMON_CLK) + +static u32 mpc512x_can_get_clock(struct platform_device *ofdev, +const char *clock_source, int *mscan_clksrc) +{ + struct device_node *np; + u32 clockdiv; + enum { + CLK_FROM_AUTO, + CLK_FROM_IPS, + CLK_FROM_SYS, + CLK_FROM_REF, + } clk_from; + struct clk *clk_in, *clk_can; + unsigned long freq_calc; + struct mscan_priv *priv; + + /* the caller passed in the clock source spec that was read from +* the device tree, get the optional clock divider as well +*/ + np = ofdev-dev.of_node; + clockdiv = 1; + of_property_read_u32(np, fsl,mscan-clock-divider, clockdiv); + dev_dbg(ofdev-dev, device tree specs: clk src[%s] div[%d]\n, + clock_source ? clock_source : NULL, clockdiv); + + /* when clock-source is 'ip', the CANCTL1[CLKSRC] bit needs to +* get set, and the 'ips' clock is the input to the MSCAN +* component +* +* for clock-source values of 'ref' or 'sys' the CANCTL1[CLKSRC] +* bit needs to get cleared, an optional clock-divider may have +* been specified (the default value is 1), the appropriate +* MSCAN related MCLK is the input to the MSCAN component +* +* in the absence of a clock-source spec, first an optimal clock +* gets determined based on the 'sys' clock, if that fails the +* 'ref' clock is used +*/ + clk_from = CLK_FROM_AUTO; + if (clock_source) { + /* interpret the device tree's spec for the clock source */ + if (!strcmp(clock_source, ip)) + clk_from = CLK_FROM_IPS; + else if (!strcmp(clock_source, sys)) + clk_from = CLK_FROM_SYS; + else if (!strcmp(clock_source, ref)) + clk_from = CLK_FROM_REF; + else + goto err_invalid; + dev_dbg(ofdev-dev, got a clk source spec[%d]\n, clk_from); + } + if (clk_from == CLK_FROM_AUTO) { + /* no spec so far, try the 'sys' clock; round to the +* next MHz and see if we can get a multiple of 16MHz +*/ + dev_dbg(ofdev-dev, no clk source spec, trying SYS\n); + clk_in = devm_clk_get(ofdev-dev, sys); + if (IS_ERR(clk_in)) + goto err_notavail; + freq_calc = clk_get_rate(clk_in); + freq_calc += 49; + freq_calc /= 100; + freq_calc *= 100; + if ((freq_calc % 1600) == 0) { + clk_from = CLK_FROM_SYS; + clockdiv = freq_calc / 1600; + dev_dbg(ofdev-dev, + clk fit, sys[%lu] div[%d] freq[%lu]\n, + freq_calc, clockdiv, freq_calc / clockdiv); + } + } + if (clk_from == CLK_FROM_AUTO) { + /* no spec so far, use the 'ref' clock */ + dev_dbg(ofdev-dev, no clk source spec, trying REF\n); + clk_in = devm_clk_get(ofdev-dev, ref); + if (IS_ERR(clk_in)) + goto err_notavail; + clk_from = CLK_FROM_REF; + freq_calc = clk_get_rate(clk_in); + dev_dbg(ofdev-dev, + clk fit, ref[%lu] (no div) freq[%lu]\n, + freq_calc, freq_calc); + } + + /* select IPS or MCLK as the MSCAN input (returned to the caller), +* setup the MCLK mux source and rate if applicable, apply the +* optionally specified or derived above divider, and determine +* the actual resulting clock rate to return to the caller +*/ + switch (clk_from) { + case
[PATCH] powerpc: VPHN topology change updates all siblings
When an associativity level change is found for one thread, the siblings threads need to be updated as well. This is done today for PRRN in stage_topology_update() but is missing for VPHN in update_cpu_associativity_changes_mask(). All threads should be updated to move to the new node. Without this patch, a single thread may be flagged for a topology change, leaving it in a different node from its siblings, which is incorrect. This causes problems for the scheduler where overlapping scheduler groups are created and a loop is formed in those groups. Reported-by: Jan Stancek jstan...@redhat.com Signed-off-by: Robert Jennings r...@linux.vnet.ibm.com Cc: sta...@vger.kernel.org --- Looking to get this fix in 3.11. This is requested for the 3.10 stable tree as well, it fixes a bug that presents as a scheduler issue when VPHN is active. VPHN was enabled in the v3.9 window in commit b7abef0. --- arch/powerpc/mm/numa.c | 59 +- 1 file changed, 44 insertions(+), 15 deletions(-) diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c index 0839721..5850798 100644 --- a/arch/powerpc/mm/numa.c +++ b/arch/powerpc/mm/numa.c @@ -27,6 +27,7 @@ #include linux/seq_file.h #include linux/uaccess.h #include linux/slab.h +#include asm/cputhreads.h #include asm/sparsemem.h #include asm/prom.h #include asm/smp.h @@ -1318,7 +1319,8 @@ static int update_cpu_associativity_changes_mask(void) } } if (changed) { - cpumask_set_cpu(cpu, changes); + cpumask_or(changes, changes, cpu_sibling_mask(cpu)); + cpu = cpu_last_thread_sibling(cpu); } } @@ -1426,7 +1428,7 @@ static int update_cpu_topology(void *data) if (!data) return -EINVAL; - cpu = get_cpu(); + cpu = smp_processor_id(); for (update = data; update; update = update-next) { if (cpu != update-cpu) @@ -1446,12 +1448,12 @@ static int update_cpu_topology(void *data) */ int arch_update_cpu_topology(void) { - unsigned int cpu, changed = 0; + unsigned int cpu, sibling, changed = 0; struct topology_update_data *updates, *ud; unsigned int associativity[VPHN_ASSOC_BUFSIZE] = {0}; cpumask_t updated_cpus; struct device *dev; - int weight, i = 0; + int weight, new_nid, i = 0; weight = cpumask_weight(cpu_associativity_changes_mask); if (!weight) @@ -1464,19 +1466,46 @@ int arch_update_cpu_topology(void) cpumask_clear(updated_cpus); for_each_cpu(cpu, cpu_associativity_changes_mask) { - ud = updates[i++]; - ud-cpu = cpu; - vphn_get_associativity(cpu, associativity); - ud-new_nid = associativity_to_nid(associativity); - - if (ud-new_nid 0 || !node_online(ud-new_nid)) - ud-new_nid = first_online_node; + /* +* If siblings aren't flagged for changes, updates list +* will be too short. Skip on this update and set for next +* update. +*/ + if (!cpumask_subset(cpu_sibling_mask(cpu), + cpu_associativity_changes_mask)) { + pr_info(Sibling bits not set for associativity + change, cpu%d\n, cpu); + cpumask_or(cpu_associativity_changes_mask, + cpu_associativity_changes_mask, + cpu_sibling_mask(cpu)); + cpu = cpu_last_thread_sibling(cpu); + continue; + } - ud-old_nid = numa_cpu_lookup_table[cpu]; - cpumask_set_cpu(cpu, updated_cpus); + /* Use associativity from first thread for all siblings */ + vphn_get_associativity(cpu, associativity); + new_nid = associativity_to_nid(associativity); + if (new_nid 0 || !node_online(new_nid)) + new_nid = first_online_node; + + if (new_nid == numa_cpu_lookup_table[cpu]) { + cpumask_andnot(cpu_associativity_changes_mask, + cpu_associativity_changes_mask, + cpu_sibling_mask(cpu)); + cpu = cpu_last_thread_sibling(cpu); + continue; + } - if (i weight) - ud-next = updates[i]; + for_each_cpu(sibling, cpu_sibling_mask(cpu)) { + ud = updates[i++]; + ud-cpu = sibling; + ud-new_nid = new_nid; + ud-old_nid = numa_cpu_lookup_table[sibling]; +
Re: [PATCH v3 11/31] net: can: mscan: improve clock API use
On 07/23/2013 01:53 PM, Gerhard Sittig wrote: On Mon, Jul 22, 2013 at 14:31 +0200, Marc Kleine-Budde wrote: On 07/22/2013 02:14 PM, Gerhard Sittig wrote: the .get_clock() callback is run from probe() and might allocate resources, introduce a .put_clock() callback that is run from remove() to undo any allocation activities looks good use devm_get_clk() upon lookup (for SYS and REF) to have the clocks put upon driver unload fine assume that resources get prepared but not necessarily enabled in the setup phase, make the open() and close() callbacks of the CAN network device enable and disable a previously acquired and prepared clock I think you should call prepare_enable and disable_unprepare in the open/close functions. After more local research, which totally eliminated the need to pre-enable the CAN related clocks, but might need more discussion as it touches the common gate support, I've learned something more: The CAN clock needs to get enabled during probe() already, since registers get accessed between probe() for the driver and open() for the network device -- while access to peripheral registers crashes the kernel when clocks still are disabled (other hardware may just hang or provide fake data, neither of this is OK). Then call prepare_enable(); before and disable_unprepare(); after accessing the registers. Have a look at the flexcan driver. But I see the point in your suggestion to prepare _and_ enable the clock during open() as well -- to have open() cope with whatever probe() did, after all the driver is shared among platforms, which may differ in what they do during probe(). If you enable a clock to access the registers before open() (and disable it afterwards), it should not harm any architecture that doesn't need this clock enabled. So I will: - make open() of the network device prepare _and_ enable the clock for the peripheral (if acquired during probe()) good - adjust open() because ATM it leaves the clock enabled when the network device operation fails (the error path is incomplete in v3) yes, clock should be disabled if open() fails. - make the MPC512x specific probe() time .get_clock() routine not just prepare but enable the clock as well If needed enable the clock, but disable after probe() has finished. - and of course address all the shutdown counter parts of the above setup paths This results in: - specific chip drivers only need to balance their private get and put clock routines which are called from probe and remove, common paths DTRT for all of them Yes, but clock should not stay enabled between probe() and open(). [...] Removing unnecessary devm_put_clk() calls is orthogonal to that. Putting these in isn't totally wrong (they won't harm, and they do signal visual balance more clearly such that the next person won't stop and wonder), but it's true that they are redundant. Trained persons will wonder as much about their presence as untrained persons wonder about their absence. :) Apparently I'm not well trained yet. The whole point about devm_* is to get rid of auto manually tear down functions. So please remove all devm_put_clk() calls, as it will be called automatically if a driver instance is removed. Marc -- Pengutronix e.K. | Marc Kleine-Budde | Industrial Linux Solutions| Phone: +49-231-2826-924 | Vertretung West/Dortmund | Fax: +49-5121-206917- | Amtsgericht Hildesheim, HRA 2686 | http://www.pengutronix.de | signature.asc Description: OpenPGP digital signature ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH v3 27/31] net: can: mscan: add common clock support for mpc512x
On 07/23/2013 02:07 PM, Gerhard Sittig wrote: [...] + return freq_calc; + +err_invalid: + dev_err(ofdev-dev, invalid clock source specification\n); + return 0; return 0 in case of error? Please add a comment what this 0 means here. The .get_clock() callback is supposed to return the resulting rate after the clock source was determined and the clock subtree was setup. It wasn't (explicitly) documented before (in the non-common-clock case), so I did not bother to comment it in the parallel common-clock case. Yes, but returning 0 in case of error should be documented, as it's very uncommon. But it's true that returning zero in the error case may be unexpected, and I will add a comment in v4 (in all the .get_clock() implementations). I think a one liner stating that the return value is the clock rate and 0 indicates is an invalid clock rate, this meaning an error here, is enough. Marc -- Pengutronix e.K. | Marc Kleine-Budde | Industrial Linux Solutions| Phone: +49-231-2826-924 | Vertretung West/Dortmund | Fax: +49-5121-206917- | Amtsgericht Hildesheim, HRA 2686 | http://www.pengutronix.de | signature.asc Description: OpenPGP digital signature ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH v3 17/31] clk: mpc512x: introduce COMMON_CLK for MPC512x
[ summary: shared gate support desirable? approach acceptable? ] On Mon, Jul 22, 2013 at 14:14 +0200, Gerhard Sittig wrote: this change implements a clock driver for the MPC512x PowerPC platform which follows the COMMON_CLK approach and uses common clock drivers shared with other platforms [ ... ] some of the clock items get pre-enabled in the clock driver to not have them automatically disabled by the underlying clock subsystem because of their being unused -- this approach is desirable because [ ... ] - some help introduce support for and migrate to the common infrastructure, while more appropriate support for specific hardware constraints isn't available yet (remaining changes are strictly internal to the clock driver and won't affect peripheral drivers) This remark was related to the CAN clocks of the MPC512x SoC. The clock subtrees which are involved in generating CAN bitrates include one path from the XTAL to an internal MCLK (this is part of the CCF support for the platform), and another path from the MCLK or yet another IP bus clock to the actual bitrate on the wire (this is taken care of within the mscan(4) driver). The MCLK generation for CAN is documented in the MPC5121e Reference Manual, chapter 5, section 5.2.5 MSCAN Clock Generation. SYS, REF (both internal), PSC_MCLK_IN, and SPDIF_TX (both external) are muxed, gated, and divided. The result is muxed with IP. The result is fed into the MSCAN component and gets muxed with IP again (can't tell why, maybe for backwards compatibility). In parallel to this MCLK block there is SCCR2[25], the BDLC and MSCAN clock enable, documented in section 5.3.1.3 System Clock Control Register 2. So there is a gate that somehow needs to get setup yet isn't part of the visible MCLK chain. The series up to and including v3 approaches the problem by - adding a gate after the second MCLK mux, which gets exported for client lookups and is the MCLK input for the mscan(4) driver - creating that gate for each of the four MSCAN clocks of the SoC, all of them referencing the single enable bit in the SCCR2 register - pre-enabling the MSCAN clocks from within the clock driver, and thus avoid having the clock disabled from the common infrastructure, because disabling one of these clocks had closed the shared gate and thus had broken all other clock uses clkdev registration provides alias names for few clock items [ ... ] [ ... ] + +/* setup the MCLK clock subtree of an individual PSC/MSCAN/SPDIF */ +static void mpc512x_clk_setup_mclk(struct mclk_setup_data *entry) +{ + size_t clks_idx_pub, clks_idx_int; + u32 __iomem *mccr_reg; /* MCLK control register (mux, en, div) */ + u32 __iomem *sccr_reg; /* system clock control register (enable) */ + int sccr_bit; + int div; + + /* derive a few parameters from the component type and index */ + switch (entry-type) { + case MCLK_TYPE_PSC: + clks_idx_pub = MPC512x_CLK_PSC0_MCLK + entry-comp_idx; + clks_idx_int = MPC512x_CLK_MCLKS_FIRST + + (entry-comp_idx) * MCLK_MAX_IDX; + mccr_reg = clkregs-psc_ccr[entry-comp_idx]; + break; + case MCLK_TYPE_MSCAN: + clks_idx_pub = MPC512x_CLK_MSCAN0_MCLK + entry-comp_idx; + clks_idx_int = MPC512x_CLK_MCLKS_FIRST + + (NR_PSCS + entry-comp_idx) * MCLK_MAX_IDX; + mccr_reg = clkregs-mscan_ccr[entry-comp_idx]; + break; + case MCLK_TYPE_SPDIF: + clks_idx_pub = MPC512x_CLK_SPDIF_MCLK; + clks_idx_int = MPC512x_CLK_MCLKS_FIRST + + (NR_PSCS + NR_MSCANS) * MCLK_MAX_IDX; + mccr_reg = clkregs-spccr; + break; + default: + return; + } + if (entry-bit_sccr1 = 0) { + sccr_reg = clkregs-sccr1; + sccr_bit = entry-bit_sccr1; + } else if (entry-bit_sccr2 = 0) { + sccr_reg = clkregs-sccr2; + sccr_bit = entry-bit_sccr2; + } else { + sccr_reg = NULL; + } + + /* + * this was grabbed from the PPC_CLOCK implementation, which + * enforced a specific MCLK divider while the clock was gated + * during setup (that's a documented hardware requirement) + * + * the PPC_CLOCK implementation might even have violated the + * MCLK = IPS constraint, the fixed divider value of 1 + * results in a divider of 2 and thus MCLK = SYS/2 which equals + * CSB which is greater than IPS; the serial port setup may have + * adjusted the divider which the clock setup might have left in + * an undesirable state + * + * initial setup is: + * - MCLK 0 from SYS + * - MCLK DIV such to not exceed the IPS clock + * - MCLK 0 enabled + * - MCLK 1 from MCLK DIV + */ + div = clk_get_rate(clks[MPC512x_CLK_SYS]);
Re: [PATCH V3 2/2] powerpc, perf: BHRB filter configuration should follow the task
On Mon, Jul 22, 2013 at 04:48:16PM +1000, Benjamin Herrenschmidt wrote: On Mon, 2013-07-22 at 12:09 +0530, Anshuman Khandual wrote: These patches have not been applied yet. Would like me to correct these spellings myself and send out again. Please do let me know. Thanks ! No, it's ok, I'll add them to my batch. Usually I assume that perf related stuff goes through acme's perf tree so I might have overlooked them because of that. Michael, you're ok with these ? Which Michael? :) I haven't had time to really get my head around the BHRB code, so I can't really say. cheers ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH] module: ppc64 module CRC relocation fix causes perf issues
On Fri, Jul 19, 2013 at 05:59:30PM -0500, Scott Wood wrote: On 07/17/2013 11:00:45 PM, Anton Blanchard wrote: Hi Scott, What specifically should I do to test it? Could you double check perf annotate works? I'm 99% sure it will but that is what was failing on ppc64. I'm not really sure what it's supposed to look like when perf annotate works. It spits a bunch of unreadable[1] dark-blue-on-black assembly code at me, all with 0.00 : in the left column. Oh, wait -- some lines have 100.00 : on the left, in even-more-unreadable dark-red-on-black. Apart from the annoying colors, is there anything specific I should be looking for? Some sort of error message, or output that actually makes sense? The colours look fine on my terminal, so I don't know what you've done there. If you care you can use --stdio to use the plainer interface, though it still uses colours. That output looks fine in terms of the bug Anton was chasing. As far as only ever hitting one instruction that does look weird. cheers ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [v1][PATCH 1/1] powerpc/ppc64: rename SOFT_DISABLE_INTS with RECONCILE_IRQ_STATE
On Tue, Jul 16, 2013 at 11:09:30AM +0800, Tiejun Chen wrote: The SOFT_DISABLE_INTS seems an odd name for something that updates the software state to be consistent with interrupts being hard disabled, so rename SOFT_DISABLE_INTS with RECONCILE_IRQ_STATE to avoid this confusion. Yes! I have a similar but unfinished patch locally. cheers ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH] powerpc/8xx: Remove last traces of 8XX_MINIMAL_FPEMU
On Tue, Jul 16, 2013 at 10:56:38AM +0200, Paul Bolle wrote: The Kconfig symbol 8XX_MINIMAL_FPEMU was removed in commit 968219fa33 (powerpc/8xx: Remove 8xx specific minimal FPU emulation). But that commit didn't remove all code depending on that symbol. Do so now. Signed-off-by: Paul Bolle pebo...@tiscali.nl --- Not even compile tested! Help yourself to a cross compiler :) https://www.kernel.org/pub/tools/crosstool/ cheers ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH] Fix a typo in pSeries_lpar_hpte_insert()
On Mon, Jul 22, 2013 at 08:54:31PM +0530, Aneesh Kumar K.V wrote: Denis Kirjanov k...@linux-powerpc.org writes: Fix a typo in pSeries_lpar_hpte_insert() Signed-off-by: Denis Kirjanov k...@linux-powerpc.org looks good Reviewed-by: Aneesh Kumar K.V aneesh.ku...@linux.vnet.ibm.com We may want to add the commit that introduced the change ? 801eb73f45371accc78ca9d6d22d647eeb722c11 Yes, as well as describe what the typo is, and what the implications are - ie. what was broken and is now fixed. cheers ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH v2] powerpc: kernel: remove useless code which related with 'max_cpus'
On Mon, Jul 22, 2013 at 12:21:16PM +0530, Srivatsa S. Bhat wrote: On 07/22/2013 12:10 PM, Chen Gang wrote: Since not need 'max_cpus' after the related commit, the related code are useless too, need be removed. The related commit: c1aa687 powerpc: Clean up obsolete code relating to decrementer and timebase The related warning: arch/powerpc/kernel/smp.c:323:43: warning: parameter ‘max_cpus’ set but not used [-Wunused-but-set-parameter] Signed-off-by: Chen Gang gang.c...@asianux.com This version looks good. Agreed. A good follow up patch, or actually series of patches, would be to change the prototype of smp_ops-probe() to return void, and fix all the implementations to no longer return anything. cheers ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [Suggestion] powerpc: xmon: about 'longjmp' related warning.
On Mon, Jul 22, 2013 at 03:02:53PM +0800, Chen Gang wrote: Hello Maintainers: With allmodconfig and EXTRA_CFLAGS=-W, it reports warnings below: arch/powerpc/xmon/xmon.c:3027:6: warning: variable ‘i’ might be clobbered by ‘longjmp’ or ‘vfork’ [-Wclobbered] arch/powerpc/xmon/xmon.c:3068:6: warning: variable ‘i’ might be clobbered by ‘longjmp’ or ‘vfork’ [-Wclobbered] In both these cases we are inside the body of a for loop and we do a if (setjmp) / else block. Although looking at the source the value of i is not modified by the setjmp, I guess it's possible that the compiler might reorder the increment of i inside the setjmp and loose the value when we longjmp. arch/powerpc/xmon/xmon.c:352:48: warning: argument ‘fromipi’ might be clobbered by ‘longjmp’ or ‘vfork’ [-Wclobbered] This one I can't see, but I assume it's a similar case. Excuse me, I am not quite sure about it whether can cause issue or not. I've never seen it get stuck in those loops or anything, but I guess it's possible. The first thing to do would be to analyse the generated assembler code to determine if there really is any possiblity of the value being clobbered, or if it's just a theoretical bug. cheers ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: cpuidle/pseries: Fix kernel command line parameter smt-snooze-delay
On Tue, Jul 23, 2013 at 10:23:57AM +0530, Deepthi Dharwar wrote: smt-snooze-delay is a tun-able provided currently on powerpc to delay the entry of an idle cpu to NAP state. By default, the value is 100us, which is entry criteria for NAP state i.e only if the idle period is above 100us it would enter NAP. Value of -1 disables entry into NAP. This value can be set either through sysfs, ppc64_cpu util or by passing it via kernel command line. Currently this feature is broken when the value is passed via the kernel command line. Has it always been broken? Or just since some commit? This patch aims to fix this, by taking the appropriate action based on the value after the pseries driver is registered. This check is carried on in the back-end driver rather than setup_smt_snooze_delay(), as one is not sure if the cpuidle driver is even registered when setup routine is executed. Also, this fixes re-enabling of NAP states by setting appropriate value without having to reboot using smt-snooze-delay parameter. Also, to note is, smt-snooze-delay is per-cpu variable. This can be used to enable/disable NAP on per-cpu basis using sysfs but when this variable is passed via kernel command line or using the smt-snooze-delay it applies to all the cpus. Per-cpu tuning can only be done via sysfs. Signed-off-by: Deepthi Dharwar deep...@linux.vnet.ibm.com --- arch/powerpc/platforms/pseries/processor_idle.c | 34 ++- 1 file changed, 27 insertions(+), 7 deletions(-) diff --git a/arch/powerpc/platforms/pseries/processor_idle.c b/arch/powerpc/platforms/pseries/processor_idle.c index 4644efa0..8133f50 100644 --- a/arch/powerpc/platforms/pseries/processor_idle.c +++ b/arch/powerpc/platforms/pseries/processor_idle.c @@ -170,18 +170,36 @@ static struct cpuidle_state shared_states[MAX_IDLE_STATE_COUNT] = { void update_smt_snooze_delay(int cpu, int residency) { struct cpuidle_driver *drv = cpuidle_get_driver(); - struct cpuidle_device *dev = per_cpu(cpuidle_devices, cpu); + struct cpuidle_device *dev; if (cpuidle_state_table != dedicated_states) return; - if (residency 0) { - /* Disable the Nap state on that cpu */ - if (dev) - dev-states_usage[1].disable = 1; - } else - if (drv) + if (!drv) + return; + + if (cpu == -1) { + if (residency 0) { + /* Disable NAP on all cpus */ + drv-states[1].disabled = true; + } else { drv-states[1].target_residency = residency; + drv-states[1].disabled = false; + } + return; + } + + dev = per_cpu(cpuidle_devices, cpu); + if (!dev) + return; + + if (residency 0) + dev-states_usage[1].disable = 1; + else { + drv-states[1].target_residency = residency; + drv-states[1].disabled = false; + dev-states_usage[1].disable = 0; Why are we indexing into all these array with '1' ? cheers ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH 1/3] cpuidle/powernv: cpuidle backend driver for powernv
On Tue, Jul 23, 2013 at 02:31:41PM +0530, Deepthi Dharwar wrote: This patch implements a back-end cpuidle driver for powernv calling power7_nap and snooze idle states. This can be extended by adding more idle states in the future to the existing framework. Other than the state table and a few minor details this looks almost identical to the pseries driver. Can we not have a single version in sysdev and isolate just the differences? cheers ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH v2] Fix a typo in pSeries_lpar_hpte_insert()
Commit 801eb73f45371accc78ca9d6d22d647eeb722c11 introduced a bug while checking PTE flags. We have to drop the _PAGE_COHERENT flag when __PAGE_NO_CACHE is set and the cache update policy is not write-through (i.e. _PAGE_WRITETHRU is not set) Signed-off-by: Denis Kirjanov k...@linux-powerpc.org Reviewed-by: Aneesh Kumar K.V aneesh.ku...@linux.vnet.ibm.com CC: Michael Ellerman mich...@ellerman.id.au --- v1-v2: - Updated commit log --- arch/powerpc/platforms/pseries/lpar.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/powerpc/platforms/pseries/lpar.c b/arch/powerpc/platforms/pseries/lpar.c index 02d6e21..8bad880 100644 --- a/arch/powerpc/platforms/pseries/lpar.c +++ b/arch/powerpc/platforms/pseries/lpar.c @@ -146,7 +146,7 @@ static long pSeries_lpar_hpte_insert(unsigned long hpte_group, flags = 0; /* Make pHyp happy */ - if ((rflags _PAGE_NO_CACHE) !(rflags _PAGE_WRITETHRU)) + if ((rflags _PAGE_NO_CACHE) !(rflags _PAGE_WRITETHRU)) hpte_r = ~_PAGE_COHERENT; if (firmware_has_feature(FW_FEATURE_XCMO) !(hpte_r HPTE_R_N)) flags |= H_COALESCE_CAND; -- 1.8.0.2 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [RFC] power/mpc85xx: Add delay after enabling I2C master
On 07/22/2013 05:33 PM, Scott Wood wrote: On Mon, May 13, 2013 at 02:27:08PM -0700, York Sun wrote: Erratum A-006037 indicates I2C controller executes the write to I2CCR only after it sees SCL idle for 64K cycle of internal I2C controller clocks. If during this waiting period, I2C controller is disabled (I2CCR[MEN] set to 0), then the controller could end in bad state, and hang the future access to I2C register. The mpc_i2c_fixup() function tries to recover the bus from a stalled state where the 9th clock pulse wasn't generated. However, this workaround disables and enables I2C controller without meeting waiting requirement of this erratum. This erratum applies to some 85xx SoCs. It is safe to apply to all of them for mpc_i2c_fixup(). Signed-off-by: York Sun york...@freescale.com --- I'd like to get rid of the #ifdef if mpc5121 is OK with the longer delay. Are mpc5121 and mpc85xx the only things that use this? No. 83xx and 86xx also uses this file. But I am only unsure if mpc52xx is OK with this extended delay. I guess they are but I don't have a proof, or someone to confirm. Are you sure the delay always works out to be longer? What is the relationship between fsl_get_sys_freq() and i2c-real_clk? Yes. The max divider from sys clock to i2c clcok is 32K. i2c-real_clk is the clock I2C controller pumps out, not its internal operation clock. In any case, you should send this patch to the i2c maintainer and list. I don't have the name on top of my head. Is that linux-...@vger.kernel.org? York ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH 1/2] Powerpc: Add voltage support in dts file
On 07/22/2013 09:59:04 PM, Haijun Zhang wrote: eSDHC of T4240 had 1.8v voltage support. Add this node to specify eSDHC voltage capacity. If this node not specified eSDHC driver still can read from eSDHC host capacity register. Signed-off-by: Haijun Zhang haijun.zh...@freescale.com Signed-off-by: Anton Vorontsov cbouatmai...@gmail.com --- changes for this patch set: - split from patch [PATCH 1/2] Powerpc: Add - voltage ranges support for T4 Documentation/devicetree/bindings/mmc/fsl-esdhc.txt | 3 +++ arch/powerpc/boot/dts/fsl/t4240si-post.dtsi | 1 + 2 files changed, 4 insertions(+) diff --git a/Documentation/devicetree/bindings/mmc/fsl-esdhc.txt b/Documentation/devicetree/bindings/mmc/fsl-esdhc.txt index bd9be0b..f1ac253 100644 --- a/Documentation/devicetree/bindings/mmc/fsl-esdhc.txt +++ b/Documentation/devicetree/bindings/mmc/fsl-esdhc.txt @@ -19,6 +19,8 @@ Optional properties: bus-width = 1 property. - sdhci,auto-cmd12: specifies that a controller can only handle auto CMD12. + - 3300 3300: specifies that eSDHC controller can support voltages ranges +from 3300 to 3300. 3300 3300 is not a property name -- and the voltage-ranges property should be defined more generically, as is done for mmc-spi-slot.txt. -Scott ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: cpuidle/pseries: Fix kernel command line parameter smt-snooze-delay
On 07/23/2013 07:32 PM, Michael Ellerman wrote: On Tue, Jul 23, 2013 at 10:23:57AM +0530, Deepthi Dharwar wrote: smt-snooze-delay is a tun-able provided currently on powerpc to delay the entry of an idle cpu to NAP state. By default, the value is 100us, which is entry criteria for NAP state i.e only if the idle period is above 100us it would enter NAP. Value of -1 disables entry into NAP. This value can be set either through sysfs, ppc64_cpu util or by passing it via kernel command line. Currently this feature is broken when the value is passed via the kernel command line. Has it always been broken? Or just since some commit? Yes, it is broken since inclusion of pseries back-end driver, around 3.3 kernel time-frame. This patch aims to fix this, by taking the appropriate action based on the value after the pseries driver is registered. This check is carried on in the back-end driver rather than setup_smt_snooze_delay(), as one is not sure if the cpuidle driver is even registered when setup routine is executed. Also, this fixes re-enabling of NAP states by setting appropriate value without having to reboot using smt-snooze-delay parameter. Also, to note is, smt-snooze-delay is per-cpu variable. This can be used to enable/disable NAP on per-cpu basis using sysfs but when this variable is passed via kernel command line or using the smt-snooze-delay it applies to all the cpus. Per-cpu tuning can only be done via sysfs. Signed-off-by: Deepthi Dharwar deep...@linux.vnet.ibm.com --- arch/powerpc/platforms/pseries/processor_idle.c | 34 ++- 1 file changed, 27 insertions(+), 7 deletions(-) diff --git a/arch/powerpc/platforms/pseries/processor_idle.c b/arch/powerpc/platforms/pseries/processor_idle.c index 4644efa0..8133f50 100644 --- a/arch/powerpc/platforms/pseries/processor_idle.c +++ b/arch/powerpc/platforms/pseries/processor_idle.c @@ -170,18 +170,36 @@ static struct cpuidle_state shared_states[MAX_IDLE_STATE_COUNT] = { void update_smt_snooze_delay(int cpu, int residency) { struct cpuidle_driver *drv = cpuidle_get_driver(); -struct cpuidle_device *dev = per_cpu(cpuidle_devices, cpu); +struct cpuidle_device *dev; if (cpuidle_state_table != dedicated_states) return; -if (residency 0) { -/* Disable the Nap state on that cpu */ -if (dev) -dev-states_usage[1].disable = 1; -} else -if (drv) +if (!drv) +return; + +if (cpu == -1) { +if (residency 0) { +/* Disable NAP on all cpus */ +drv-states[1].disabled = true; +} else { drv-states[1].target_residency = residency; +drv-states[1].disabled = false; +} +return; +} + +dev = per_cpu(cpuidle_devices, cpu); +if (!dev) +return; + +if (residency 0) +dev-states_usage[1].disable = 1; +else { +drv-states[1].target_residency = residency; +drv-states[1].disabled = false; +dev-states_usage[1].disable = 0; Why are we indexing into all these array with '1' ? We are disabling/enabling NAP state, which indexes into pseries cpuidle state table array with index value of 1. smt-snooze-delay of -1, disables NAP state. Else, we need to set the residency of NAP state i.e minimum time CPU should spend in NAP state ( based on which menu governor takes a decision on selection of Idle state) there by delaying the entry to NAP state. Thanks for the review. Regards, Deepthi cheers ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [3/4] powerpc/85xx: Add C293PCIE board support
On 07/23/2013 02:47:18 AM, Liu Po-B43644 wrote: +partition@190 { +/* 7MB for User Area */ +reg = 0x0190 0x0070; +label = NAND User area; +}; Above you say there's 4 GiB of NAND, but here you define partitions that only cover 32 MiB. Can I set one partion include all other space(4GB- 32MB) with label name Others? Are you sure you don't want to leave more room for the RFS? And what is the difference between user area and others? diff --git a/arch/powerpc/platforms/85xx/c293pcie.c b/arch/powerpc/platforms/85xx/c293pcie.c new file mode 100644 index 000..75dda12 --- /dev/null +++ b/arch/powerpc/platforms/85xx/c293pcie.c @@ -0,0 +1,82 @@ +/* + * C293PCIE Board Setup + * + * Copyright 2013 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/stddef.h +#include linux/kernel.h +#include linux/pci.h +#include linux/delay.h +#include linux/interrupt.h +#include linux/of_platform.h + +#include asm/time.h +#include asm/machdep.h +#include asm/pci-bridge.h +#include mm/mmu_decl.h +#include asm/prom.h +#include asm/udbg.h +#include asm/mpic.h + +#include sysdev/fsl_soc.h +#include sysdev/fsl_pci.h + +#include mpc85xx.h Are you sure you need all of these? I don't see any delays, for example. Thanks, I'll test and remove redundant includes. Don't base it purely on testing -- you don't want to rely on accidentally picking up a needed include from some other include (which could change down the road). Base it on whether this file uses something declared by the header in question. -Scott ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [RFC] power/mpc85xx: Add delay after enabling I2C master
On 07/23/2013 10:37:46 AM, York Sun wrote: On 07/22/2013 05:33 PM, Scott Wood wrote: On Mon, May 13, 2013 at 02:27:08PM -0700, York Sun wrote: Erratum A-006037 indicates I2C controller executes the write to I2CCR only after it sees SCL idle for 64K cycle of internal I2C controller clocks. If during this waiting period, I2C controller is disabled (I2CCR[MEN] set to 0), then the controller could end in bad state, and hang the future access to I2C register. The mpc_i2c_fixup() function tries to recover the bus from a stalled state where the 9th clock pulse wasn't generated. However, this workaround disables and enables I2C controller without meeting waiting requirement of this erratum. This erratum applies to some 85xx SoCs. It is safe to apply to all of them for mpc_i2c_fixup(). Signed-off-by: York Sun york...@freescale.com --- I'd like to get rid of the #ifdef if mpc5121 is OK with the longer delay. Are mpc5121 and mpc85xx the only things that use this? No. 83xx and 86xx also uses this file. But I am only unsure if mpc52xx is OK with this extended delay. I guess they are but I don't have a proof, or someone to confirm. Are you sure the delay always works out to be longer? What is the relationship between fsl_get_sys_freq() and i2c-real_clk? Yes. The max divider from sys clock to i2c clcok is 32K. i2c-real_clk is the clock I2C controller pumps out, not its internal operation clock. 32K is the max for all implementations? BTW, Where does the 200 come from? Shouldn't it be 100 if you're converting to usec? If you're trying to add some slack, say so rather than having a comment suggest that the output of that formula is 64K cycles. Or is there an implicit assumption that i2c runs at half the system frequency? Is that assumption true for all implementations that have this erratum? In any case, you should send this patch to the i2c maintainer and list. I don't have the name on top of my head. Is that linux-...@vger.kernel.org? Yes, and Wolfram Sang w...@the-dreams.de is the maintainer. This is listed in the MAINTAINERS file. -Scott ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 2/3] cpufreq: pmac64: re-estimate G5 cpufreq transition latency
The latency is in milliseconds scale rather than microseconds based on measurements on iMac G5 and Xscale G5. The patch also enables to use ondemand governor on the latter. Signed-off-by: Aaro Koskinen aaro.koski...@iki.fi --- drivers/cpufreq/pmac64-cpufreq.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/cpufreq/pmac64-cpufreq.c b/drivers/cpufreq/pmac64-cpufreq.c index 674807d..f9e399b 100644 --- a/drivers/cpufreq/pmac64-cpufreq.c +++ b/drivers/cpufreq/pmac64-cpufreq.c @@ -85,7 +85,8 @@ static int (*g5_query_freq)(void); static DEFINE_MUTEX(g5_switch_mutex); -static unsigned long transition_latency; +/* A conservative estimate, based on Xserve G5 and iMac G5 (iSight). */ +static const unsigned long transition_latency = 10 * NSEC_PER_MSEC; #ifdef CONFIG_PMAC_SMU @@ -499,7 +500,6 @@ static int __init g5_neo2_cpufreq_init(struct device_node *cpus) g5_cpu_freqs[1].frequency = max_freq/2; /* Set callbacks */ - transition_latency = 12000; g5_switch_freq = g5_scom_switch_freq; g5_query_freq = g5_scom_query_freq; freq_method = SCOM; @@ -675,7 +675,6 @@ static int __init g5_pm72_cpufreq_init(struct device_node *cpus) g5_cpu_freqs[1].frequency = min_freq; /* Set callbacks */ - transition_latency = CPUFREQ_ETERNAL; g5_switch_volt = g5_pfunc_switch_volt; g5_switch_freq = g5_pfunc_switch_freq; g5_query_freq = g5_pfunc_query_freq; -- 1.8.3.2 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 1/3] cpufreq: pmac64: speed up frequency switch
Some functions on switch path use msleep() which is inaccurate, and depends on HZ. With HZ=100 msleep(1) takes actually over ten times longer. Using usleep_range() we get more accurate sleeps. I measured the pfunc_slewing_done polling to take 300us at max (on 2.3GHz dual-processor Xserve G5), so using 500us sleep there should be fine. With the patch, g5_switch_freq() duration drops from ~50ms to ~10ms on Xserve with HZ=100. Signed-off-by: Aaro Koskinen aaro.koski...@iki.fi --- drivers/cpufreq/pmac64-cpufreq.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/cpufreq/pmac64-cpufreq.c b/drivers/cpufreq/pmac64-cpufreq.c index 7ba4234..674807d 100644 --- a/drivers/cpufreq/pmac64-cpufreq.c +++ b/drivers/cpufreq/pmac64-cpufreq.c @@ -141,7 +141,7 @@ static void g5_vdnap_switch_volt(int speed_mode) pmf_call_one(pfunc_vdnap0_complete, args); if (done) break; - msleep(1); + usleep_range(1000, 1000); } if (done == 0) printk(KERN_WARNING cpufreq: Timeout in clock slewing !\n); @@ -240,7 +240,7 @@ static void g5_pfunc_switch_volt(int speed_mode) if (pfunc_cpu1_volt_low) pmf_call_one(pfunc_cpu1_volt_low, NULL); } - msleep(10); /* should be faster , to fix */ + usleep_range(1, 1); /* should be faster , to fix */ } /* @@ -285,7 +285,7 @@ static int g5_pfunc_switch_freq(int speed_mode) pmf_call_one(pfunc_slewing_done, args); if (done) break; - msleep(1); + usleep_range(500, 500); } if (done == 0) printk(KERN_WARNING cpufreq: Timeout in clock slewing !\n); -- 1.8.3.2 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [RFC] power/mpc85xx: Add delay after enabling I2C master
On 07/23/2013 11:43 AM, Scott Wood wrote: Yes. The max divider from sys clock to i2c clcok is 32K. i2c-real_clk is the clock I2C controller pumps out, not its internal operation clock. 32K is the max for all implementations? Yes, according to application note 2919 (published). BTW, Where does the 200 come from? Shouldn't it be 100 if you're converting to usec? If you're trying to add some slack, say so rather than having a comment suggest that the output of that formula is 64K cycles. Or is there an implicit assumption that i2c runs at half the system frequency? Is that assumption true for all implementations that have this erratum? The clock source is half the sysclk. This erratum applies to selected 85xx SoCs. I have confirmed with application team that it is safe to apply the delay to all 85xx. In any case, you should send this patch to the i2c maintainer and list. I don't have the name on top of my head. Is that linux-...@vger.kernel.org? Yes, and Wolfram Sang w...@the-dreams.de is the maintainer. This is listed in the MAINTAINERS file. I can resubmit this patch after the feedback is addressed. York ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 3/3] cpufreq: pmac64: enable cpufreq on iMac G5 (iSight) model
Enable cpufreq on iMac G5 (iSight) model. Tested with the 2.1 GHz version. Signed-off-by: Aaro Koskinen aaro.koski...@iki.fi --- drivers/cpufreq/pmac64-cpufreq.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/cpufreq/pmac64-cpufreq.c b/drivers/cpufreq/pmac64-cpufreq.c index f9e399b..1f352e5 100644 --- a/drivers/cpufreq/pmac64-cpufreq.c +++ b/drivers/cpufreq/pmac64-cpufreq.c @@ -399,7 +399,8 @@ static int __init g5_neo2_cpufreq_init(struct device_node *cpus) /* Check supported platforms */ if (of_machine_is_compatible(PowerMac8,1) || of_machine_is_compatible(PowerMac8,2) || - of_machine_is_compatible(PowerMac9,1)) + of_machine_is_compatible(PowerMac9,1) || + of_machine_is_compatible(PowerMac12,1)) use_volts_smu = 1; else if (of_machine_is_compatible(PowerMac11,2)) use_volts_vdnap = 1; -- 1.8.3.2 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH 1/3] cpufreq: pmac64: speed up frequency switch
On Tue, 2013-07-23 at 23:20 +0200, Rafael J. Wysocki wrote: All looks good in the patchset from 1 feet (or more), but I need Ben to speak here. I want to give it a quick spin on the HW here, I'll ack then. But yes, it looks good. Cheers, Ben. ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH 1/3] cpufreq: pmac64: speed up frequency switch
On Tuesday, July 23, 2013 11:24:37 PM Aaro Koskinen wrote: Some functions on switch path use msleep() which is inaccurate, and depends on HZ. With HZ=100 msleep(1) takes actually over ten times longer. Using usleep_range() we get more accurate sleeps. I measured the pfunc_slewing_done polling to take 300us at max (on 2.3GHz dual-processor Xserve G5), so using 500us sleep there should be fine. With the patch, g5_switch_freq() duration drops from ~50ms to ~10ms on Xserve with HZ=100. Signed-off-by: Aaro Koskinen aaro.koski...@iki.fi All looks good in the patchset from 1 feet (or more), but I need Ben to speak here. Thanks, Rafael --- drivers/cpufreq/pmac64-cpufreq.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/cpufreq/pmac64-cpufreq.c b/drivers/cpufreq/pmac64-cpufreq.c index 7ba4234..674807d 100644 --- a/drivers/cpufreq/pmac64-cpufreq.c +++ b/drivers/cpufreq/pmac64-cpufreq.c @@ -141,7 +141,7 @@ static void g5_vdnap_switch_volt(int speed_mode) pmf_call_one(pfunc_vdnap0_complete, args); if (done) break; - msleep(1); + usleep_range(1000, 1000); } if (done == 0) printk(KERN_WARNING cpufreq: Timeout in clock slewing !\n); @@ -240,7 +240,7 @@ static void g5_pfunc_switch_volt(int speed_mode) if (pfunc_cpu1_volt_low) pmf_call_one(pfunc_cpu1_volt_low, NULL); } - msleep(10); /* should be faster , to fix */ + usleep_range(1, 1); /* should be faster , to fix */ } /* @@ -285,7 +285,7 @@ static int g5_pfunc_switch_freq(int speed_mode) pmf_call_one(pfunc_slewing_done, args); if (done) break; - msleep(1); + usleep_range(500, 500); } if (done == 0) printk(KERN_WARNING cpufreq: Timeout in clock slewing !\n); -- I speak only for myself. Rafael J. Wysocki, Intel Open Source Technology Center. ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH 2/2] cpuidle: export cpuidle_idle_call symbol
On Tuesday, July 23, 2013 05:28:01 PM Dongsheng Wang wrote: From: Wang Dongsheng dongsheng.w...@freescale.com Export cpuidle_idle_call symbol, make this function can be invoked in the module. Why? Rafael Signed-off-by: Wang Dongsheng dongsheng.w...@freescale.com --- Branch: pm-cpuidle drivers/cpuidle/cpuidle.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c index 534320a..d0a61d6 100644 --- a/drivers/cpuidle/cpuidle.c +++ b/drivers/cpuidle/cpuidle.c @@ -168,6 +168,7 @@ int cpuidle_idle_call(void) return 0; } +EXPORT_SYMBOL_GPL(cpuidle_idle_call); /** * cpuidle_install_idle_handler - installs the cpuidle idle loop handler -- I speak only for myself. Rafael J. Wysocki, Intel Open Source Technology Center. ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH 1/2] cpuidle: fix cpu idle driver as a module can not remove
On Tuesday, July 23, 2013 05:28:00 PM Dongsheng Wang wrote: From: Wang Dongsheng dongsheng.w...@freescale.com The module can not be removed when execute rmmod. rmmod not use --force. Log: root:~# rmmod cpuidle-e500 incs[9], decs[1] rmmod: can't unload 'cpuidle_e500': Resource temporarily unavailable Signed-off-by: Wang Dongsheng dongsheng.w...@freescale.com Can you please check the current linux-next branch of the linux-pm.git tree and see if that doesn't conflict with the material in there? Also please explain in the changelog how your changes help to fix the problem. Thanks, Rafael --- Branch: pm-cpuidle drivers/cpuidle/cpuidle.c | 7 +++ 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c index fdc432f..534320a 100644 --- a/drivers/cpuidle/cpuidle.c +++ b/drivers/cpuidle/cpuidle.c @@ -386,6 +386,9 @@ static int __cpuidle_register_device(struct cpuidle_device *dev) goto err_coupled; dev-registered = 1; + + module_put(drv-owner); + return 0; err_coupled: @@ -432,8 +435,6 @@ EXPORT_SYMBOL_GPL(cpuidle_register_device); */ void cpuidle_unregister_device(struct cpuidle_device *dev) { - struct cpuidle_driver *drv = cpuidle_get_cpu_driver(dev); - if (dev-registered == 0) return; @@ -448,8 +449,6 @@ void cpuidle_unregister_device(struct cpuidle_device *dev) cpuidle_coupled_unregister_device(dev); cpuidle_resume_and_unlock(); - - module_put(drv-owner); } EXPORT_SYMBOL_GPL(cpuidle_unregister_device); -- I speak only for myself. Rafael J. Wysocki, Intel Open Source Technology Center. ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [1/4] powerpc/85xx: Add SEC6.0 device tree
On 07/23/2013 03:01:17 AM, Liu Po-B43644 wrote: -Original Message- From: Wood Scott-B07421 Sent: Tuesday, July 23, 2013 6:41 AM To: Liu Po-B43644 Cc: linuxppc-...@ozlabs.org; Hu Mingkai-B21284 Subject: Re: [1/4] powerpc/85xx: Add SEC6.0 device tree On Thu, Apr 25, 2013 at 09:54:14AM +0800, Po Liu wrote: From: Mingkai Hu mingkai...@freescale.com Add device tree for SEC 6.0 used on C29x silicon. Signed-off-by: Mingkai Hu mingkai...@freescale.com Singed-off-by: Po Liu po@freescale.com I've heard of patches being flamed, but here we want signing, not singeing. :-) Don't forget that you can use the -s option to have git add the signoff for you. --- Base on git://git.am.freescale.net/gitolite/mirrors/linux-2.6.git This URL is not accessible outside Freescale, so don't reference it when posting patches publicly. If your patch is against the latest upstream code, you don't need to say anything special about that. You only need to make a note when it's against some other yet-to-be-merged tree or patch. +compatible = fsl,sec-v6.0, fsl,sec-v5.2, + fsl,sec-v5.0, fsl,sec-v4.4, + fsl,sec-v4.0; +fsl,sec-era = 6; +#address-cells = 1; +#size-cells = 1; + +jr@1000 { +compatible = fsl,sec-v6.0-job-ring, + fsl,sec-v5.2-job-ring, + fsl,sec-v5.0-job-ring, + fsl,sec-v4.4-job-ring, + fsl,sec-v4.0-job-ring; +reg= 0x1000 0x1000; +}; + +jr@2000 { +compatible = fsl,sec-v6.0-job-ring, + fsl,sec-v5.2-job-ring, + fsl,sec-v5.0-job-ring, + fsl,sec-v4.4-job-ring, + fsl,sec-v4.0-job-ring; +reg= 0x2000 0x1000; +}; You claim compatibility with a bunch of prior SECs, but sec-v5.2 has four job rings and an rtic node. Likewise for the previous compatibles listed. This has two job rings and no rtic. So, shall I remove fsl,sec-v5.2,fsl,sec-v5.0, fsl,sec-v4.4, fsl,sec-v4.0 since all other SEC with 4 job rings? and only leave fsl,sec-v6.0? Yes, I think so. Can you point to where in the SEC v4.0 binding (I don't see a binding for the subsequent versions), it says that these are optional? I found SEC V4.0 in file qoriq-sec4.0-0.dtsi. If fsl,sec-v4.0 not in the compatible list, it is no use in this compatible list. But seems keep the fsl,sec-v4.0-job-ring job ring compatible is ok. Is that what you were ask? No, I was talking about binding documents: Documentation/devicetree/bindings/crypto/ -Scott ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH] Update compilation flags with core specific options
On 07/02/2013 06:20:04 AM, Catalin Udma wrote: If CONFIG_E500 is enabled, the compilation flags are updated specifying the target core -mcpu=e5500/e500mc/8540 Also remove -Wa,-me500, being incompatible with -mcpu=e5500/e6500 The assembler option is redundant if the -mcpu= flag is set. The patch fixes the kernel compilation problem for e5500/e6500 when using gcc option -mcpu=e5500/e6500. Signed-off-by: Catalin Udma catalin.u...@freescale.com --- arch/powerpc/Makefile | 13 - 1 files changed, 12 insertions(+), 1 deletions(-) diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile index 0624909..82808b5 100644 --- a/arch/powerpc/Makefile +++ b/arch/powerpc/Makefile @@ -140,6 +140,18 @@ ifeq ($(CONFIG_6xx),y) KBUILD_CFLAGS += -mcpu=powerpc endif +ifeq ($(CONFIG_E500),y) +ifeq ($(CONFIG_64BIT),y) +KBUILD_CFLAGS += -mcpu=e5500 +else +ifeq ($(CONFIG_PPC_E500MC),y) +KBUILD_CFLAGS += -mcpu=e500mc +else +KBUILD_CFLAGS += -mcpu=8540 +endif +endif +endif + # Work around a gcc code-gen bug with -fno-omit-frame-pointer. ifeq ($(CONFIG_FUNCTION_TRACER),y) KBUILD_CFLAGS += -mno-sched-epilog @@ -147,7 +159,6 @@ endif cpu-as-$(CONFIG_4xx) += -Wa,-m405 cpu-as-$(CONFIG_ALTIVEC) += -Wa,-maltivec -cpu-as-$(CONFIG_E500) += -Wa,-me500 cpu-as-$(CONFIG_E200) += -Wa,-me200 KBUILD_AFLAGS += $(cpu-as-y) This breaks the vdso for e500v1/v2 (userspace dies with SIGILL), since KBUILD_CFLAGS doesn't get used when building asm files, and the vdso uses mftbu/mftbl which are not being assembled to the form that e500v1/v2 support. We should be setting -mcpu=whatever and -msoft-float in both CFLAGS and AFLAGS, since we don't call as directly, and target selection should not differ based on whether we're building a C file or an asm file. -Scott ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH v2] powerpc: kernel: remove useless code which related with 'max_cpus'
On 07/23/2013 09:44 PM, Michael Ellerman wrote: On Mon, Jul 22, 2013 at 12:21:16PM +0530, Srivatsa S. Bhat wrote: On 07/22/2013 12:10 PM, Chen Gang wrote: Since not need 'max_cpus' after the related commit, the related code are useless too, need be removed. The related commit: c1aa687 powerpc: Clean up obsolete code relating to decrementer and timebase The related warning: arch/powerpc/kernel/smp.c:323:43: warning: parameter ‘max_cpus’ set but not used [-Wunused-but-set-parameter] Signed-off-by: Chen Gang gang.c...@asianux.com This version looks good. Agreed. A good follow up patch, or actually series of patches, would be to change the prototype of smp_ops-probe() to return void, and fix all the implementations to no longer return anything. Hmm... normally, a function need have a return value, it will make it more extensible (especially, it is an API which need be implemented in various sub modules). Even though the return value may be useless, now, if the performance is not quite important in our case, I still suggest to have it (especially each various original implementation already has it). cheers Thanks. -- Chen Gang ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [Suggestion] powerpc: xmon: about 'longjmp' related warning.
On 07/23/2013 09:58 PM, Michael Ellerman wrote: On Mon, Jul 22, 2013 at 03:02:53PM +0800, Chen Gang wrote: Hello Maintainers: With allmodconfig and EXTRA_CFLAGS=-W, it reports warnings below: arch/powerpc/xmon/xmon.c:3027:6: warning: variable ‘i’ might be clobbered by ‘longjmp’ or ‘vfork’ [-Wclobbered] arch/powerpc/xmon/xmon.c:3068:6: warning: variable ‘i’ might be clobbered by ‘longjmp’ or ‘vfork’ [-Wclobbered] In both these cases we are inside the body of a for loop and we do a if (setjmp) / else block. Although looking at the source the value of i is not modified by the setjmp, I guess it's possible that the compiler might reorder the increment of i inside the setjmp and loose the value when we longjmp. I should continue to confirm the details based on your valuable information, thanks. arch/powerpc/xmon/xmon.c:352:48: warning: argument ‘fromipi’ might be clobbered by ‘longjmp’ or ‘vfork’ [-Wclobbered] This one I can't see, but I assume it's a similar case. OK, I should continue for it. Excuse me, I am not quite sure about it whether can cause issue or not. I've never seen it get stuck in those loops or anything, but I guess it's possible. OK, I should make the confirmation. The first thing to do would be to analyse the generated assembler code to determine if there really is any possiblity of the value being clobbered, or if it's just a theoretical bug. Thank you for your valuable information again. Excuse me, I have to do another things within this month, so I should provide the confirmation within next month (2013-08-31), is it OK (no reply means OK). Welcome any suggestions or completions. Thanks. -- Chen Gang ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 1/2 V2] Powerpc: Add voltage support in dts file
eSDHC of T4240 had 1.8v voltage support. Add this node to specify eSDHC voltage capacity. If this node not specified eSDHC driver still can read from eSDHC host capacity register. Signed-off-by: Haijun Zhang haijun.zh...@freescale.com Signed-off-by: Anton Vorontsov cbouatmai...@gmail.com --- changes for v2: - rewrite the voltage-ranges description Documentation/devicetree/bindings/mmc/fsl-esdhc.txt | 4 arch/powerpc/boot/dts/fsl/t4240si-post.dtsi | 1 + 2 files changed, 5 insertions(+) diff --git a/Documentation/devicetree/bindings/mmc/fsl-esdhc.txt b/Documentation/devicetree/bindings/mmc/fsl-esdhc.txt index bd9be0b..b7943f3 100644 --- a/Documentation/devicetree/bindings/mmc/fsl-esdhc.txt +++ b/Documentation/devicetree/bindings/mmc/fsl-esdhc.txt @@ -19,6 +19,9 @@ Optional properties: bus-width = 1 property. - sdhci,auto-cmd12: specifies that a controller can only handle auto CMD12. + - voltage-ranges : two cells are required, first cell specifies minimum +slot voltage (mV), second cell specifies maximum slot voltage (mV). +Several ranges could be specified. Example: @@ -29,4 +32,5 @@ sdhci@2e000 { interrupt-parent = ipic; /* Filled in by U-Boot */ clock-frequency = 0; + voltage-ranges = 3300 3300; }; diff --git a/arch/powerpc/boot/dts/fsl/t4240si-post.dtsi b/arch/powerpc/boot/dts/fsl/t4240si-post.dtsi index bd611a9..567d0fb 100644 --- a/arch/powerpc/boot/dts/fsl/t4240si-post.dtsi +++ b/arch/powerpc/boot/dts/fsl/t4240si-post.dtsi @@ -399,6 +399,7 @@ sdhc@114000 { compatible = fsl,t4240-esdhc, fsl,esdhc; sdhci,auto-cmd12; + voltage-ranges = 1800 1800; }; /include/ qoriq-i2c-0.dtsi /include/ qoriq-i2c-1.dtsi -- 1.8.0 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH v2] powerpc: kernel: remove useless code which related with 'max_cpus'
On Wed, Jul 24, 2013 at 08:28:07AM +0800, Chen Gang wrote: On 07/23/2013 09:44 PM, Michael Ellerman wrote: On Mon, Jul 22, 2013 at 12:21:16PM +0530, Srivatsa S. Bhat wrote: On 07/22/2013 12:10 PM, Chen Gang wrote: Since not need 'max_cpus' after the related commit, the related code are useless too, need be removed. The related commit: c1aa687 powerpc: Clean up obsolete code relating to decrementer and timebase The related warning: arch/powerpc/kernel/smp.c:323:43: warning: parameter ‘max_cpus’ set but not used [-Wunused-but-set-parameter] Signed-off-by: Chen Gang gang.c...@asianux.com This version looks good. Agreed. A good follow up patch, or actually series of patches, would be to change the prototype of smp_ops-probe() to return void, and fix all the implementations to no longer return anything. Hmm... normally, a function need have a return value, it will make it more extensible (especially, it is an API which need be implemented in various sub modules). A function doesn't need a return value, and if it needs one in future then we'll add it then. We don't carry code around just in case. Even though the return value may be useless, now, if the performance is not quite important in our case, I still suggest to have it (especially each various original implementation already has it). It's dead code, it should be removed. cheers ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH v2] powerpc/fsl-booke: Work around erratum A-006958
Erratum A-006598 says that 64-bit mftb is not atomic -- it's subject to a similar race condition as doing mftbu/mftbl on 32-bit. The lower half of timebase is updated before the upper half; thus, we can share the workaround for a similar bug on Cell. This workaround involves looping if the lower half of timebase is zero, thus avoiding the need for a scratch register (other than CR0). This workaround must be avoided when the timebase is frozen, such as during the timebase sync code. This deals with kernel and vdso accesses, but other userspace accesses will of course need to be fixed elsewhere. Signed-off-by: Scott Wood scottw...@freescale.com Cc: Zhao Chenhui chenhui.z...@freescale.com Cc: Andy Fleming aflem...@freescale.com Cc: James Yang james.y...@freescale.com --- v2: re-use the existing cell workaround arch/powerpc/include/asm/cputable.h | 9 +++-- arch/powerpc/include/asm/ppc_asm.h | 2 +- arch/powerpc/include/asm/reg.h | 2 +- arch/powerpc/platforms/85xx/smp.c | 23 +++ 4 files changed, 32 insertions(+), 4 deletions(-) diff --git a/arch/powerpc/include/asm/cputable.h b/arch/powerpc/include/asm/cputable.h index 6f3887d..0d4939b 100644 --- a/arch/powerpc/include/asm/cputable.h +++ b/arch/powerpc/include/asm/cputable.h @@ -371,14 +371,19 @@ extern const char *powerpc_base_platform; #define CPU_FTRS_E500MC(CPU_FTR_USE_TB | CPU_FTR_NODSISRALIGN | \ CPU_FTR_L2CSR | CPU_FTR_LWSYNC | CPU_FTR_NOEXECUTE | \ CPU_FTR_DBELL | CPU_FTR_DEBUG_LVL_EXC | CPU_FTR_EMB_HV) +/* + * e5500/e6500 erratum A-006958 is a timebase bug that can use the + * same workaround as CPU_FTR_CELL_TB_BUG. + */ #define CPU_FTRS_E5500 (CPU_FTR_USE_TB | CPU_FTR_NODSISRALIGN | \ CPU_FTR_L2CSR | CPU_FTR_LWSYNC | CPU_FTR_NOEXECUTE | \ CPU_FTR_DBELL | CPU_FTR_POPCNTB | CPU_FTR_POPCNTD | \ - CPU_FTR_DEBUG_LVL_EXC | CPU_FTR_EMB_HV) + CPU_FTR_DEBUG_LVL_EXC | CPU_FTR_EMB_HV | CPU_FTR_CELL_TB_BUG) #define CPU_FTRS_E6500 (CPU_FTR_USE_TB | CPU_FTR_NODSISRALIGN | \ CPU_FTR_L2CSR | CPU_FTR_LWSYNC | CPU_FTR_NOEXECUTE | \ CPU_FTR_DBELL | CPU_FTR_POPCNTB | CPU_FTR_POPCNTD | \ - CPU_FTR_DEBUG_LVL_EXC | CPU_FTR_EMB_HV | CPU_FTR_ALTIVEC_COMP) + CPU_FTR_DEBUG_LVL_EXC | CPU_FTR_EMB_HV | CPU_FTR_ALTIVEC_COMP | \ + CPU_FTR_CELL_TB_BUG) #define CPU_FTRS_GENERIC_32(CPU_FTR_COMMON | CPU_FTR_NODSISRALIGN) /* 64-bit CPUs */ diff --git a/arch/powerpc/include/asm/ppc_asm.h b/arch/powerpc/include/asm/ppc_asm.h index 2f1b6c5..fe713b6 100644 --- a/arch/powerpc/include/asm/ppc_asm.h +++ b/arch/powerpc/include/asm/ppc_asm.h @@ -443,7 +443,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_601) #define ISYNC_601 #endif -#ifdef CONFIG_PPC_CELL +#if defined(CONFIG_PPC_CELL) || defined(CONFIG_PPC_FSL_BOOK3E) #define MFTB(dest) \ 90:mftb dest; \ BEGIN_FTR_SECTION_NESTED(96); \ diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h index 5d7d9c2..aa49fdb 100644 --- a/arch/powerpc/include/asm/reg.h +++ b/arch/powerpc/include/asm/reg.h @@ -1116,7 +1116,7 @@ : memory) #ifdef __powerpc64__ -#ifdef CONFIG_PPC_CELL +#if defined(CONFIG_PPC_CELL) || defined(CONFIG_PPC_FSL_BOOK3E) #define mftb() ({unsigned long rval; \ asm volatile( \ 90:mftb %0;\n \ diff --git a/arch/powerpc/platforms/85xx/smp.c b/arch/powerpc/platforms/85xx/smp.c index 5ced4f5..f60eae2 100644 --- a/arch/powerpc/platforms/85xx/smp.c +++ b/arch/powerpc/platforms/85xx/smp.c @@ -69,7 +69,30 @@ static void mpc85xx_give_timebase(void) tb_req = 0; mpc85xx_timebase_freeze(1); +#ifdef CONFIG_PPC64 + /* +* e5500/e6500 have a workaround for erratum A-006958 in place +* that will reread the timebase until TBL is non-zero. +* That would be a bad thing when the timebase is frozen. +* +* Thus, we read it manually, and instead of checking that +* TBL is non-zero, we ensure that TB does not change. We don't +* do that for the main mftb implementation, because it requires +* a scratch register +*/ + { + u64 prev; + + asm volatile(mftb %0 : =r (timebase)); + + do { + prev = timebase; + asm volatile(mftb %0 : =r (timebase)); + } while (prev != timebase); + } +#else timebase = get_tb(); +#endif mb(); tb_valid = 1; -- 1.8.1.2 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH v2] powerpc: kernel: remove useless code which related with 'max_cpus'
On 07/24/2013 09:16 AM, Michael Ellerman wrote: On Wed, Jul 24, 2013 at 08:28:07AM +0800, Chen Gang wrote: On 07/23/2013 09:44 PM, Michael Ellerman wrote: On Mon, Jul 22, 2013 at 12:21:16PM +0530, Srivatsa S. Bhat wrote: On 07/22/2013 12:10 PM, Chen Gang wrote: Since not need 'max_cpus' after the related commit, the related code are useless too, need be removed. The related commit: c1aa687 powerpc: Clean up obsolete code relating to decrementer and timebase The related warning: arch/powerpc/kernel/smp.c:323:43: warning: parameter ‘max_cpus’ set but not used [-Wunused-but-set-parameter] Signed-off-by: Chen Gang gang.c...@asianux.com This version looks good. Agreed. A good follow up patch, or actually series of patches, would be to change the prototype of smp_ops-probe() to return void, and fix all the implementations to no longer return anything. Hmm... normally, a function need have a return value, it will make it more extensible (especially, it is an API which need be implemented in various sub modules). A function doesn't need a return value, and if it needs one in future then we'll add it then. We don't carry code around just in case. But for API (also include the internal API), at least, better to always provide the return value which can indicate failure by negative number (if succeed can return the meanness value, e.g. the number of cpus). Even though the return value may be useless, now, if the performance is not quite important in our case, I still suggest to have it (especially each various original implementation already has it). It's dead code, it should be removed. For API, if not cause the real world issue, better to keep compatible (especially, the return value still can indicate failure by negative number). Thanks. -- Chen Gang ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
RE: [PATCH 2/2] cpuidle: export cpuidle_idle_call symbol
-Original Message- From: Rafael J. Wysocki [mailto:r...@sisk.pl] Sent: Wednesday, July 24, 2013 5:33 AM To: Wang Dongsheng-B40534 Cc: daniel.lezc...@linaro.org; linux...@vger.kernel.org; linuxppc- d...@lists.ozlabs.org Subject: Re: [PATCH 2/2] cpuidle: export cpuidle_idle_call symbol On Tuesday, July 23, 2013 05:28:01 PM Dongsheng Wang wrote: From: Wang Dongsheng dongsheng.w...@freescale.com Export cpuidle_idle_call symbol, make this function can be invoked in the module. Why? On powerpc platform, there is already have cpu idle implementation. I want use cpuidle framework to control various low power modes. But need to be compatible with the current implementation. And driver should be as a module, The user can using this module at any time. We need cpuidle_idle_call to drive the new implementation in modules. Thanks. - dongsheng Rafael ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH v4 0/11] EEH Followup Fixes (II)
The series of patches bases on linux-poerpc-next initially and intends to resolve the following problems: - On pSeries platform, the EEH doesn't work after PHB hotplug with drmgr. The root cause is that the EEH resources ( EEH devices, EEH caches) aren't released correctly. For the problem, we add one hook (pcibios_stop_dev), which is called on pci_stop_and_remove_device(). In pcibios_stop_dev(), we release the EEH resources. - Another issue is that we need put the domain (PE or PHB) into quite state while doing reset on that domain. However, some deivces in the domain might not have EEH sensitive drivers, or even don't have driver. Those deivces can't be put into quite state and possibly keep issuing PCI-CFG or MMIO request during resetting the domain. That possibly causes the failure of reset and eventually failure of EEH recovery. For the issue, we introduces so-called partial hotplug. That means, those devices without driver or without EEH sensitive driver are removed before doing reset, and plugged (probed) into the system after reset. - We need traverse EEH devices of one specific PE with safe variant of list tranverse function. The EEH device might be removed while doing iteration. - When doing plug for PCI bus, we need check if we need reassign the resources for subordinate devices (PCI_REASSIGN_ALL_RSRC) and do that accordingly. The patchset is verified on pSeires and PowerNV platforms: pSeries Platform: drmgr -c phb -r -s PHB 513 drmgr -c phb -a -s PHB 513 errinjct eeh -f 1 -s net/eth2 PowerNV Platform: cd /sys/devices/pci0005:00/0005:00:00.0/0005:01:00.0/0005:02:08.0/0005:80:00.0/0005:90:01.0 while true; do od -x config /dev/null; sleep 1; done echo 1 /sys/kernel/debug/powerpc/PCI0005/err_injct --- v3 - v4: * Add some comments to explain why we needn't check the return value of pci_scan_slot() in pcibios_add_pci_devices(). * Check PCI_PROBE_ONLY while assigning those unassigned resources in pcibios_finish_adding_to_bus(). v2 - v3: * Make pcibios_add_pci_devices() to support partial hotplug according to Ben's comments. arch/powerpc/kernel/pci_of_scan.c has been adjusted for that. * Use pcibios_add_pci_devices() to do partial hotplug inside eeh_reset_device(). * Introduce flag EEH_DEV_SYSFS to trace the state of sysfs entries of the EEH device (then PCI device) to avoid race condition during partial hotplug. v1 - v2: * Rebase to 3.11.rc1 in order to use pcibios_release_device(). * Use pcibios_release_device() to release EEH cache and detach EEH device from PCI device. * Remove reference to PCI device in EEH cache since we're relying on pcibios_release_device(). * PCI device instance (struct pci_dev) isn't available during BAR restore and avoid use the instance that time. * Fix unbalanced enable for IRQ in eeh_driver.c * Retest the series of patches on Firebird-L/VPL3/VPL4 --- arch/powerpc/include/asm/eeh.h | 30 -- arch/powerpc/include/asm/pci-bridge.h|1 - arch/powerpc/kernel/eeh.c| 70 +++ arch/powerpc/kernel/eeh_cache.c | 18 ++ arch/powerpc/kernel/eeh_driver.c | 77 +- arch/powerpc/kernel/eeh_pe.c | 58 --- arch/powerpc/kernel/eeh_sysfs.c | 21 +++ arch/powerpc/kernel/pci-common.c |2 + arch/powerpc/kernel/pci-hotplug.c| 49 arch/powerpc/kernel/pci_of_scan.c| 56 +- arch/powerpc/platforms/powernv/eeh-powernv.c | 17 +- arch/powerpc/platforms/pseries/eeh_pseries.c | 67 +- drivers/pci/hotplug/rpadlpar_core.c |1 - 13 files changed, 327 insertions(+), 140 deletions(-) Thanks, Gavin ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 04/11] PCI/hotplug: Needn't remove EEH cache again
Since pcibios_release_device() called by pci_stop_and_remove_bus_device() has removed the EEH cache, we needn't do that again. Cc: Bjorn Helgaas bhelg...@google.com Acked-by: Bjorn Helgaas bhelg...@google.com Signed-off-by: Gavin Shan sha...@linux.vnet.ibm.com --- drivers/pci/hotplug/rpadlpar_core.c |1 - 1 files changed, 0 insertions(+), 1 deletions(-) diff --git a/drivers/pci/hotplug/rpadlpar_core.c b/drivers/pci/hotplug/rpadlpar_core.c index b29e20b..bb7af78 100644 --- a/drivers/pci/hotplug/rpadlpar_core.c +++ b/drivers/pci/hotplug/rpadlpar_core.c @@ -388,7 +388,6 @@ int dlpar_remove_pci_slot(char *drc_name, struct device_node *dn) /* Remove the EADS bridge device itself */ BUG_ON(!bus-self); pr_debug(PCI: Now removing bridge device %s\n, pci_name(bus-self)); - eeh_remove_bus_device(bus-self, true); pci_stop_and_remove_bus_device(bus-self); return 0; -- 1.7.5.4 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 05/11] powerpc/eeh: Keep PE during hotplug
When we do normal hotplug, the PE shouldn't be kept. However, we need the PE if the hotplug caused by EEH errors. Since we remove EEH device through the PCI hook pcibios_stop_dev(), the flag purge_pe passed to various functions is meaningless. So the patch removes the meaningless flag and introduce new flag EEH_PE_KEEP to save the PE while doing hotplug during EEH error recovery. Signed-off-by: Gavin Shan sha...@linux.vnet.ibm.com --- arch/powerpc/include/asm/eeh.h| 11 +-- arch/powerpc/include/asm/pci-bridge.h |1 - arch/powerpc/kernel/eeh.c | 28 ++-- arch/powerpc/kernel/eeh_driver.c |7 +-- arch/powerpc/kernel/eeh_pe.c |7 +++ arch/powerpc/kernel/pci-hotplug.c | 26 +- 6 files changed, 20 insertions(+), 60 deletions(-) diff --git a/arch/powerpc/include/asm/eeh.h b/arch/powerpc/include/asm/eeh.h index d9d35c2..2ce22d7 100644 --- a/arch/powerpc/include/asm/eeh.h +++ b/arch/powerpc/include/asm/eeh.h @@ -55,6 +55,8 @@ struct device_node; #define EEH_PE_RECOVERING (1 1)/* Recovering PE*/ #define EEH_PE_PHB_DEAD(1 2)/* Dead PHB */ +#define EEH_PE_KEEP(1 8)/* Keep PE on hotplug */ + struct eeh_pe { int type; /* PE type: PHB/Bus/Device */ int state; /* PE EEH dependent mode*/ @@ -193,7 +195,7 @@ int eeh_phb_pe_create(struct pci_controller *phb); struct eeh_pe *eeh_phb_pe_get(struct pci_controller *phb); struct eeh_pe *eeh_pe_get(struct eeh_dev *edev); int eeh_add_to_parent_pe(struct eeh_dev *edev); -int eeh_rmv_from_parent_pe(struct eeh_dev *edev, int purge_pe); +int eeh_rmv_from_parent_pe(struct eeh_dev *edev); void eeh_pe_update_time_stamp(struct eeh_pe *pe); void *eeh_pe_dev_traverse(struct eeh_pe *root, eeh_traverse_func fn, void *flag); @@ -214,8 +216,7 @@ void eeh_add_device_tree_early(struct device_node *); void eeh_add_device_late(struct pci_dev *); void eeh_add_device_tree_late(struct pci_bus *); void eeh_add_sysfs_files(struct pci_bus *); -void eeh_remove_device(struct pci_dev *, int); -void eeh_remove_bus_device(struct pci_dev *, int); +void eeh_remove_device(struct pci_dev *); /** * EEH_POSSIBLE_ERROR() -- test for possible MMIO failure. @@ -265,9 +266,7 @@ static inline void eeh_add_device_tree_late(struct pci_bus *bus) { } static inline void eeh_add_sysfs_files(struct pci_bus *bus) { } -static inline void eeh_remove_device(struct pci_dev *dev, int purge_pe) { } - -static inline void eeh_remove_bus_device(struct pci_dev *dev, int purge_pe) { } +static inline void eeh_remove_device(struct pci_dev *dev) { } #define EEH_POSSIBLE_ERROR(val, type) (0) #define EEH_IO_ERROR_VALUE(size) (-1UL) diff --git a/arch/powerpc/include/asm/pci-bridge.h b/arch/powerpc/include/asm/pci-bridge.h index 2c1d8cb..32d0d20 100644 --- a/arch/powerpc/include/asm/pci-bridge.h +++ b/arch/powerpc/include/asm/pci-bridge.h @@ -209,7 +209,6 @@ static inline struct eeh_dev *of_node_to_eeh_dev(struct device_node *dn) extern struct pci_bus *pcibios_find_pci_bus(struct device_node *dn); /** Remove all of the PCI devices under this bus */ -extern void __pcibios_remove_pci_devices(struct pci_bus *bus, int purge_pe); extern void pcibios_remove_pci_devices(struct pci_bus *bus); /** Discover new pci devices under this bus, and add them */ diff --git a/arch/powerpc/kernel/eeh.c b/arch/powerpc/kernel/eeh.c index 582ad1e..ce81477 100644 --- a/arch/powerpc/kernel/eeh.c +++ b/arch/powerpc/kernel/eeh.c @@ -964,7 +964,6 @@ EXPORT_SYMBOL_GPL(eeh_add_sysfs_files); /** * eeh_remove_device - Undo EEH setup for the indicated pci device * @dev: pci device to be removed - * @purge_pe: remove the PE or not * * This routine should be called when a device is removed from * a running system (e.g. by hotplug or dlpar). It unregisters @@ -972,7 +971,7 @@ EXPORT_SYMBOL_GPL(eeh_add_sysfs_files); * this device will no longer be detected after this call; thus, * i/o errors affecting this slot may leave this device unusable. */ -void eeh_remove_device(struct pci_dev *dev, int purge_pe) +void eeh_remove_device(struct pci_dev *dev) { struct eeh_dev *edev; @@ -990,34 +989,11 @@ void eeh_remove_device(struct pci_dev *dev, int purge_pe) edev-pdev = NULL; dev-dev.archdata.edev = NULL; - eeh_rmv_from_parent_pe(edev, purge_pe); + eeh_rmv_from_parent_pe(edev); eeh_addr_cache_rmv_dev(dev); eeh_sysfs_remove_device(dev); } -/** - * eeh_remove_bus_device - Undo EEH setup for the indicated PCI device - * @dev: PCI device - * @purge_pe: remove the corresponding PE or not - * - * This routine must be called when a device is removed from the - * running system through hotplug or dlpar. The corresponding - * PCI address cache will be removed. - */ -void
[PATCH 02/11] powerpc/eeh: Export functions for hotplug
Make some functions public in order to support hotplug on either specific PCI bus or PCI device in future. Signed-off-by: Gavin Shan sha...@linux.vnet.ibm.com --- arch/powerpc/include/asm/eeh.h |9 + arch/powerpc/kernel/eeh.c |6 +++--- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/arch/powerpc/include/asm/eeh.h b/arch/powerpc/include/asm/eeh.h index 09a8743..d9d35c2 100644 --- a/arch/powerpc/include/asm/eeh.h +++ b/arch/powerpc/include/asm/eeh.h @@ -209,9 +209,12 @@ unsigned long eeh_check_failure(const volatile void __iomem *token, unsigned long val); int eeh_dev_check_failure(struct eeh_dev *edev); void eeh_addr_cache_build(void); +void eeh_add_device_early(struct device_node *); void eeh_add_device_tree_early(struct device_node *); +void eeh_add_device_late(struct pci_dev *); void eeh_add_device_tree_late(struct pci_bus *); void eeh_add_sysfs_files(struct pci_bus *); +void eeh_remove_device(struct pci_dev *, int); void eeh_remove_bus_device(struct pci_dev *, int); /** @@ -252,12 +255,18 @@ static inline unsigned long eeh_check_failure(const volatile void __iomem *token static inline void eeh_addr_cache_build(void) { } +static inline void eeh_add_device_early(struct device_node *dn) { } + static inline void eeh_add_device_tree_early(struct device_node *dn) { } +static inline void eeh_add_device_late(struct pci_dev *dev) { } + static inline void eeh_add_device_tree_late(struct pci_bus *bus) { } static inline void eeh_add_sysfs_files(struct pci_bus *bus) { } +static inline void eeh_remove_device(struct pci_dev *dev, int purge_pe) { } + static inline void eeh_remove_bus_device(struct pci_dev *dev, int purge_pe) { } #define EEH_POSSIBLE_ERROR(val, type) (0) diff --git a/arch/powerpc/kernel/eeh.c b/arch/powerpc/kernel/eeh.c index b5c425e..582ad1e 100644 --- a/arch/powerpc/kernel/eeh.c +++ b/arch/powerpc/kernel/eeh.c @@ -836,7 +836,7 @@ core_initcall_sync(eeh_init); * on the CEC architecture, type of the device, on earlier boot * command-line arguments etc. */ -static void eeh_add_device_early(struct device_node *dn) +void eeh_add_device_early(struct device_node *dn) { struct pci_controller *phb; @@ -884,7 +884,7 @@ EXPORT_SYMBOL_GPL(eeh_add_device_tree_early); * This routine must be used to complete EEH initialization for PCI * devices that were added after system boot (e.g. hotplug, dlpar). */ -static void eeh_add_device_late(struct pci_dev *dev) +void eeh_add_device_late(struct pci_dev *dev) { struct device_node *dn; struct eeh_dev *edev; @@ -972,7 +972,7 @@ EXPORT_SYMBOL_GPL(eeh_add_sysfs_files); * this device will no longer be detected after this call; thus, * i/o errors affecting this slot may leave this device unusable. */ -static void eeh_remove_device(struct pci_dev *dev, int purge_pe) +void eeh_remove_device(struct pci_dev *dev, int purge_pe) { struct eeh_dev *edev; -- 1.7.5.4 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 01/11] powerpc/eeh: Remove reference to PCI device
We will rely on pcibios_release_device() to remove the EEH cache and unbind EEH device for the specific PCI device. So we shouldn't hold the reference to the PCI device from EEH cache and EEH device. Otherwise, pcibios_release_device() won't be called as we expected. The patch removes the reference to the PCI device in EEH core. Signed-off-by: Gavin Shan sha...@linux.vnet.ibm.com --- arch/powerpc/kernel/eeh.c |4 arch/powerpc/kernel/eeh_cache.c | 18 +- 2 files changed, 5 insertions(+), 17 deletions(-) diff --git a/arch/powerpc/kernel/eeh.c b/arch/powerpc/kernel/eeh.c index 39954fe..b5c425e 100644 --- a/arch/powerpc/kernel/eeh.c +++ b/arch/powerpc/kernel/eeh.c @@ -499,8 +499,6 @@ unsigned long eeh_check_failure(const volatile void __iomem *token, unsigned lon } eeh_dev_check_failure(edev); - - pci_dev_put(eeh_dev_to_pci_dev(edev)); return val; } @@ -904,7 +902,6 @@ static void eeh_add_device_late(struct pci_dev *dev) } WARN_ON(edev-pdev); - pci_dev_get(dev); edev-pdev = dev; dev-dev.archdata.edev = edev; @@ -992,7 +989,6 @@ static void eeh_remove_device(struct pci_dev *dev, int purge_pe) } edev-pdev = NULL; dev-dev.archdata.edev = NULL; - pci_dev_put(dev); eeh_rmv_from_parent_pe(edev, purge_pe); eeh_addr_cache_rmv_dev(dev); diff --git a/arch/powerpc/kernel/eeh_cache.c b/arch/powerpc/kernel/eeh_cache.c index f9ac123..e8c9fd5 100644 --- a/arch/powerpc/kernel/eeh_cache.c +++ b/arch/powerpc/kernel/eeh_cache.c @@ -68,16 +68,12 @@ static inline struct eeh_dev *__eeh_addr_cache_get_device(unsigned long addr) struct pci_io_addr_range *piar; piar = rb_entry(n, struct pci_io_addr_range, rb_node); - if (addr piar-addr_lo) { + if (addr piar-addr_lo) n = n-rb_left; - } else { - if (addr piar-addr_hi) { - n = n-rb_right; - } else { - pci_dev_get(piar-pcidev); - return piar-edev; - } - } + else if (addr piar-addr_hi) + n = n-rb_right; + else + return piar-edev; } return NULL; @@ -156,7 +152,6 @@ eeh_addr_cache_insert(struct pci_dev *dev, unsigned long alo, if (!piar) return NULL; - pci_dev_get(dev); piar-addr_lo = alo; piar-addr_hi = ahi; piar-edev = pci_dev_to_eeh_dev(dev); @@ -250,7 +245,6 @@ restart: if (piar-pcidev == dev) { rb_erase(n, pci_io_addr_cache_root.rb_root); - pci_dev_put(piar-pcidev); kfree(piar); goto restart; } @@ -302,12 +296,10 @@ void eeh_addr_cache_build(void) if (!edev) continue; - pci_dev_get(dev); /* matching put is in eeh_remove_device() */ dev-dev.archdata.edev = edev; edev-pdev = dev; eeh_addr_cache_insert_dev(dev); - eeh_sysfs_add_device(dev); } -- 1.7.5.4 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 07/11] powerpc/pci: Partial hotplug support
When EEH error happens to one specific PE, the device drivers of its attached EEH devices (PCI devices) are checked to see the further action: reset with complete hotplug, or reset without hotplug. However, that's not enough for those PCI devices whose drivers can't support EEH, or those PCI devices without driver. So we need do so-called partial hotplug on basis of PCI devices. In the situation, part of PCI devices of the specific PE are unplugged and plugged again after PE reset. The patch changes pcibios_add_pci_devices() so that it can support full hotplug and so-called partial hotplug based on device-tree or real hardware. It's notable that pci_of_scan.c has been changed for a bit in order to support the partial hotplug based on dev-tree. Signed-off-by: Gavin Shan sha...@linux.vnet.ibm.com --- arch/powerpc/kernel/pci-common.c |2 + arch/powerpc/kernel/pci-hotplug.c | 14 ++--- arch/powerpc/kernel/pci_of_scan.c | 56 ++-- 3 files changed, 51 insertions(+), 21 deletions(-) diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c index f46914a..7d22a67 100644 --- a/arch/powerpc/kernel/pci-common.c +++ b/arch/powerpc/kernel/pci-common.c @@ -1462,6 +1462,8 @@ void pcibios_finish_adding_to_bus(struct pci_bus *bus) /* Allocate bus and devices resources */ pcibios_allocate_bus_resources(bus); pcibios_claim_one_bus(bus); + if (!pci_has_flag(PCI_PROBE_ONLY)) + pci_assign_unassigned_bus_resources(bus); /* Fixup EEH */ eeh_add_device_tree_late(bus); diff --git a/arch/powerpc/kernel/pci-hotplug.c b/arch/powerpc/kernel/pci-hotplug.c index fc0831d..62388a6 100644 --- a/arch/powerpc/kernel/pci-hotplug.c +++ b/arch/powerpc/kernel/pci-hotplug.c @@ -71,7 +71,7 @@ EXPORT_SYMBOL_GPL(pcibios_remove_pci_devices); */ void pcibios_add_pci_devices(struct pci_bus * bus) { - int slotno, num, mode, pass, max; + int slotno, mode, pass, max; struct pci_dev *dev; struct device_node *dn = pci_bus_to_OF_node(bus); @@ -85,11 +85,15 @@ void pcibios_add_pci_devices(struct pci_bus * bus) /* use ofdt-based probe */ of_rescan_bus(dn, bus); } else if (mode == PCI_PROBE_NORMAL) { - /* use legacy probe */ + /* +* Use legacy probe. In the partial hotplug case, we +* probably have indirect child devices unplugged. So +* we don't check return value from pci_scan_slot() in +* order for full-scan to pick up those indirect child +* devices, which were removed during partial hotplug. +*/ slotno = PCI_SLOT(PCI_DN(dn-child)-devfn); - num = pci_scan_slot(bus, PCI_DEVFN(slotno, 0)); - if (!num) - return; + pci_scan_slot(bus, PCI_DEVFN(slotno, 0)); pcibios_setup_bus_devices(bus); max = bus-busn_res.start; for (pass = 0; pass 2; pass++) { diff --git a/arch/powerpc/kernel/pci_of_scan.c b/arch/powerpc/kernel/pci_of_scan.c index 6b0ba58..15d9105 100644 --- a/arch/powerpc/kernel/pci_of_scan.c +++ b/arch/powerpc/kernel/pci_of_scan.c @@ -230,11 +230,14 @@ void of_scan_pci_bridge(struct pci_dev *dev) return; } - bus = pci_add_new_bus(dev-bus, dev, busrange[0]); + bus = pci_find_bus(pci_domain_nr(dev-bus), busrange[0]); if (!bus) { - printk(KERN_ERR Failed to create pci bus for %s\n, - node-full_name); - return; + bus = pci_add_new_bus(dev-bus, dev, busrange[0]); + if (!bus) { + printk(KERN_ERR Failed to create pci bus for %s\n, + node-full_name); + return; + } } bus-primary = dev-bus-number; @@ -292,6 +295,38 @@ void of_scan_pci_bridge(struct pci_dev *dev) } EXPORT_SYMBOL(of_scan_pci_bridge); +static struct pci_dev *of_scan_pci_dev(struct pci_bus *bus, + struct device_node *dn) +{ + struct pci_dev *dev = NULL; + const u32 *reg; + int reglen, devfn; + + pr_debug( * %s\n, dn-full_name); + if (!of_device_is_available(dn)) + return NULL; + + reg = of_get_property(dn, reg, reglen); + if (reg == NULL || reglen 20) + return NULL; + devfn = (reg[0] 8) 0xff; + + /* Check if the PCI device is already there */ + dev = pci_get_slot(bus, devfn); + if (dev) { + pci_dev_put(dev); + return dev; + } + + /* create a new pci_dev for this device */ + dev = of_create_pci_dev(dn, bus, devfn); + if (!dev) + return NULL; + + pr_debug( dev header type: %x\n, dev-hdr_type); + return dev; +} + /** *
[PATCH 06/11] powerpc/eeh: Tranverse EEH devices with safe mode
Currently, we're transversing EEH devices by list_for_each_entry(). That's not safe enough because the EEH devices might be removed from its parent PE while doing iteration. The patch replaces that with list_for_each_entry_safe(). Signed-off-by: Gavin Shan sha...@linux.vnet.ibm.com --- arch/powerpc/include/asm/eeh.h |4 ++-- arch/powerpc/kernel/eeh.c |4 ++-- arch/powerpc/kernel/eeh_pe.c | 10 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/arch/powerpc/include/asm/eeh.h b/arch/powerpc/include/asm/eeh.h index 2ce22d7..e8c411b 100644 --- a/arch/powerpc/include/asm/eeh.h +++ b/arch/powerpc/include/asm/eeh.h @@ -74,8 +74,8 @@ struct eeh_pe { struct list_head child; /* Child PEs*/ }; -#define eeh_pe_for_each_dev(pe, edev) \ - list_for_each_entry(edev, pe-edevs, list) +#define eeh_pe_for_each_dev(pe, edev, tmp) \ + list_for_each_entry_safe(edev, tmp, pe-edevs, list) /* * The struct is used to trace EEH state for the associated diff --git a/arch/powerpc/kernel/eeh.c b/arch/powerpc/kernel/eeh.c index ce81477..56bd458 100644 --- a/arch/powerpc/kernel/eeh.c +++ b/arch/powerpc/kernel/eeh.c @@ -231,7 +231,7 @@ static size_t eeh_gather_pci_data(struct eeh_dev *edev, char * buf, size_t len) void eeh_slot_error_detail(struct eeh_pe *pe, int severity) { size_t loglen = 0; - struct eeh_dev *edev; + struct eeh_dev *edev, *tmp; bool valid_cfg_log = true; /* @@ -251,7 +251,7 @@ void eeh_slot_error_detail(struct eeh_pe *pe, int severity) eeh_pe_restore_bars(pe); pci_regs_buf[0] = 0; - eeh_pe_for_each_dev(pe, edev) { + eeh_pe_for_each_dev(pe, edev, tmp) { loglen += eeh_gather_pci_data(edev, pci_regs_buf + loglen, EEH_PCI_REGS_LOG_LEN - loglen); } diff --git a/arch/powerpc/kernel/eeh_pe.c b/arch/powerpc/kernel/eeh_pe.c index 32ef409..c8b815e 100644 --- a/arch/powerpc/kernel/eeh_pe.c +++ b/arch/powerpc/kernel/eeh_pe.c @@ -176,7 +176,7 @@ void *eeh_pe_dev_traverse(struct eeh_pe *root, eeh_traverse_func fn, void *flag) { struct eeh_pe *pe; - struct eeh_dev *edev; + struct eeh_dev *edev, *tmp; void *ret; if (!root) { @@ -186,7 +186,7 @@ void *eeh_pe_dev_traverse(struct eeh_pe *root, /* Traverse root PE */ for (pe = root; pe; pe = eeh_pe_next(pe, root)) { - eeh_pe_for_each_dev(pe, edev) { + eeh_pe_for_each_dev(pe, edev, tmp) { ret = fn(edev, flag); if (ret) return ret; @@ -501,7 +501,7 @@ static void *__eeh_pe_state_mark(void *data, void *flag) { struct eeh_pe *pe = (struct eeh_pe *)data; int state = *((int *)flag); - struct eeh_dev *tmp; + struct eeh_dev *edev, *tmp; struct pci_dev *pdev; /* @@ -511,8 +511,8 @@ static void *__eeh_pe_state_mark(void *data, void *flag) * the PCI device driver. */ pe-state |= state; - eeh_pe_for_each_dev(pe, tmp) { - pdev = eeh_dev_to_pci_dev(tmp); + eeh_pe_for_each_dev(pe, edev, tmp) { + pdev = eeh_dev_to_pci_dev(edev); if (pdev) pdev-error_state = pci_channel_io_frozen; } -- 1.7.5.4 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 09/11] powerpc/eeh: Don't use pci_dev during BAR restore
While restoring BARs for one specific PCI device, the pci_dev instance should have been released. So it's not reliable to use the pci_dev instance on restoring BARs. However, we still need some information (e.g. PCIe capability position, header type) from the pci_dev instance. So we have to store those information to EEH device in advance. Signed-off-by: Gavin Shan sha...@linux.vnet.ibm.com --- arch/powerpc/include/asm/eeh.h |8 +++- arch/powerpc/kernel/eeh_pe.c | 25 +- arch/powerpc/platforms/powernv/eeh-powernv.c | 11 + arch/powerpc/platforms/pseries/eeh_pseries.c | 63 +- 4 files changed, 91 insertions(+), 16 deletions(-) diff --git a/arch/powerpc/include/asm/eeh.h b/arch/powerpc/include/asm/eeh.h index f54a601..4199d99 100644 --- a/arch/powerpc/include/asm/eeh.h +++ b/arch/powerpc/include/asm/eeh.h @@ -84,8 +84,11 @@ struct eeh_pe { * another tree except the currently existing tree of PCI * buses and PCI devices */ -#define EEH_DEV_IRQ_DISABLED (1 0)/* Interrupt disabled */ -#define EEH_DEV_DISCONNECTED (1 1)/* Removing from PE */ +#define EEH_DEV_BRIDGE (1 0)/* PCI bridge */ +#define EEH_DEV_ROOT_PORT (1 1)/* PCIe root port */ +#define EEH_DEV_DS_PORT(1 2)/* Downstream port */ +#define EEH_DEV_IRQ_DISABLED (1 3)/* Interrupt disabled */ +#define EEH_DEV_DISCONNECTED (1 4)/* Removing from PE */ struct eeh_dev { int mode; /* EEH mode */ @@ -93,6 +96,7 @@ struct eeh_dev { int config_addr;/* Config address */ int pe_config_addr; /* PE config address*/ u32 config_space[16]; /* Saved PCI config space */ + u8 pcie_cap;/* Saved PCIe capability*/ struct eeh_pe *pe; /* Associated PE*/ struct list_head list; /* Form link list in the PE */ struct pci_controller *phb; /* Associated PHB */ diff --git a/arch/powerpc/kernel/eeh_pe.c b/arch/powerpc/kernel/eeh_pe.c index 2aa955a..f945053 100644 --- a/arch/powerpc/kernel/eeh_pe.c +++ b/arch/powerpc/kernel/eeh_pe.c @@ -578,7 +578,7 @@ void eeh_pe_state_clear(struct eeh_pe *pe, int state) * blocked on normal path during the stage. So we need utilize * eeh operations, which is always permitted. */ -static void eeh_bridge_check_link(struct pci_dev *pdev, +static void eeh_bridge_check_link(struct eeh_dev *edev, struct device_node *dn) { int cap; @@ -589,16 +589,17 @@ static void eeh_bridge_check_link(struct pci_dev *pdev, * We only check root port and downstream ports of * PCIe switches */ - if (!pci_is_pcie(pdev) || - (pci_pcie_type(pdev) != PCI_EXP_TYPE_ROOT_PORT -pci_pcie_type(pdev) != PCI_EXP_TYPE_DOWNSTREAM)) + if (!(edev-mode (EEH_DEV_ROOT_PORT | EEH_DEV_DS_PORT))) return; - pr_debug(%s: Check PCIe link for %s ...\n, -__func__, pci_name(pdev)); + pr_debug(%s: Check PCIe link for %04x:%02x:%02x.%01x ...\n, +__func__, edev-phb-global_number, +edev-config_addr 8, +PCI_SLOT(edev-config_addr 0xFF), +PCI_FUNC(edev-config_addr 0xFF)); /* Check slot status */ - cap = pdev-pcie_cap; + cap = edev-pcie_cap; eeh_ops-read_config(dn, cap + PCI_EXP_SLTSTA, 2, val); if (!(val PCI_EXP_SLTSTA_PDS)) { pr_debug( No card in the slot (0x%04x) !\n, val); @@ -652,8 +653,7 @@ static void eeh_bridge_check_link(struct pci_dev *pdev, #define BYTE_SWAP(OFF) (8*((OFF)/4)+3-(OFF)) #define SAVED_BYTE(OFF)(((u8 *)(edev-config_space))[BYTE_SWAP(OFF)]) -static void eeh_restore_bridge_bars(struct pci_dev *pdev, - struct eeh_dev *edev, +static void eeh_restore_bridge_bars(struct eeh_dev *edev, struct device_node *dn) { int i; @@ -679,7 +679,7 @@ static void eeh_restore_bridge_bars(struct pci_dev *pdev, eeh_ops-write_config(dn, PCI_COMMAND, 4, edev-config_space[1]); /* Check the PCIe link is ready */ - eeh_bridge_check_link(pdev, dn); + eeh_bridge_check_link(edev, dn); } static void eeh_restore_device_bars(struct eeh_dev *edev, @@ -729,12 +729,11 @@ static void eeh_restore_device_bars(struct eeh_dev *edev, static void *eeh_restore_one_device_bars(void *data, void *flag) { struct eeh_dev *edev = (struct eeh_dev *)data; - struct pci_dev *pdev = eeh_dev_to_pci_dev(edev); struct device_node *dn = eeh_dev_to_of_node(edev); /* Do special restore for bridges */ - if (pdev-hdr_type ==
[PATCH 10/11] powerpc/eeh: Fix unbalanced enable for IRQ
The patch fixes following issue: Unbalanced enable for IRQ 23 [ cut here ] WARNING: at kernel/irq/manage.c:437 : NIP [c016de8c] .__enable_irq+0x11c/0x140 LR [c016de88] .__enable_irq+0x118/0x140 Call Trace: [c03ea1f23880] [c016de88] .__enable_irq+0x118/0x140 (unreliable) [c03ea1f23910] [c016df08] .enable_irq+0x58/0xa0 [c03ea1f239a0] [c00388b4] .eeh_enable_irq+0xc4/0xe0 [c03ea1f23a30] [c0038a28] .eeh_report_reset+0x78/0x130 [c03ea1f23ac0] [c0037508] .eeh_pe_dev_traverse+0x98/0x170 [c03ea1f23b60] [c00391ac] .eeh_handle_normal_event+0x2fc/0x3d0 [c03ea1f23bf0] [c0039538] .eeh_handle_event+0x2b8/0x2c0 [c03ea1f23c90] [c0039600] .eeh_event_handler+0xc0/0x170 [c03ea1f23d30] [c00da9a0] .kthread+0xf0/0x100 [c03ea1f23e30] [c000a1dc] .ret_from_kernel_thread+0x5c/0x80 Signed-off-by: Gavin Shan sha...@linux.vnet.ibm.com --- arch/powerpc/kernel/eeh_driver.c |6 +- 1 files changed, 5 insertions(+), 1 deletions(-) diff --git a/arch/powerpc/kernel/eeh_driver.c b/arch/powerpc/kernel/eeh_driver.c index 9fda75d..36bed5a 100644 --- a/arch/powerpc/kernel/eeh_driver.c +++ b/arch/powerpc/kernel/eeh_driver.c @@ -143,10 +143,14 @@ static void eeh_disable_irq(struct pci_dev *dev) static void eeh_enable_irq(struct pci_dev *dev) { struct eeh_dev *edev = pci_dev_to_eeh_dev(dev); + struct irq_desc *desc; if ((edev-mode) EEH_DEV_IRQ_DISABLED) { edev-mode = ~EEH_DEV_IRQ_DISABLED; - enable_irq(dev-irq); + + desc = irq_to_desc(dev-irq); + if (desc desc-depth 0) + enable_irq(dev-irq); } } -- 1.7.5.4 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 03/11] powerpc/pci: Override pcibios_release_device()
The patch overrides pcibios_release_device() to release EEH resources (EEH cache, unbinding EEH device) for the indicated PCI device. Signed-off-by: Gavin Shan sha...@linux.vnet.ibm.com --- arch/powerpc/kernel/pci-hotplug.c | 11 +++ 1 files changed, 11 insertions(+), 0 deletions(-) diff --git a/arch/powerpc/kernel/pci-hotplug.c b/arch/powerpc/kernel/pci-hotplug.c index 3f60880..3dab2f2 100644 --- a/arch/powerpc/kernel/pci-hotplug.c +++ b/arch/powerpc/kernel/pci-hotplug.c @@ -22,6 +22,17 @@ #include asm/eeh.h /** + * pcibios_release_device - release PCI device + * @dev: PCI device + * + * The function is called before releasing the indicated PCI device. + */ +void pcibios_release_device(struct pci_dev *dev) +{ + eeh_remove_device(dev, 1); +} + +/** * __pcibios_remove_pci_devices - remove all devices under this bus * @bus: the indicated PCI bus * @purge_pe: destroy the PE on removal of PCI devices -- 1.7.5.4 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 08/11] powerpc/eeh: Support partial hotplug
When EEH error happens to one specific PE, some devices with drivers supporting EEH won't except hotplug on the deivce. However, there might have other deivces without driver, or with driver without EEH support. For the case, we need do partial hotplug in order to make sure that the PE becomes absolutely quite during reset. Otherise, the PE reset might fail and leads to failure of error recovery. The patch intends to support so-called partial hotplug for EEH: Before we do reset, we stop and remove those PCI devices without EEH sensitive driver. The corresponding EEH devices are not detached from its PE, but with special flag. After the reset is done, those EEH devices with the special flag will be scanned one by one. Signed-off-by: Gavin Shan sha...@linux.vnet.ibm.com --- arch/powerpc/include/asm/eeh.h |6 ++- arch/powerpc/kernel/eeh.c| 30 +- arch/powerpc/kernel/eeh_driver.c | 74 -- arch/powerpc/kernel/eeh_pe.c | 20 +++- arch/powerpc/kernel/eeh_sysfs.c |7 +++ arch/powerpc/platforms/powernv/eeh-powernv.c |2 +- arch/powerpc/platforms/pseries/eeh_pseries.c |2 +- 7 files changed, 117 insertions(+), 24 deletions(-) diff --git a/arch/powerpc/include/asm/eeh.h b/arch/powerpc/include/asm/eeh.h index e8c411b..f54a601 100644 --- a/arch/powerpc/include/asm/eeh.h +++ b/arch/powerpc/include/asm/eeh.h @@ -84,7 +84,8 @@ struct eeh_pe { * another tree except the currently existing tree of PCI * buses and PCI devices */ -#define EEH_DEV_IRQ_DISABLED (10) /* Interrupt disabled */ +#define EEH_DEV_IRQ_DISABLED (1 0)/* Interrupt disabled */ +#define EEH_DEV_DISCONNECTED (1 1)/* Removing from PE */ struct eeh_dev { int mode; /* EEH mode */ @@ -97,6 +98,7 @@ struct eeh_dev { struct pci_controller *phb; /* Associated PHB */ struct device_node *dn; /* Associated device node */ struct pci_dev *pdev; /* Associated PCI device*/ + struct pci_bus *bus;/* PCI bus for partial hotplug */ }; static inline struct device_node *eeh_dev_to_of_node(struct eeh_dev *edev) @@ -197,6 +199,8 @@ struct eeh_pe *eeh_pe_get(struct eeh_dev *edev); int eeh_add_to_parent_pe(struct eeh_dev *edev); int eeh_rmv_from_parent_pe(struct eeh_dev *edev); void eeh_pe_update_time_stamp(struct eeh_pe *pe); +void *eeh_pe_traverse(struct eeh_pe *root, + eeh_traverse_func fn, void *flag); void *eeh_pe_dev_traverse(struct eeh_pe *root, eeh_traverse_func fn, void *flag); void eeh_pe_restore_bars(struct eeh_pe *pe); diff --git a/arch/powerpc/kernel/eeh.c b/arch/powerpc/kernel/eeh.c index 56bd458..a5783f1 100644 --- a/arch/powerpc/kernel/eeh.c +++ b/arch/powerpc/kernel/eeh.c @@ -900,7 +900,21 @@ void eeh_add_device_late(struct pci_dev *dev) pr_debug(EEH: Already referenced !\n); return; } - WARN_ON(edev-pdev); + + /* +* The EEH cache might not be removed correctly because of +* unbalanced kref to the device during unplug time, which +* relies on pcibios_release_device(). So we have to remove +* that here explicitly. +*/ + if (edev-pdev) { + eeh_rmv_from_parent_pe(edev); + eeh_addr_cache_rmv_dev(edev-pdev); + eeh_sysfs_remove_device(edev-pdev); + + edev-pdev = NULL; + dev-dev.archdata.edev = NULL; + } edev-pdev = dev; dev-dev.archdata.edev = edev; @@ -982,14 +996,24 @@ void eeh_remove_device(struct pci_dev *dev) /* Unregister the device with the EEH/PCI address search system */ pr_debug(EEH: Removing device %s\n, pci_name(dev)); - if (!edev || !edev-pdev) { + if (!edev || !edev-pdev || !edev-pe) { pr_debug(EEH: Not referenced !\n); return; } + + /* +* During the hotplug for EEH error recovery, we need the EEH +* device attached to the parent PE in order for BAR restore +* a bit later. So we keep it for BAR restore and remove it +* from the parent PE during the BAR resotre. +*/ edev-pdev = NULL; dev-dev.archdata.edev = NULL; + if (!(edev-pe-state EEH_PE_KEEP)) + eeh_rmv_from_parent_pe(edev); + else + edev-mode |= EEH_DEV_DISCONNECTED; - eeh_rmv_from_parent_pe(edev); eeh_addr_cache_rmv_dev(dev); eeh_sysfs_remove_device(dev); } diff --git a/arch/powerpc/kernel/eeh_driver.c b/arch/powerpc/kernel/eeh_driver.c index 9ef3bbb..9fda75d 100644 --- a/arch/powerpc/kernel/eeh_driver.c +++ b/arch/powerpc/kernel/eeh_driver.c @@ -338,6 +338,54 @@ static void *eeh_report_failure(void *data, void *userdata) return NULL; } +static
[PATCH 11/11] powerpc/eeh: Introdce flag to protect sysfs
The patch introduces flag EEH_DEV_SYSFS to trace that the sysfs for the corresponding EEH device (then PCI device) has been added or removed, in order to avoid race condition. Signed-off-by: Gavin Shan sha...@linux.vnet.ibm.com --- arch/powerpc/include/asm/eeh.h |2 ++ arch/powerpc/kernel/eeh.c|2 ++ arch/powerpc/kernel/eeh_sysfs.c | 16 +++- arch/powerpc/platforms/powernv/eeh-powernv.c |4 ++-- arch/powerpc/platforms/pseries/eeh_pseries.c |2 +- 5 files changed, 22 insertions(+), 4 deletions(-) diff --git a/arch/powerpc/include/asm/eeh.h b/arch/powerpc/include/asm/eeh.h index 4199d99..d3e5e9b 100644 --- a/arch/powerpc/include/asm/eeh.h +++ b/arch/powerpc/include/asm/eeh.h @@ -90,6 +90,8 @@ struct eeh_pe { #define EEH_DEV_IRQ_DISABLED (1 3)/* Interrupt disabled */ #define EEH_DEV_DISCONNECTED (1 4)/* Removing from PE */ +#define EEH_DEV_SYSFS (1 8)/* Sysfs created*/ + struct eeh_dev { int mode; /* EEH mode */ int class_code; /* Class code of the device */ diff --git a/arch/powerpc/kernel/eeh.c b/arch/powerpc/kernel/eeh.c index a5783f1..ea9414c8 100644 --- a/arch/powerpc/kernel/eeh.c +++ b/arch/powerpc/kernel/eeh.c @@ -911,6 +911,7 @@ void eeh_add_device_late(struct pci_dev *dev) eeh_rmv_from_parent_pe(edev); eeh_addr_cache_rmv_dev(edev-pdev); eeh_sysfs_remove_device(edev-pdev); + edev-mode = ~EEH_DEV_SYSFS; edev-pdev = NULL; dev-dev.archdata.edev = NULL; @@ -1016,6 +1017,7 @@ void eeh_remove_device(struct pci_dev *dev) eeh_addr_cache_rmv_dev(dev); eeh_sysfs_remove_device(dev); + edev-mode = ~EEH_DEV_SYSFS; } static int proc_eeh_show(struct seq_file *m, void *v) diff --git a/arch/powerpc/kernel/eeh_sysfs.c b/arch/powerpc/kernel/eeh_sysfs.c index 61e2a14..5d753d4 100644 --- a/arch/powerpc/kernel/eeh_sysfs.c +++ b/arch/powerpc/kernel/eeh_sysfs.c @@ -56,26 +56,40 @@ EEH_SHOW_ATTR(eeh_pe_config_addr, pe_config_addr, 0x%x); void eeh_sysfs_add_device(struct pci_dev *pdev) { + struct eeh_dev *edev = pci_dev_to_eeh_dev(pdev); int rc=0; + if (edev (edev-mode EEH_DEV_SYSFS)) + return; + rc += device_create_file(pdev-dev, dev_attr_eeh_mode); rc += device_create_file(pdev-dev, dev_attr_eeh_config_addr); rc += device_create_file(pdev-dev, dev_attr_eeh_pe_config_addr); if (rc) printk(KERN_WARNING EEH: Unable to create sysfs entries\n); + else if (edev) + edev-mode |= EEH_DEV_SYSFS; } void eeh_sysfs_remove_device(struct pci_dev *pdev) { + struct eeh_dev *edev = pci_dev_to_eeh_dev(pdev); + /* * The parent directory might have been removed. We needn't * continue for that case. */ - if (!pdev-dev.kobj.sd) + if (!pdev-dev.kobj.sd) { + if (edev) + edev-mode = ~EEH_DEV_SYSFS; return; + } device_remove_file(pdev-dev, dev_attr_eeh_mode); device_remove_file(pdev-dev, dev_attr_eeh_config_addr); device_remove_file(pdev-dev, dev_attr_eeh_pe_config_addr); + + if (edev) + edev-mode = ~EEH_DEV_SYSFS; } diff --git a/arch/powerpc/platforms/powernv/eeh-powernv.c b/arch/powerpc/platforms/powernv/eeh-powernv.c index 4361a5c..79663d2 100644 --- a/arch/powerpc/platforms/powernv/eeh-powernv.c +++ b/arch/powerpc/platforms/powernv/eeh-powernv.c @@ -122,8 +122,8 @@ static int powernv_eeh_dev_probe(struct pci_dev *dev, void *flag) return 0; /* Initialize eeh device */ - edev-class_code= dev-class; - edev-mode = 0; + edev-class_code = dev-class; + edev-mode = 0xFF00; if (dev-hdr_type == PCI_HEADER_TYPE_BRIDGE) edev-mode |= EEH_DEV_BRIDGE; if (pci_is_pcie(dev)) { diff --git a/arch/powerpc/platforms/pseries/eeh_pseries.c b/arch/powerpc/platforms/pseries/eeh_pseries.c index 9e80f0a..7fbc25b 100644 --- a/arch/powerpc/platforms/pseries/eeh_pseries.c +++ b/arch/powerpc/platforms/pseries/eeh_pseries.c @@ -218,7 +218,7 @@ static void *pseries_eeh_of_probe(struct device_node *dn, void *flag) */ edev-class_code = *class_code; edev-pcie_cap = pseries_eeh_find_cap(dn, PCI_CAP_ID_EXP); - edev-mode = 0; + edev-mode = 0xFF00; if ((edev-class_code 8) == PCI_CLASS_BRIDGE_PCI) { edev-mode |= EEH_DEV_BRIDGE; if (edev-pcie_cap) { -- 1.7.5.4 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
RE: [PATCH 1/2] cpuidle: fix cpu idle driver as a module can not remove
-Original Message- From: Rafael J. Wysocki [mailto:r...@sisk.pl] Sent: Wednesday, July 24, 2013 5:33 AM To: Wang Dongsheng-B40534 Cc: daniel.lezc...@linaro.org; linux...@vger.kernel.org; linuxppc- d...@lists.ozlabs.org Subject: Re: [PATCH 1/2] cpuidle: fix cpu idle driver as a module can not remove On Tuesday, July 23, 2013 05:28:00 PM Dongsheng Wang wrote: From: Wang Dongsheng dongsheng.w...@freescale.com The module can not be removed when execute rmmod. rmmod not use --force. Log: root:~# rmmod cpuidle-e500 incs[9], decs[1] rmmod: can't unload 'cpuidle_e500': Resource temporarily unavailable Signed-off-by: Wang Dongsheng dongsheng.w...@freescale.com Can you please check the current linux-next branch of the linux-pm.git tree and see if that doesn't conflict with the material in there? Also please explain in the changelog how your changes help to fix the problem. Yes, Linux-next branch also have this problem. Should I base on Linux-next to fix this problem? Thanks. - dongsheng ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: Inbound PCI and Memory Corruption
On Fri, Jul 19, 2013 at 6:46 AM, Gerhard Sittig g...@denx.de wrote: So: No, not having to fiddle with DMA stuff when doing PCI need not be a problem, it's actually expected. But since a DMA engine might be involved (that's just not under your command), the accompanying problems may arise. You may need to flush CPU provided data upon write before telling an external entity to access it, and may need to invalidate caches (to have data re-fetched) before the CPU accesses what an external entity did manipulate. And this applies to both payload data as well as management data (descriptors) if the latter apply to the former. This is something I've been exploring today. But what is unclear is _how_ to flush/invalidate the caches'. I was going to tweak the driver to setup the descriptors, flush the cache, then enable the hardware (and when taking the device down, disable the hardware, flush the cache, then deallocate the descriptors). But this is in the network code and it isn't obvious how to make this happen. I think I figured something out. Basically, in the receive interrupt, prior to reading the data in the descriptor, I call dma_sync_single_for_cpu(). Then the driver can continue to process the data, then unmap the DMA region (with dma_unmap_single() ). When setting up the descriptors, after calling dma_map_single(), configuring the descriptor, I then call dma_sync_single_for_device(). Does this look correct? However, on the PPC platforms, these calls (dma_sync_*) are NOPs unless CONFIG_NOT_COHERENT_CACHE is defined (which it doesn't appear to be for the 8349). So I tweaked the Kconfig to enable CONFIG_NOT_COHERENT. Things built ok, but I'm not sure if this is sufficient to invoke the cache flush necessary. Am I on the right track? Thanks, Pete ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: Inbound PCI and Memory Corruption
On Tue, 2013-07-23 at 21:22 -0700, Peter LaDow wrote: On Fri, Jul 19, 2013 at 6:46 AM, Gerhard Sittig g...@denx.de wrote: So: No, not having to fiddle with DMA stuff when doing PCI need not be a problem, it's actually expected. But since a DMA engine might be involved (that's just not under your command), the accompanying problems may arise. You may need to flush CPU provided data upon write before telling an external entity to access it, and may need to invalidate caches (to have data re-fetched) before the CPU accesses what an external entity did manipulate. And this applies to both payload data as well as management data (descriptors) if the latter apply to the former. This is something I've been exploring today. But what is unclear is _how_ to flush/invalidate the caches'. I was going to tweak the driver to setup the descriptors, flush the cache, then enable the hardware (and when taking the device down, disable the hardware, flush the cache, then deallocate the descriptors). But this is in the network code and it isn't obvious how to make this happen. CONFIG_NOT_COHERENT_CACHE will do it for you (in arch/powerpc/kernel/dma.c) provided the driver does the right things vs. the DMA accessors but afaik e1000 does. The problem with that is we never officially supported that option of non-coherent cache (non-coherent DMA) on any of the S processors (including 603 aka e300) because first they are supposed to be used in coherent fabrics, but also because the code somewhat assumes that your CPU won't suddenly prefetch stuff back into the cache at any time. The 603 does some amount of speculative prefech, so potentially might pollute the cache. But it's still worth trying out. If that helps, that might hint at either a missing barrier or some kind of HW (or HW configuration) bug with cache coherency. I think I figured something out. Basically, in the receive interrupt, prior to reading the data in the descriptor, I call dma_sync_single_for_cpu(). Then the driver can continue to process the data, then unmap the DMA region (with dma_unmap_single() ). When setting up the descriptors, after calling dma_map_single(), configuring the descriptor, I then call dma_sync_single_for_device(). Does this look correct? Yes. However, on the PPC platforms, these calls (dma_sync_*) are NOPs unless CONFIG_NOT_COHERENT_CACHE is defined (which it doesn't appear to be for the 8349). So I tweaked the Kconfig to enable CONFIG_NOT_COHERENT. Things built ok, but I'm not sure if this is sufficient to invoke the cache flush necessary. Am I on the right track? Well, they are supposed to be nops ... that's the thing. Because afaik, anything built on a 603 core is *supposed* to be coherent (though those NOPs should at least be memory barriers imho). In any case, let us know if that helps. Cheers, Ben. Thanks, Pete ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH] powerpc: VPHN topology change updates all siblings
On Tue, 2013-07-23 at 07:33 -0500, Robert Jennings wrote: When an associativity level change is found for one thread, the siblings threads need to be updated as well. This is done today for PRRN in stage_topology_update() but is missing for VPHN in update_cpu_associativity_changes_mask(). All threads should be updated to move to the new node. Without this patch, a single thread may be flagged for a topology change, leaving it in a different node from its siblings, which is incorrect. This causes problems for the scheduler where overlapping scheduler groups are created and a loop is formed in those groups. Reported-by: Jan Stancek jstan...@redhat.com Signed-off-by: Robert Jennings r...@linux.vnet.ibm.com Cc: sta...@vger.kernel.org Patch breaks the UP build ... Cheers, Ben. ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH 1/3] cpufreq: pmac64: speed up frequency switch
On 24 July 2013 01:54, Aaro Koskinen aaro.koski...@iki.fi wrote: Some functions on switch path use msleep() which is inaccurate, and depends on HZ. With HZ=100 msleep(1) takes actually over ten times longer. Using usleep_range() we get more accurate sleeps. I measured the pfunc_slewing_done polling to take 300us at max (on 2.3GHz dual-processor Xserve G5), so using 500us sleep there should be fine. With the patch, g5_switch_freq() duration drops from ~50ms to ~10ms on Xserve with HZ=100. Signed-off-by: Aaro Koskinen aaro.koski...@iki.fi --- drivers/cpufreq/pmac64-cpufreq.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) Looks fine to me as well.. Acked-by: Viresh Kumar viresh.ku...@linaro.org ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH 3/3] cpufreq: pmac64: enable cpufreq on iMac G5 (iSight) model
On 24 July 2013 01:54, Aaro Koskinen aaro.koski...@iki.fi wrote: Enable cpufreq on iMac G5 (iSight) model. Tested with the 2.1 GHz version. Signed-off-by: Aaro Koskinen aaro.koski...@iki.fi --- drivers/cpufreq/pmac64-cpufreq.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) Acked-by: Viresh Kumar viresh.ku...@linaro.org ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH 2/3] cpufreq: pmac64: re-estimate G5 cpufreq transition latency
On 24 July 2013 01:54, Aaro Koskinen aaro.koski...@iki.fi wrote: The patch also enables to use ondemand governor on the latter. How? I can't see anything obvious here. :( Signed-off-by: Aaro Koskinen aaro.koski...@iki.fi --- drivers/cpufreq/pmac64-cpufreq.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/cpufreq/pmac64-cpufreq.c b/drivers/cpufreq/pmac64-cpufreq.c index 674807d..f9e399b 100644 --- a/drivers/cpufreq/pmac64-cpufreq.c +++ b/drivers/cpufreq/pmac64-cpufreq.c @@ -85,7 +85,8 @@ static int (*g5_query_freq)(void); static DEFINE_MUTEX(g5_switch_mutex); -static unsigned long transition_latency; +/* A conservative estimate, based on Xserve G5 and iMac G5 (iSight). */ +static const unsigned long transition_latency = 10 * NSEC_PER_MSEC; #ifdef CONFIG_PMAC_SMU @@ -499,7 +500,6 @@ static int __init g5_neo2_cpufreq_init(struct device_node *cpus) g5_cpu_freqs[1].frequency = max_freq/2; /* Set callbacks */ - transition_latency = 12000; g5_switch_freq = g5_scom_switch_freq; g5_query_freq = g5_scom_query_freq; freq_method = SCOM; @@ -675,7 +675,6 @@ static int __init g5_pm72_cpufreq_init(struct device_node *cpus) g5_cpu_freqs[1].frequency = min_freq; /* Set callbacks */ - transition_latency = CPUFREQ_ETERNAL; g5_switch_volt = g5_pfunc_switch_volt; g5_switch_freq = g5_pfunc_switch_freq; g5_query_freq = g5_pfunc_query_freq; -- 1.8.3.2 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev