RE: [PATCH v5] powerpc/mpc85xx: Update the clock nodes in device tree
Thanks for your review. -Original Message- From: Wood Scott-B07421 Sent: 2013年10月29日 星期二 11:26 To: Tang Yuantian-B29983 Cc: Wood Scott-B07421; Mark Rutland; devicet...@vger.kernel.org; linuxppc-dev@lists.ozlabs.org; Li Yang-Leo-R58472 Subject: Re: [PATCH v5] powerpc/mpc85xx: Update the clock nodes in device tree On Sun, 2013-10-20 at 21:55 -0500, Tang Yuantian-B29983 wrote: I didn't see how your suggestion is a better matching. OSC PLL1 mux CPU | | |-- PLL2 --| As your suggestion, the clock tree looks like the above. In this case, the MUX driver will not know the divider details(/2, /4, or /3). When is there ever a /3? For T4, there is a /3, but it is used by PME not CPU. I think the MUX should act like switch which choose one of the input clock as a output clock. It should not CREATE clock(like PLL1/2, PLL1/4). The purpose of clock driver is to establish the clock tree. The clock tree will not be established in your suggestion because the divider is missing, we don't know where PLL/2 comes from. If you really like your proposal, it should be changed to this: OSC -- PLL1 - PLL1 /1 - MUX ---CPU ||___ PLL1 /2 ___| | | | PLL2 - PLL2 /2 ---| |___ PLL2/ 4 ___| (it is possible that PLLs have different divider). Do we actually have (or expect) a situation where the PLLs have different dividers, or even where the same bit setting in the MUX register means a different divider from one chip to another (within the same MUX compatible string)? If so, then I agree that we should go with your approach. For a specific chip, the dividers are same for each PLL. But CPU may use ONLY one of the dividers of a PLL. For example, on p4080, core0-3 may use PLL3/1, but do not use PLL3/2. (I didn't deal with this situation in driver either because there are limitations to use it). The way Freescale documents things in chip manuals rather than in block manuals, with little bits of information different in each chip manual, makes it hard to figure out this sort of thing. From the examples I looked at, it seemed pretty consistent that the low 2 bits of CLKSEL in the MUX were the log2 of the divider. Are there any chips that don't adhere to this? Your observation is correct until then. But there is no rule on this officially. Now I want to summary the pros and cons of your suggestion: The pros: 1. the device tree would be simpler. The cons: 1. cannot get the whole clock tree picture because dividers are hidden in driver. 2. no way to deal with the use case on p4080 3. need to deal with each chip-clockgen compatible string and pass a parameter to tell it what the divider is. 4. the log2 rule could be incorrect in future, say, we have a divider of /5. Any thoughts on this? Regards, Yuantian ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
RE: [PATCHv1 1/8] ALSA: Add SAI SoC Digital Audio Interface driver.
-Original Message- From: Chen Guangyu-B42378 Sent: Tuesday, October 29, 2013 12:02 PM To: Xiubo Li-B47053 Cc: Mark Brown; Guo Shawn-R65073; ti...@tabi.org; lgirdw...@gmail.com; Jin Zhengxiong-R64188; rob.herr...@calxeda.com; pawel.m...@arm.com; mark.rutl...@arm.com; swar...@wwwdotorg.org; ian.campb...@citrix.com; r...@landley.net; li...@arm.linux.org.uk; pe...@perex.cz; ti...@suse.de; grant.lik...@linaro.org; Estevam Fabio-R49496; l...@karo-electronics.de; os...@scara.com; shawn@linaro.org; Wang Huan-B18965; devicet...@vger.kernel.org; linux-...@vger.kernel.org; linux- ker...@vger.kernel.org; linux-arm-ker...@lists.infradead.org; alsa- de...@alsa-project.org; linuxppc-dev@lists.ozlabs.org Subject: Re: [PATCHv1 1/8] ALSA: Add SAI SoC Digital Audio Interface driver. On Tue, Oct 29, 2013 at 12:00:57PM +0800, Xiubo Li-B47053 wrote: There's a patch in -next that lets the generic dmaengine code figure out some settings from the dmacontroller rather than requiring the driver to explicitly provide configuration - it's ASoC: dmaengine-pcm: Provide default config. Please update your driver to use this, or let's work out what it doesn't do any try to fix it. I couldn't find the patch in the next and other trees. Does this patch has been submitted to the -next tree ? Or could you tell me how to find the patch please? Are you using broonie's repository? NO. git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git If you searched the title in for-next branch, you should have found it. Yes, find it. Thanks very much. -- Xiubo ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: perf events ring buffer memory barrier on powerpc
On Mon, Oct 28, 2013 at 10:58:58PM +0200, Victor Kaplansky wrote: Oleg Nesterov o...@redhat.com wrote on 10/28/2013 10:17:35 PM: mb(); // : do we really need it? I think yes. Oh, it is hard to argue with feelings. Also, it is easy to be on conservative side and put the barrier here just in case. I'll make it a full mb for now and too am curious to see the end of this discussion explaining things ;-) ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: perf events ring buffer memory barrier on powerpc
On Tue, Oct 29, 2013 at 11:21:31AM +0100, Peter Zijlstra wrote: On Mon, Oct 28, 2013 at 10:58:58PM +0200, Victor Kaplansky wrote: Oleg Nesterov o...@redhat.com wrote on 10/28/2013 10:17:35 PM: mb(); // : do we really need it? I think yes. Oh, it is hard to argue with feelings. Also, it is easy to be on conservative side and put the barrier here just in case. I'll make it a full mb for now and too am curious to see the end of this discussion explaining things ;-) That is, I've now got this queued: --- Subject: perf: Fix perf ring buffer memory ordering From: Peter Zijlstra pet...@infradead.org Date: Mon Oct 28 13:55:29 CET 2013 The PPC64 people noticed a missing memory barrier and crufty old comments in the perf ring buffer code. So update all the comments and add the missing barrier. When the architecture implements local_t using atomic_long_t there will be double barriers issued; but short of introducing more conditional barrier primitives this is the best we can do. Cc: Mathieu Desnoyers mathieu.desnoy...@polymtl.ca Cc: mich...@ellerman.id.au Cc: Paul McKenney paul...@linux.vnet.ibm.com Cc: Michael Neuling mi...@neuling.org Cc: Frederic Weisbecker fweis...@gmail.com Cc: an...@samba.org Cc: b...@kernel.crashing.org Reported-by: Victor Kaplansky vict...@il.ibm.com Tested-by: Victor Kaplansky vict...@il.ibm.com Signed-off-by: Peter Zijlstra pet...@infradead.org Link: http://lkml.kernel.org/r/20131025173749.gg19...@laptop.lan --- include/uapi/linux/perf_event.h | 12 +++- kernel/events/ring_buffer.c | 31 +++ 2 files changed, 34 insertions(+), 9 deletions(-) Index: linux-2.6/include/uapi/linux/perf_event.h === --- linux-2.6.orig/include/uapi/linux/perf_event.h +++ linux-2.6/include/uapi/linux/perf_event.h @@ -479,13 +479,15 @@ struct perf_event_mmap_page { /* * Control data for the mmap() data buffer. * -* User-space reading the @data_head value should issue an rmb(), on -* SMP capable platforms, after reading this value -- see -* perf_event_wakeup(). +* User-space reading the @data_head value should issue an smp_rmb(), +* after reading this value. * * When the mapping is PROT_WRITE the @data_tail value should be -* written by userspace to reflect the last read data. In this case -* the kernel will not over-write unread data. +* written by userspace to reflect the last read data, after issueing +* an smp_mb() to separate the data read from the -data_tail store. +* In this case the kernel will not over-write unread data. +* +* See perf_output_put_handle() for the data ordering. */ __u64 data_head; /* head in the data section */ __u64 data_tail; /* user-space written tail */ Index: linux-2.6/kernel/events/ring_buffer.c === --- linux-2.6.orig/kernel/events/ring_buffer.c +++ linux-2.6/kernel/events/ring_buffer.c @@ -87,10 +87,31 @@ static void perf_output_put_handle(struc goto out; /* -* Publish the known good head. Rely on the full barrier implied -* by atomic_dec_and_test() order the rb-head read and this -* write. +* Since the mmap() consumer (userspace) can run on a different CPU: +* +* kernel user +* +* READ -data_tail READ -data_head +* smp_mb() (A) smp_rmb() (C) +* WRITE $dataREAD $data +* smp_wmb() (B) smp_mb()(D) +* STORE -data_head WRITE -data_tail +* +* Where A pairs with D, and B pairs with C. +* +* I don't think A needs to be a full barrier because we won't in fact +* write data until we see the store from userspace. So we simply don't +* issue the data WRITE until we observe it. Be conservative for now. +* +* OTOH, D needs to be a full barrier since it separates the data READ +* from the tail WRITE. +* +* For B a WMB is sufficient since it separates two WRITEs, and for C +* an RMB is sufficient since it separates two READs. +* +* See perf_output_begin(). */ + smp_wmb(); rb-user_page-data_head = head; /* @@ -154,9 +175,11 @@ int perf_output_begin(struct perf_output * Userspace could choose to issue a mb() before updating the * tail pointer. So that all reads will be completed before the * write is issued. +* +* See perf_output_put_handle(). */ tail =
Re: perf events ring buffer memory barrier on powerpc
On Tue, Oct 29, 2013 at 11:30:57AM +0100, Peter Zijlstra wrote: @@ -154,9 +175,11 @@ int perf_output_begin(struct perf_output * Userspace could choose to issue a mb() before updating the * tail pointer. So that all reads will be completed before the * write is issued. + * + * See perf_output_put_handle(). */ tail = ACCESS_ONCE(rb-user_page-data_tail); - smp_rmb(); + smp_mb(); offset = head = local_read(rb-head); head += size; if (unlikely(!perf_output_space(rb, tail, offset, head))) That said; it would be very nice to be able to remove this barrier. This is in every event write path :/ ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH V7 0/7] POWER/cpuidle: Generic IBM-POWER cpuidle driver enabled for PSERIES and POWERNV platforms
This patch series consolidates the backend cpuidle driver for pSeries and powernv platforms with minimal code duplication. Current existing backend driver for pseries has been moved to drivers/cpuidle and has been extended to accommodate powernv idle power mgmt states. As seen in V1 of this patch series, having a separate powernv backend driver results in too much code duplication, which is less elegant and can pose maintenance problems going further. Using the cpuidle framework to exploit platform low power idle states management can take advantage of advanced heuristics, tunables and features provided by 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. Earlier in 3.3 kernel, pSeries idle state management was modified to exploit the cpuidle framework and the end goal of this patch is to have powernv platform also to hook its idle states into cpuidle framework with minimal code duplication between both platforms. This series aims to maintain compatibility and functionality to existing pseries and 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. V1 - http://lkml.org/lkml/2013/7/23/143 V2 - https://lkml.org/lkml/2013/7/30/872 V3 - http://comments.gmane.org/gmane.linux.ports.ppc.embedded/63093 V4 - https://lkml.org/lkml/2013/8/22/25 V5 - http://lkml.org/lkml/2013/8/22/184 V6 - https://lkml.org/lkml/2013/8/27/432 Changes in V7: * Rebased to the latest kernel 3.12-rc7 * Default idle routine to be called on POWERNV is power7_idle() instead of HMT_low() routines. Changes in V6: = * Made changes in Patch3: Generic POWER cpuidle driver in V5 by breaking down to multiple patches, as there were multiple changes including moving the file location. * Remove MAX_IDLE_STATE macro and kernel command line for IBM-POWER systems. * Make backend driver a built-in, instead of a module. As building this as a module is currently not possible. * Generic backend driver minor cleanups. * First two patches in V5 are not a part of the series, as they are generic cleanups, already pushed into the tree. Changes in V5: = * As per the discussions in the community, this patch series enables cpuidle backend driver only for IBM-POWER platforms. File is re-named from drivers/cpuidle/cpuidle-powerpc.c to drivers/cpuidle/cpuildle-ibm-power.c New back-end cpuidle driver is called IBM-POWER-Idle. * General cleanups on the accessors front that was introduced in previous version. Changes in V4: = * This patch series includes generic backend driver cpuidle cleanups including, replacing the driver and device initialisation routines with cpuidle_register function. * Enable CPUIDLE framework only for POWER and POWERNV platforms. Changes in V3: = * This patch series does not include smt-snooze-delay fixes. This will be taken up later on. * Integrated POWERPC driver in drivers/cpuidle. Enabled for all of POWERPC platform. Currently has PSERIES and POWERNV support. No compile time flags in .c file. This will be one consolidated binary that does a run time detection based on platform and take decisions accordingly. * Enabled CPUIDLE framwork for all of PPC64. Changes in V2: = * Merged the backend driver posted out for powernv in V1 with pSeries to create a single powerpc driver but this had compile time flags. Deepthi Dharwar (7): pseries/cpuidle: Move processor_idle.c to drivers/cpuidle. pseries/cpuidle: Use cpuidle_register() for initialisation. pseries/cpuidle: Make pseries_idle backend driver a non-module. pseries/cpuidle: Remove MAX_IDLE_STATE macro. POWER/cpuidle: Generic POWER CPUIDLE driver supporting PSERIES. POWER/cpuidle: Enable powernv cpuidle support. powernv/cpuidle: Enable idle powernv cpu to call into the cpuidle framework. arch/powerpc/include/asm/processor.h|2 arch/powerpc/platforms/powernv/setup.c | 13 + arch/powerpc/platforms/pseries/Kconfig |9 - arch/powerpc/platforms/pseries/Makefile |1 arch/powerpc/platforms/pseries/processor_idle.c | 364 --- drivers/cpuidle/Kconfig |5 drivers/cpuidle/Kconfig.powerpc | 10 + drivers/cpuidle/Makefile|4 drivers/cpuidle/cpuidle-ibm-power.c | 320 9 files changed, 352 insertions(+), 376 deletions(-) delete mode 100644 arch/powerpc/platforms/pseries/processor_idle.c create mode 100644 drivers/cpuidle/Kconfig.powerpc create mode 100644
[PATCH V7 2/7] pseries/cpuidle: Use cpuidle_register() for initialisation.
This patch replaces the cpuidle driver and devices initialisation calls with a single generic cpuidle_register() call and also includes minor refactoring of the code around it. Signed-off-by: Deepthi Dharwar deep...@linux.vnet.ibm.com --- drivers/cpuidle/cpuidle-ibm-power.c | 80 +-- 1 file changed, 12 insertions(+), 68 deletions(-) diff --git a/drivers/cpuidle/cpuidle-ibm-power.c b/drivers/cpuidle/cpuidle-ibm-power.c index a166e38..faf8cc1 100644 --- a/drivers/cpuidle/cpuidle-ibm-power.c +++ b/drivers/cpuidle/cpuidle-ibm-power.c @@ -1,5 +1,5 @@ /* - * processor_idle - idle state cpuidle driver. + * cpuidle-ibm-power - idle state cpuidle driver. * Adapted from drivers/idle/intel_idle.c and * drivers/acpi/processor_idle.c * @@ -28,7 +28,6 @@ struct cpuidle_driver pseries_idle_driver = { #define MAX_IDLE_STATE_COUNT 2 static int max_idle_state = MAX_IDLE_STATE_COUNT - 1; -static struct cpuidle_device __percpu *pseries_cpuidle_devices; static struct cpuidle_state *cpuidle_state_table; static inline void idle_loop_prolog(unsigned long *in_purr) @@ -56,13 +55,12 @@ static int snooze_loop(struct cpuidle_device *dev, int index) { unsigned long in_purr; - int cpu = dev-cpu; idle_loop_prolog(in_purr); local_irq_enable(); set_thread_flag(TIF_POLLING_NRFLAG); - while ((!need_resched()) cpu_online(cpu)) { + while (!need_resched()) { ppc64_runlatch_off(); HMT_low(); HMT_very_low(); @@ -191,7 +189,7 @@ static int pseries_cpuidle_add_cpu_notifier(struct notifier_block *n, { int hotcpu = (unsigned long)hcpu; struct cpuidle_device *dev = - per_cpu_ptr(pseries_cpuidle_devices, hotcpu); + per_cpu(cpuidle_devices, hotcpu); if (dev cpuidle_get_driver()) { switch (action) { @@ -248,50 +246,6 @@ static int pseries_cpuidle_driver_init(void) return 0; } -/* pseries_idle_devices_uninit(void) - * unregister cpuidle devices and de-allocate memory - */ -static void pseries_idle_devices_uninit(void) -{ - int i; - struct cpuidle_device *dev; - - for_each_possible_cpu(i) { - dev = per_cpu_ptr(pseries_cpuidle_devices, i); - cpuidle_unregister_device(dev); - } - - free_percpu(pseries_cpuidle_devices); - return; -} - -/* pseries_idle_devices_init() - * allocate, initialize and register cpuidle device - */ -static int pseries_idle_devices_init(void) -{ - int i; - struct cpuidle_driver *drv = pseries_idle_driver; - struct cpuidle_device *dev; - - pseries_cpuidle_devices = alloc_percpu(struct cpuidle_device); - if (pseries_cpuidle_devices == NULL) - return -ENOMEM; - - for_each_possible_cpu(i) { - dev = per_cpu_ptr(pseries_cpuidle_devices, i); - dev-state_count = drv-state_count; - dev-cpu = i; - if (cpuidle_register_device(dev)) { - printk(KERN_DEBUG \ - cpuidle_register_device %d failed!\n, i); - return -EIO; - } - } - - return 0; -} - /* * pseries_idle_probe() * Choose state table for shared versus dedicated partition @@ -299,9 +253,6 @@ static int pseries_idle_devices_init(void) static int pseries_idle_probe(void) { - if (!firmware_has_feature(FW_FEATURE_SPLPAR)) - return -ENODEV; - if (cpuidle_disable != IDLE_NO_OVERRIDE) return -ENODEV; @@ -310,10 +261,13 @@ static int pseries_idle_probe(void) return -EPERM; } - if (lppaca_shared_proc(get_lppaca())) - cpuidle_state_table = shared_states; - else - cpuidle_state_table = dedicated_states; + if (firmware_has_feature(FW_FEATURE_SPLPAR)) { + if (lppaca_shared_proc(get_lppaca())) + cpuidle_state_table = shared_states; + else + cpuidle_state_table = dedicated_states; + } else + return -ENODEV; return 0; } @@ -327,22 +281,14 @@ static int __init pseries_processor_idle_init(void) return retval; pseries_cpuidle_driver_init(); - retval = cpuidle_register_driver(pseries_idle_driver); + retval = cpuidle_register(pseries_idle_driver, NULL); if (retval) { printk(KERN_DEBUG Registration of pseries driver failed.\n); return retval; } - retval = pseries_idle_devices_init(); - if (retval) { - pseries_idle_devices_uninit(); - cpuidle_unregister_driver(pseries_idle_driver); - return retval; - } - register_cpu_notifier(setup_hotplug_notifier); printk(KERN_DEBUG
[PATCH V7 1/7] pseries/cpuidle: Move processor_idle.c to drivers/cpuidle.
Move the file from arch specific pseries/processor_idle.c to drivers/cpuidle/cpuidle-ibm-power.c Make the relevant Makefile and Kconfig changes. This will enable having a common backend cpuidle driver for POWER platform going forward. Signed-off-by: Deepthi Dharwar deep...@linux.vnet.ibm.com --- arch/powerpc/include/asm/processor.h|2 arch/powerpc/platforms/pseries/Kconfig |9 - arch/powerpc/platforms/pseries/Makefile |1 arch/powerpc/platforms/pseries/processor_idle.c | 364 --- drivers/cpuidle/Kconfig |5 drivers/cpuidle/Kconfig.powerpc | 10 + drivers/cpuidle/Makefile|4 drivers/cpuidle/cpuidle-ibm-power.c | 364 +++ 8 files changed, 384 insertions(+), 375 deletions(-) delete mode 100644 arch/powerpc/platforms/pseries/processor_idle.c create mode 100644 drivers/cpuidle/Kconfig.powerpc create mode 100644 drivers/cpuidle/cpuidle-ibm-power.c diff --git a/arch/powerpc/include/asm/processor.h b/arch/powerpc/include/asm/processor.h index ce4de5a..d53bb88 100644 --- a/arch/powerpc/include/asm/processor.h +++ b/arch/powerpc/include/asm/processor.h @@ -428,7 +428,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 +#ifdef CONFIG_CPU_IDLE_IBM_POWER 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/pseries/Kconfig b/arch/powerpc/platforms/pseries/Kconfig index 62b4f80..bb59bb0 100644 --- a/arch/powerpc/platforms/pseries/Kconfig +++ b/arch/powerpc/platforms/pseries/Kconfig @@ -119,12 +119,3 @@ config DTL which are accessible through a debugfs file. Say N if you are unsure. - -config PSERIES_IDLE - bool Cpuidle driver for pSeries platforms - depends on CPU_IDLE - depends on PPC_PSERIES - default y - help - Select this option to enable processor idle state management - through cpuidle subsystem. diff --git a/arch/powerpc/platforms/pseries/Makefile b/arch/powerpc/platforms/pseries/Makefile index 6c61ec5..6f2500b 100644 --- a/arch/powerpc/platforms/pseries/Makefile +++ b/arch/powerpc/platforms/pseries/Makefile @@ -21,7 +21,6 @@ obj-$(CONFIG_HCALL_STATS) += hvCall_inst.o obj-$(CONFIG_CMM) += cmm.o obj-$(CONFIG_DTL) += dtl.o obj-$(CONFIG_IO_EVENT_IRQ) += io_event_irq.o -obj-$(CONFIG_PSERIES_IDLE) += processor_idle.o obj-$(CONFIG_LPARCFG) += lparcfg.o ifeq ($(CONFIG_PPC_PSERIES),y) diff --git a/arch/powerpc/platforms/pseries/processor_idle.c b/arch/powerpc/platforms/pseries/processor_idle.c deleted file mode 100644 index a166e38..000 --- a/arch/powerpc/platforms/pseries/processor_idle.c +++ /dev/null @@ -1,364 +0,0 @@ -/* - * processor_idle - idle state cpuidle driver. - * Adapted from drivers/idle/intel_idle.c and - * drivers/acpi/processor_idle.c - * - */ - -#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/paca.h -#include asm/reg.h -#include asm/machdep.h -#include asm/firmware.h -#include asm/runlatch.h -#include asm/plpar_wrappers.h - -struct cpuidle_driver pseries_idle_driver = { - .name = pseries_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 *pseries_cpuidle_devices; -static struct cpuidle_state *cpuidle_state_table; - -static inline void idle_loop_prolog(unsigned long *in_purr) -{ - *in_purr = mfspr(SPRN_PURR); - /* -* Indicate to the HV that we are idle. Now would be -* a good time to find other work to dispatch. -*/ - get_lppaca()-idle = 1; -} - -static inline void idle_loop_epilog(unsigned long in_purr) -{ - u64 wait_cycles; - - wait_cycles = be64_to_cpu(get_lppaca()-wait_state_cycles); - wait_cycles += mfspr(SPRN_PURR) - in_purr; - get_lppaca()-wait_state_cycles = cpu_to_be64(wait_cycles); - get_lppaca()-idle = 0; -} - -static int snooze_loop(struct cpuidle_device *dev, - struct cpuidle_driver *drv, - int index) -{ - unsigned long in_purr; - int cpu = dev-cpu; - - idle_loop_prolog(in_purr); - local_irq_enable(); - set_thread_flag(TIF_POLLING_NRFLAG); - - while ((!need_resched()) cpu_online(cpu)) { - ppc64_runlatch_off(); - HMT_low(); - HMT_very_low(); - } - - HMT_medium(); - clear_thread_flag(TIF_POLLING_NRFLAG); -
[PATCH V7 3/7] pseries/cpuidle: Make pseries_idle backend driver a non-module.
Currently pseries_idle cpuidle backend driver cannot be built as a module due to dependencies. Therefore the driver has to be built in. The dependency is around update_snooze_delay() defined in cpuidle driver and called from kernel/sysfs.c. This patch is removes all the module related code. Signed-off-by: Deepthi Dharwar deep...@linux.vnet.ibm.com --- drivers/cpuidle/cpuidle-ibm-power.c | 15 +-- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/drivers/cpuidle/cpuidle-ibm-power.c b/drivers/cpuidle/cpuidle-ibm-power.c index faf8cc1..8c9e42c 100644 --- a/drivers/cpuidle/cpuidle-ibm-power.c +++ b/drivers/cpuidle/cpuidle-ibm-power.c @@ -292,17 +292,4 @@ static int __init pseries_processor_idle_init(void) return 0; } -static void __exit pseries_processor_idle_exit(void) -{ - - unregister_cpu_notifier(setup_hotplug_notifier); - cpuidle_unregister(pseries_idle_driver); - return; -} - -module_init(pseries_processor_idle_init); -module_exit(pseries_processor_idle_exit); - -MODULE_AUTHOR(Deepthi Dharwar deep...@linux.vnet.ibm.com); -MODULE_DESCRIPTION(Cpuidle driver for POWER); -MODULE_LICENSE(GPL); +device_initcall(pseries_processor_idle_init); ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH V7 4/7] pseries/cpuidle: Remove MAX_IDLE_STATE macro.
This patch removes the usage of MAX_IDLE_STATE macro and dead code around it. The number of states are determined at run time based on the cpuidle state table selected on a given platform Signed-off-by: Deepthi Dharwar deep...@linux.vnet.ibm.com --- drivers/cpuidle/cpuidle-ibm-power.c | 26 +- 1 file changed, 9 insertions(+), 17 deletions(-) diff --git a/drivers/cpuidle/cpuidle-ibm-power.c b/drivers/cpuidle/cpuidle-ibm-power.c index 8c9e42c..e81c207 100644 --- a/drivers/cpuidle/cpuidle-ibm-power.c +++ b/drivers/cpuidle/cpuidle-ibm-power.c @@ -25,9 +25,7 @@ struct cpuidle_driver pseries_idle_driver = { .owner= THIS_MODULE, }; -#define MAX_IDLE_STATE_COUNT 2 - -static int max_idle_state = MAX_IDLE_STATE_COUNT - 1; +static int max_idle_state; static struct cpuidle_state *cpuidle_state_table; static inline void idle_loop_prolog(unsigned long *in_purr) @@ -137,7 +135,7 @@ static int shared_cede_loop(struct cpuidle_device *dev, /* * States for dedicated partition case. */ -static struct cpuidle_state dedicated_states[MAX_IDLE_STATE_COUNT] = { +static struct cpuidle_state dedicated_states[] = { { /* Snooze */ .name = snooze, .desc = snooze, @@ -157,7 +155,7 @@ static struct cpuidle_state dedicated_states[MAX_IDLE_STATE_COUNT] = { /* * States for shared partition case. */ -static struct cpuidle_state shared_states[MAX_IDLE_STATE_COUNT] = { +static struct cpuidle_state shared_states[] = { { /* Shared Cede */ .name = Shared Cede, .desc = Shared Cede, @@ -227,11 +225,7 @@ static int pseries_cpuidle_driver_init(void) struct cpuidle_driver *drv = pseries_idle_driver; drv-state_count = 0; - - for (idle_state = 0; idle_state MAX_IDLE_STATE_COUNT; ++idle_state) { - - if (idle_state max_idle_state) - break; + for (idle_state = 0; idle_state max_idle_state; ++idle_state) { /* is the state not enabled? */ if (cpuidle_state_table[idle_state].enter == NULL) @@ -256,16 +250,14 @@ static int pseries_idle_probe(void) if (cpuidle_disable != IDLE_NO_OVERRIDE) return -ENODEV; - if (max_idle_state == 0) { - printk(KERN_DEBUG pseries processor idle disabled.\n); - return -EPERM; - } - if (firmware_has_feature(FW_FEATURE_SPLPAR)) { - if (lppaca_shared_proc(get_lppaca())) + if (lppaca_shared_proc(get_lppaca())) { cpuidle_state_table = shared_states; - else + max_idle_state = ARRAY_SIZE(shared_states); + } else { cpuidle_state_table = dedicated_states; + max_idle_state = ARRAY_SIZE(dedicated_states); + } } else return -ENODEV; ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH V7 5/7] POWER/cpuidle: Generic POWER CPUIDLE driver supporting PSERIES.
This patch includes cleanup and refactoring of the existing code to make the driver POWER generic. * Re-naming the functions from pseries to generic power. * Re-naming the backend driver from pseries_idle to ibm-power-idle. Signed-off-by: Deepthi Dharwar deep...@linux.vnet.ibm.com --- drivers/cpuidle/cpuidle-ibm-power.c | 32 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/drivers/cpuidle/cpuidle-ibm-power.c b/drivers/cpuidle/cpuidle-ibm-power.c index e81c207..5b92242 100644 --- a/drivers/cpuidle/cpuidle-ibm-power.c +++ b/drivers/cpuidle/cpuidle-ibm-power.c @@ -20,8 +20,8 @@ #include asm/runlatch.h #include asm/plpar_wrappers.h -struct cpuidle_driver pseries_idle_driver = { - .name = pseries_idle, +struct cpuidle_driver power_idle_driver = { + .name = ibm_power_idle, .owner= THIS_MODULE, }; @@ -182,7 +182,7 @@ void update_smt_snooze_delay(int cpu, int residency) drv-states[1].target_residency = residency; } -static int pseries_cpuidle_add_cpu_notifier(struct notifier_block *n, +static int power_cpuidle_add_cpu_notifier(struct notifier_block *n, unsigned long action, void *hcpu) { int hotcpu = (unsigned long)hcpu; @@ -213,16 +213,16 @@ static int pseries_cpuidle_add_cpu_notifier(struct notifier_block *n, } static struct notifier_block setup_hotplug_notifier = { - .notifier_call = pseries_cpuidle_add_cpu_notifier, + .notifier_call = power_cpuidle_add_cpu_notifier, }; /* - * pseries_cpuidle_driver_init() + * power_cpuidle_driver_init() */ -static int pseries_cpuidle_driver_init(void) +static int power_cpuidle_driver_init(void) { int idle_state; - struct cpuidle_driver *drv = pseries_idle_driver; + struct cpuidle_driver *drv = power_idle_driver; drv-state_count = 0; for (idle_state = 0; idle_state max_idle_state; ++idle_state) { @@ -241,10 +241,10 @@ static int pseries_cpuidle_driver_init(void) } /* - * pseries_idle_probe() + * power_idle_probe() * Choose state table for shared versus dedicated partition */ -static int pseries_idle_probe(void) +static int power_idle_probe(void) { if (cpuidle_disable != IDLE_NO_OVERRIDE) @@ -264,24 +264,24 @@ static int pseries_idle_probe(void) return 0; } -static int __init pseries_processor_idle_init(void) +static int __init power_processor_idle_init(void) { int retval; - retval = pseries_idle_probe(); + retval = power_idle_probe(); if (retval) return retval; - pseries_cpuidle_driver_init(); - retval = cpuidle_register(pseries_idle_driver, NULL); + power_cpuidle_driver_init(); + retval = cpuidle_register(power_idle_driver, NULL); if (retval) { - printk(KERN_DEBUG Registration of pseries driver failed.\n); + printk(KERN_DEBUG Registration of ibm_power_idle driver failed.\n); return retval; } register_cpu_notifier(setup_hotplug_notifier); - printk(KERN_DEBUG pseries_idle_driver registered\n); + printk(KERN_DEBUG ibm_power_idle registered\n); return 0; } -device_initcall(pseries_processor_idle_init); +device_initcall(power_processor_idle_init); ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH V7 6/7] POWER/cpuidle: Enable powernv cpuidle support.
The following patch extends the current power backend idle driver to the powernv platform. Signed-off-by: Deepthi Dharwar deep...@linux.vnet.ibm.com --- drivers/cpuidle/cpuidle-ibm-power.c | 39 --- 1 file changed, 36 insertions(+), 3 deletions(-) diff --git a/drivers/cpuidle/cpuidle-ibm-power.c b/drivers/cpuidle/cpuidle-ibm-power.c index 5b92242..f790ea2 100644 --- a/drivers/cpuidle/cpuidle-ibm-power.c +++ b/drivers/cpuidle/cpuidle-ibm-power.c @@ -52,9 +52,10 @@ static int snooze_loop(struct cpuidle_device *dev, struct cpuidle_driver *drv, int index) { - unsigned long in_purr; + unsigned long in_purr = 0; - idle_loop_prolog(in_purr); + if (firmware_has_feature(FW_FEATURE_SPLPAR)) + idle_loop_prolog(in_purr); local_irq_enable(); set_thread_flag(TIF_POLLING_NRFLAG); @@ -68,7 +69,8 @@ static int snooze_loop(struct cpuidle_device *dev, clear_thread_flag(TIF_POLLING_NRFLAG); smp_mb(); - idle_loop_epilog(in_purr); + if (firmware_has_feature(FW_FEATURE_SPLPAR)) + idle_loop_epilog(in_purr); return index; } @@ -132,6 +134,15 @@ static int shared_cede_loop(struct cpuidle_device *dev, 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. */ @@ -165,6 +176,23 @@ static struct cpuidle_state shared_states[] = { .enter = shared_cede_loop }, }; +static struct cpuidle_state powernv_states[] = { + { /* 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 }, +}; + void update_smt_snooze_delay(int cpu, int residency) { struct cpuidle_driver *drv = cpuidle_get_driver(); @@ -258,6 +286,11 @@ static int power_idle_probe(void) cpuidle_state_table = dedicated_states; max_idle_state = ARRAY_SIZE(dedicated_states); } + + } else if (firmware_has_feature(FW_FEATURE_OPALv3)) { + cpuidle_state_table = powernv_states; + max_idle_state = ARRAY_SIZE(powernv_states); + } else return -ENODEV; ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH V7 7/7] powernv/cpuidle: Enable idle powernv cpu to call into the cpuidle framework.
This patch enables idle cpu on the powernv platform 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 | 13 - 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/arch/powerpc/platforms/powernv/setup.c b/arch/powerpc/platforms/powernv/setup.c index e239dcf..42a6ba0 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 @@ -192,6 +193,16 @@ static void __init pnv_setup_machdep_rtas(void) } #endif /* CONFIG_PPC_POWERNV_RTAS */ +void powernv_idle(void) +{ + /* Hook to cpuidle framework if available, else +* call on default platform idle code +*/ + if (cpuidle_idle_call()) { + power7_idle(); + } +} + static int __init pnv_probe(void) { unsigned long root = of_get_flat_dt_root(); @@ -222,7 +233,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] ASoC: fsl_ssi: separately enable and disable TIE/RIE in trigger()
This patch enables Tx-related SIER_FLAGS only when direction is PLAYBACK and does same thing for CAPTURE. Also, after TRIGGER_STOP/PAUSE, it will disable SIER_xFLAGS for symmetric. [ Passed compile-test with mpc85xx_defconfig ] Signed-off-by: Nicolin Chen b42...@freescale.com --- sound/soc/fsl/fsl_ssi.c | 21 + 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c index 35e2773..3797bf0 100644 --- a/sound/soc/fsl/fsl_ssi.c +++ b/sound/soc/fsl/fsl_ssi.c @@ -107,11 +107,14 @@ static inline void write_ssi_mask(u32 __iomem *addr, u32 clear, u32 set) #endif /* SIER bitflag of interrupts to enable */ -#define SIER_FLAGS (CCSR_SSI_SIER_TFRC_EN | CCSR_SSI_SIER_TDMAE | \ +#define SIER_TFLAGS (CCSR_SSI_SIER_TFRC_EN | CCSR_SSI_SIER_TDMAE | \ CCSR_SSI_SIER_TIE | CCSR_SSI_SIER_TUE0_EN | \ - CCSR_SSI_SIER_TUE1_EN | CCSR_SSI_SIER_RFRC_EN | \ - CCSR_SSI_SIER_RDMAE | CCSR_SSI_SIER_RIE | \ - CCSR_SSI_SIER_ROE0_EN | CCSR_SSI_SIER_ROE1_EN) + CCSR_SSI_SIER_TUE1_EN) +#define SIER_RFLAGS (CCSR_SSI_SIER_RFRC_EN | CCSR_SSI_SIER_RDMAE | \ + CCSR_SSI_SIER_RIE | CCSR_SSI_SIER_ROE0_EN | \ + CCSR_SSI_SIER_ROE1_EN) + +#define SIER_FLAGS (SIER_TFLAGS | SIER_RFLAGS) /** * fsl_ssi_private: per-SSI private data @@ -560,12 +563,12 @@ static int fsl_ssi_trigger(struct snd_pcm_substream *substream, int cmd, if (substream-stream == SNDRV_PCM_STREAM_PLAYBACK) { if (ssi_private-use_dma) - sier_bits = SIER_FLAGS; + sier_bits = SIER_TFLAGS; else sier_bits = CCSR_SSI_SIER_TIE | CCSR_SSI_SIER_TFE0_EN; } else { if (ssi_private-use_dma) - sier_bits = SIER_FLAGS; + sier_bits = SIER_RFLAGS; else sier_bits = CCSR_SSI_SIER_RIE | CCSR_SSI_SIER_RFF0_EN; } @@ -579,6 +582,8 @@ static int fsl_ssi_trigger(struct snd_pcm_substream *substream, int cmd, else write_ssi_mask(ssi-scr, 0, CCSR_SSI_SCR_SSIEN | CCSR_SSI_SCR_RE); + + write_ssi_mask(ssi-sier, 0, sier_bits); break; case SNDRV_PCM_TRIGGER_STOP: @@ -591,14 +596,14 @@ static int fsl_ssi_trigger(struct snd_pcm_substream *substream, int cmd, if (!ssi_private-imx_ac97 (read_ssi(ssi-scr) (CCSR_SSI_SCR_TE | CCSR_SSI_SCR_RE)) == 0) write_ssi_mask(ssi-scr, CCSR_SSI_SCR_SSIEN, 0); + + write_ssi_mask(ssi-sier, sier_bits, 0); break; default: return -EINVAL; } - write_ssi(sier_bits, ssi-sier); - return 0; } -- 1.8.4 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 1/5 RFC] pci:msi: add weak function for returning msi region info
In Aperture type of IOMMU (like FSL PAMU), VFIO-iommu system need to know the MSI region to map its window in h/w. This patch just defines the required weak functions only and will be used by followup patches. Signed-off-by: Bharat Bhushan bharat.bhus...@freescale.com --- drivers/pci/msi.c | 22 ++ include/linux/msi.h | 14 ++ 2 files changed, 36 insertions(+), 0 deletions(-) diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c index d5f90d6..2643a29 100644 --- a/drivers/pci/msi.c +++ b/drivers/pci/msi.c @@ -67,6 +67,28 @@ int __weak arch_msi_check_device(struct pci_dev *dev, int nvec, int type) return chip-check_device(chip, dev, nvec, type); } +int __weak arch_msi_get_region_count(void) +{ + return 0; +} + +int __weak arch_msi_get_region(int region_num, struct msi_region *region) +{ + return 0; +} + +int msi_get_region_count(void) +{ + return arch_msi_get_region_count(); +} +EXPORT_SYMBOL(msi_get_region_count); + +int msi_get_region(int region_num, struct msi_region *region) +{ + return arch_msi_get_region(region_num, region); +} +EXPORT_SYMBOL(msi_get_region); + int __weak arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) { struct msi_desc *entry; diff --git a/include/linux/msi.h b/include/linux/msi.h index b17ead8..0deedb4 100644 --- a/include/linux/msi.h +++ b/include/linux/msi.h @@ -51,6 +51,18 @@ struct msi_desc { }; /* + * This structure is used to get + * - physical address + * - size + * of a msi region + */ +struct msi_region { + int region_num; /* MSI region number */ + dma_addr_t addr; /* Address of MSI region */ + size_t size; /* Size of MSI region */ +}; + +/* * The arch hooks to setup up msi irqs. Those functions are * implemented as weak symbols so that they /can/ be overriden by * architecture specific code if needed. @@ -64,6 +76,8 @@ void arch_restore_msi_irqs(struct pci_dev *dev, int irq); void default_teardown_msi_irqs(struct pci_dev *dev); void default_restore_msi_irqs(struct pci_dev *dev, int irq); +int arch_msi_get_region_count(void); +int arch_msi_get_region(int region_num, struct msi_region *region); struct msi_chip { struct module *owner; -- 1.7.0.4 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 4/5 RFC] pci: msi: expose msi region information functions
So by now we have defined all the interfaces for getting the msi region, this patch expose the interface to linux subsystem. These will be used by vfio subsystem for setting up iommu for MSI interrupt of direct assignment devices. Signed-off-by: Bharat Bhushan bharat.bhus...@freescale.com --- include/linux/pci.h | 13 + 1 files changed, 13 insertions(+), 0 deletions(-) diff --git a/include/linux/pci.h b/include/linux/pci.h index da172f9..c587034 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -1142,6 +1142,7 @@ struct msix_entry { u16 entry; /* driver uses to specify entry, OS writes */ }; +struct msi_region; #ifndef CONFIG_PCI_MSI static inline int pci_enable_msi_block(struct pci_dev *dev, unsigned int nvec) @@ -1184,6 +1185,16 @@ static inline int pci_msi_enabled(void) { return 0; } + +static inline int msi_get_region_count(void) +{ + return 0; +} + +static inline int msi_get_region(int region_num, struct msi_region *region) +{ + return 0; +} #else int pci_enable_msi_block(struct pci_dev *dev, unsigned int nvec); int pci_enable_msi_block_auto(struct pci_dev *dev, unsigned int *maxvec); @@ -1196,6 +1207,8 @@ void pci_disable_msix(struct pci_dev *dev); void msi_remove_pci_irq_vectors(struct pci_dev *dev); void pci_restore_msi_state(struct pci_dev *dev); int pci_msi_enabled(void); +int msi_get_region_count(void); +int msi_get_region(int region_num, struct msi_region *region); #endif #ifdef CONFIG_PCIEPORTBUS -- 1.7.0.4 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 2/5 RFC] powerpc: pci: Add arch specific msi region interface
This patch adds the interface to get the msi region information from arch specific code. The machine spicific code is not yet defined. Signed-off-by: Bharat Bhushan bharat.bhus...@freescale.com --- arch/powerpc/include/asm/machdep.h |8 arch/powerpc/kernel/msi.c | 18 ++ 2 files changed, 26 insertions(+), 0 deletions(-) diff --git a/arch/powerpc/include/asm/machdep.h b/arch/powerpc/include/asm/machdep.h index 8b48090..8d1b787 100644 --- a/arch/powerpc/include/asm/machdep.h +++ b/arch/powerpc/include/asm/machdep.h @@ -30,6 +30,7 @@ struct file; struct pci_controller; struct kimage; struct pci_host_bridge; +struct msi_region; struct machdep_calls { char*name; @@ -124,6 +125,13 @@ struct machdep_calls { int (*setup_msi_irqs)(struct pci_dev *dev, int nvec, int type); void(*teardown_msi_irqs)(struct pci_dev *dev); + + /* Returns the number of MSI regions (banks) */ + int (*msi_get_region_count)(void); + + /* Returns the requested region's address and size */ + int (*msi_get_region)(int region_num, + struct msi_region *region); #endif void(*restart)(char *cmd); diff --git a/arch/powerpc/kernel/msi.c b/arch/powerpc/kernel/msi.c index 8bbc12d..1a67787 100644 --- a/arch/powerpc/kernel/msi.c +++ b/arch/powerpc/kernel/msi.c @@ -13,6 +13,24 @@ #include asm/machdep.h +int arch_msi_get_region_count(void) +{ + if (ppc_md.msi_get_region_count) { + pr_debug(msi: Using platform get_region_count routine.\n); + return ppc_md.msi_get_region_count(); + } + return 0; +} + +int arch_msi_get_region(int region_num, struct msi_region *region) +{ + if (ppc_md.msi_get_region) { + pr_debug(msi: Using platform get_region routine.\n); + return ppc_md.msi_get_region(region_num, region); + } + return 0; +} + int arch_msi_check_device(struct pci_dev* dev, int nvec, int type) { if (!ppc_md.setup_msi_irqs || !ppc_md.teardown_msi_irqs) { -- 1.7.0.4 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 3/5 RFC] powerpc: msi: Extend the msi region interface to get info from fsl_msi
The FSL MSI will provide the interface to get: - Number of MSI regions (which is number of MSI banks for powerpc) - Get the region address range: Physical page which have the address/addresses used for generating MSI interrupt and size of the page. These are required to create IOMMU (Freescale PAMU) mapping for devices which are directly assigned using VFIO. Signed-off-by: Bharat Bhushan bharat.bhus...@freescale.com --- arch/powerpc/sysdev/fsl_msi.c | 42 +++- arch/powerpc/sysdev/fsl_msi.h | 11 - 2 files changed, 45 insertions(+), 8 deletions(-) diff --git a/arch/powerpc/sysdev/fsl_msi.c b/arch/powerpc/sysdev/fsl_msi.c index 77efbae..eeebbf0 100644 --- a/arch/powerpc/sysdev/fsl_msi.c +++ b/arch/powerpc/sysdev/fsl_msi.c @@ -109,6 +109,34 @@ static int fsl_msi_init_allocator(struct fsl_msi *msi_data) return 0; } +static int fsl_msi_get_region_count(void) +{ + int count = 0; + struct fsl_msi *msi_data; + + list_for_each_entry(msi_data, msi_head, list) + count++; + + return count; +} + +static int fsl_msi_get_region(int region_num, struct msi_region *region) +{ + struct fsl_msi *msi_data; + + list_for_each_entry(msi_data, msi_head, list) { + if (msi_data-bank_index == region_num) { + region-region_num = msi_data-bank_index; + /* Setting PAGE_SIZE as MSIIR is a 4 byte register */ + region-size = PAGE_SIZE; + region-addr = msi_data-msiir ~(region-size - 1); + return 0; + } + } + + return -ENODEV; +} + static int fsl_msi_check_device(struct pci_dev *pdev, int nvec, int type) { if (type == PCI_CAP_ID_MSIX) @@ -150,7 +178,8 @@ static void fsl_compose_msi_msg(struct pci_dev *pdev, int hwirq, if (reg (len == sizeof(u64))) address = be64_to_cpup(reg); else - address = fsl_pci_immrbar_base(hose) + msi_data-msiir_offset; + address = fsl_pci_immrbar_base(hose) + + (msi_data-msiir 0xf); msg-address_lo = lower_32_bits(address); msg-address_hi = upper_32_bits(address); @@ -393,6 +422,7 @@ static int fsl_of_msi_probe(struct platform_device *dev) const struct fsl_msi_feature *features; int len; u32 offset; + static atomic_t bank_index = ATOMIC_INIT(-1); match = of_match_device(fsl_of_msi_ids, dev-dev); if (!match) @@ -436,18 +466,15 @@ static int fsl_of_msi_probe(struct platform_device *dev) dev-dev.of_node-full_name); goto error_out; } - msi-msiir_offset = - features-msiir_offset + (res.start 0xf); /* * First read the MSIIR/MSIIR1 offset from dts * On failure use the hardcode MSIIR offset */ if (of_address_to_resource(dev-dev.of_node, 1, msiir)) - msi-msiir_offset = features-msiir_offset + - (res.start MSIIR_OFFSET_MASK); + msi-msiir = res.start + features-msiir_offset; else - msi-msiir_offset = msiir.start MSIIR_OFFSET_MASK; + msi-msiir = msiir.start; } msi-feature = features-fsl_pic_ip; @@ -521,6 +548,7 @@ static int fsl_of_msi_probe(struct platform_device *dev) } } + msi-bank_index = atomic_inc_return(bank_index); list_add_tail(msi-list, msi_head); /* The multiple setting ppc_md.setup_msi_irqs will not harm things */ @@ -528,6 +556,8 @@ static int fsl_of_msi_probe(struct platform_device *dev) ppc_md.setup_msi_irqs = fsl_setup_msi_irqs; ppc_md.teardown_msi_irqs = fsl_teardown_msi_irqs; ppc_md.msi_check_device = fsl_msi_check_device; + ppc_md.msi_get_region_count = fsl_msi_get_region_count; + ppc_md.msi_get_region = fsl_msi_get_region; } else if (ppc_md.setup_msi_irqs != fsl_setup_msi_irqs) { dev_err(dev-dev, Different MSI driver already installed!\n); err = -ENODEV; diff --git a/arch/powerpc/sysdev/fsl_msi.h b/arch/powerpc/sysdev/fsl_msi.h index df9aa9f..a2cc5a2 100644 --- a/arch/powerpc/sysdev/fsl_msi.h +++ b/arch/powerpc/sysdev/fsl_msi.h @@ -31,14 +31,21 @@ struct fsl_msi { struct irq_domain *irqhost; unsigned long cascade_irq; - - u32 msiir_offset; /* Offset of MSIIR, relative to start of CCSR */ + phys_addr_t msiir; /* MSIIR Address in CCSR */ u32 ibs_shift; /* Shift of interrupt bit select */ u32 srs_shift; /* Shift of the shared interrupt register select */ void __iomem *msi_regs; u32 feature;
[PATCH 5/5 RFC] vfio: setup iova-base for msi interrupts for vfio assigned device
PAMU (FSL IOMMU) has a concept of primary window and subwindows. Primary window corresponds to the complete guest iova address space (including MSI space), with respect to IOMMU_API this is termed as geometry. IOVA Base of subwindow is determined from the number of subwindows (configurable using iommu API). MSI I/O page must be within the geometry and maximum supported subwindows, so MSI IO-page is setup just after guest memory iova space. This patch is for setting up MSI iova-base for vfio devices assigned in msi subsystem, so that when msi-message will be composed then this configured iova will be used. According to this design vfio will make msi_set_iova() msi-API call to setup iova for a device. MSI will keep track of iova-base of all device under a msi-bank. When composing the MSI address and data this list will be traversed, if device found in the list then device used by vfio and its iova-base will be taken from here otherwise iova-base will be taken as before. This is a draft patch to describe the interface to setup iova in MSI (what Alex Williamson proposed earlier on related patchset). Currently I have bundled all changes in one patch to take initial review comment on design. I will divide this in multiple logical patches once this design is accepted. Signed-off-by: Bharat Bhushan bharat.bhus...@freescale.com --- arch/powerpc/include/asm/machdep.h |2 + arch/powerpc/kernel/msi.c | 10 ++ arch/powerpc/sysdev/fsl_msi.c | 64 arch/powerpc/sysdev/fsl_msi.h | 10 - drivers/pci/msi.c | 12 +++ include/linux/pci.h|8 6 files changed, 104 insertions(+), 2 deletions(-) diff --git a/arch/powerpc/include/asm/machdep.h b/arch/powerpc/include/asm/machdep.h index 8d1b787..e87b806 100644 --- a/arch/powerpc/include/asm/machdep.h +++ b/arch/powerpc/include/asm/machdep.h @@ -132,6 +132,8 @@ struct machdep_calls { /* Returns the requested region's address and size */ int (*msi_get_region)(int region_num, struct msi_region *region); + int (*msi_set_iova)(struct pci_dev *pdev, int region_num, + dma_addr_t iova, bool set); #endif void(*restart)(char *cmd); diff --git a/arch/powerpc/kernel/msi.c b/arch/powerpc/kernel/msi.c index 1a67787..e2bd555 100644 --- a/arch/powerpc/kernel/msi.c +++ b/arch/powerpc/kernel/msi.c @@ -13,6 +13,16 @@ #include asm/machdep.h +int arch_msi_set_iova(struct pci_dev *pdev, int region_num, + dma_addr_t iova, bool set) +{ + if (ppc_md.msi_set_iova) { + pr_debug(msi: Using platform get_region_count routine.\n); + return ppc_md.msi_set_iova(pdev, region_num, iova, set); + } + return 0; +} + int arch_msi_get_region_count(void) { if (ppc_md.msi_get_region_count) { diff --git a/arch/powerpc/sysdev/fsl_msi.c b/arch/powerpc/sysdev/fsl_msi.c index eeebbf0..ad22d74 100644 --- a/arch/powerpc/sysdev/fsl_msi.c +++ b/arch/powerpc/sysdev/fsl_msi.c @@ -137,6 +137,46 @@ static int fsl_msi_get_region(int region_num, struct msi_region *region) return -ENODEV; } +static int fsl_msi_set_iova(struct pci_dev *pdev, int region_num, + dma_addr_t iova, bool set) +{ + struct fsl_msi *msi_data; + struct fsl_msi_device *device; + + list_for_each_entry(msi_data, msi_head, list) { + if (msi_data-bank_index != region_num) + continue; + mutex_lock(msi_data-lock); + if (set) { + list_for_each_entry(device, msi_data-device_list, list) { + if (device-dev == pdev) { + device-iova = iova; + mutex_unlock(msi_data-lock); + return 0; + } + } + + device = kzalloc(sizeof(struct fsl_msi_device), GFP_KERNEL); + device-dev = pdev; + device-iova = iova; + list_add_tail(device-list, msi_data-device_list); + } else { + list_for_each_entry(device, msi_data-device_list, list) { + if (device-dev == pdev) { + list_del(device-list); + kfree(device); + mutex_unlock(msi_data-lock); + return 0; + } + } + } + + mutex_unlock(msi_data-lock); + break; + } + return 0; +} + static int fsl_msi_check_device(struct pci_dev *pdev, int nvec, int type) { if
[PATCH 0/5 RFC] vfio/pci: add interface to for MSI support with FSL PAMU
From: Bharat Bhushan bharat.bhus...@freescale.com PAMU (FSL IOMMU) has a concept of primary window and subwindows. Primary window corresponds to the complete guest iova address space (including MSI space), with respect to IOMMU_API this is termed as geometry. IOVA Base of subwindow is determined from the number of subwindows (configurable using iommu API). MSI I/O page must be within the geometry and maximum supported subwindows, so MSI IO-page is setup just after guest memory iova space. So first four patches are for defining the interface to get: - Number of MSI regions (which is number of MSI banks for powerpc) - MSI-region address range: Physical page which have the address/addresses used for generating MSI interrupt and size of the page. Last Patch is for setting up MSI iova-base for vfio devices assigned in msi subsystem, so that when msi-message will be composed then this configured iova will be used. Earlier we were using iommu interface for getting the configured iova which was not currect and Alex Williamson suggeested this type of interface. Bharat Bhushan (5): pci:msi: add weak function for returning msi region info powerpc: pci: Add arch specific msi region interface powerpc: msi: Extend the msi region interface to get info from fsl_msi pci: msi: expose msi region information functions vfio: setup iova-base for msi interrupts for vfio assigned device arch/powerpc/include/asm/machdep.h | 10 arch/powerpc/kernel/msi.c | 28 ++ arch/powerpc/sysdev/fsl_msi.c | 106 ++-- arch/powerpc/sysdev/fsl_msi.h | 19 ++- drivers/pci/msi.c | 34 include/linux/msi.h| 14 + include/linux/pci.h| 21 +++ 7 files changed, 223 insertions(+), 9 deletions(-) ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH] ASoC: fsl_ssi: separately enable and disable TIE/RIE in trigger()
Nicolin Chen wrote: This patch enables Tx-related SIER_FLAGS only when direction is PLAYBACK and does same thing for CAPTURE. Also, after TRIGGER_STOP/PAUSE, it will disable SIER_xFLAGS for symmetric. I'm okay with this patch in principle, but why bother? The sysfs entry is going to display all interrupts anyway, and so the result will be the same. ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH] ASoC: fsl_ssi: separately enable and disable TIE/RIE in trigger()
On Tue, Oct 29, 2013 at 06:59:44AM -0500, Timur Tabi wrote: Nicolin Chen wrote: This patch enables Tx-related SIER_FLAGS only when direction is PLAYBACK and does same thing for CAPTURE. Also, after TRIGGER_STOP/PAUSE, it will disable SIER_xFLAGS for symmetric. I'm okay with this patch in principle, but why bother? The sysfs entry is going to display all interrupts anyway, and so the result will be the same. Well, actually I just wanted to clear T/RDMAE to disable DMA request, but it seems to be much easier to do it like this based on current code and disabling unused interrupts should be better right? :) Thank you, Nicolin Chen ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH] ASoC: fsl_ssi: separately enable and disable TIE/RIE in trigger()
Nicolin Chen wrote: Well, actually I just wanted to clear T/RDMAE to disable DMA request, but it seems to be much easier to do it like this based on current code and disabling unused interrupts should be better right?:) It's not better if it complicates the code and has no real impact. The code has been running fine for years the way it is. Unless you can show me that it actually makes a difference, I will have to NACK this patch. ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH] ASoC: fsl_ssi: separately enable and disable TIE/RIE in trigger()
On Tue, Oct 29, 2013 at 07:18:21AM -0500, Timur Tabi wrote: Nicolin Chen wrote: Well, actually I just wanted to clear T/RDMAE to disable DMA request, but it seems to be much easier to do it like this based on current code and disabling unused interrupts should be better right?:) It's not better if it complicates the code and has no real impact. The code has been running fine for years the way it is. Unless you can show me that it actually makes a difference, I will have to NACK this patch. The DMA request might be remaining high if not disabling it. This would cause SDMA re-check this request, while it has no BD existing. For the other interrupts, if you don't like it, I can drop it. Just modification to the driver might not be less complicated. Thank you, Nicolin Chen ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 0/3] Add dual-fifo mode support of i.MX ssi
Changelog v1: * SSI can reduce hardware overrun/underrun possibility when using dual * fifo mode. To support this mode, we need to first update sdma sciprt * list, and then enable dual fifo BIT in SSI driver, and last update DT * bindings of i.MX series. * * ! This series of patches has a direct dependency between them. When * ! applying them, we need to apply in one single branch. Otherwise, * ! it would break currect branches. Nicolin Chen (3): dma: imx-sdma: Add ssi dual fifo script support ASoC: fsl_ssi: Add dual fifo mode support ARM: dts: imx: use dual-fifo sdma script for ssi .../devicetree/bindings/dma/fsl-imx-sdma.txt | 1 + arch/arm/boot/dts/imx51.dtsi | 4 ++-- arch/arm/boot/dts/imx53.dtsi | 4 ++-- arch/arm/boot/dts/imx6qdl.dtsi | 12 +-- arch/arm/boot/dts/imx6sl.dtsi | 12 +-- drivers/dma/imx-sdma.c | 6 +- include/linux/platform_data/dma-imx-sdma.h | 2 ++ include/linux/platform_data/dma-imx.h | 1 + sound/soc/fsl/fsl_ssi.c| 24 +- 9 files changed, 48 insertions(+), 18 deletions(-) -- 1.8.4 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 1/3] dma: imx-sdma: Add ssi dual fifo script support
There's a script for SSI missing in current sdma script list. Thus add it. This script would allow SSI use its dual fifo mode to transimit/receive data without occasional hardware underrun/overrun. This patch also fixed a counting error for total number of scripts. Signed-off-by: Nicolin Chen b42...@freescale.com --- Documentation/devicetree/bindings/dma/fsl-imx-sdma.txt | 1 + drivers/dma/imx-sdma.c | 6 +- include/linux/platform_data/dma-imx-sdma.h | 2 ++ include/linux/platform_data/dma-imx.h | 1 + 4 files changed, 9 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/dma/fsl-imx-sdma.txt b/Documentation/devicetree/bindings/dma/fsl-imx-sdma.txt index 4fa814d..3b933c5 100644 --- a/Documentation/devicetree/bindings/dma/fsl-imx-sdma.txt +++ b/Documentation/devicetree/bindings/dma/fsl-imx-sdma.txt @@ -42,6 +42,7 @@ The full ID of peripheral types can be found below. 19 IPU Memory 20 ASRC 21 ESAI + 22 SSI Dual FIFO The third cell specifies the transfer priority as below. diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c index fc43603..695871f 100644 --- a/drivers/dma/imx-sdma.c +++ b/drivers/dma/imx-sdma.c @@ -724,6 +724,10 @@ static void sdma_get_pc(struct sdma_channel *sdmac, per_2_emi = sdma-script_addrs-app_2_mcu_addr; emi_2_per = sdma-script_addrs-mcu_2_app_addr; break; + case IMX_DMATYPE_SSI_DUAL: + per_2_emi = sdma-script_addrs-ssish_2_mcu_addr; + emi_2_per = sdma-script_addrs-mcu_2_ssish_addr; + break; case IMX_DMATYPE_SSI_SP: case IMX_DMATYPE_MMC: case IMX_DMATYPE_SDHC: @@ -1237,7 +1241,7 @@ static void sdma_issue_pending(struct dma_chan *chan) sdma_enable_channel(sdma, sdmac-channel); } -#define SDMA_SCRIPT_ADDRS_ARRAY_SIZE_V134 +#define SDMA_SCRIPT_ADDRS_ARRAY_SIZE_V137 static void sdma_add_scripts(struct sdma_engine *sdma, const struct sdma_script_start_addrs *addr) diff --git a/include/linux/platform_data/dma-imx-sdma.h b/include/linux/platform_data/dma-imx-sdma.h index 3a39428..19cfa9a 100644 --- a/include/linux/platform_data/dma-imx-sdma.h +++ b/include/linux/platform_data/dma-imx-sdma.h @@ -43,6 +43,8 @@ struct sdma_script_start_addrs { s32 dptc_dvfs_addr; s32 utra_addr; s32 ram_code_start_addr; + s32 mcu_2_ssish_addr; + s32 ssish_2_mcu_addr; }; /** diff --git a/include/linux/platform_data/dma-imx.h b/include/linux/platform_data/dma-imx.h index beac6b8..bcbc6c3 100644 --- a/include/linux/platform_data/dma-imx.h +++ b/include/linux/platform_data/dma-imx.h @@ -39,6 +39,7 @@ enum sdma_peripheral_type { IMX_DMATYPE_IPU_MEMORY, /* IPU Memory */ IMX_DMATYPE_ASRC, /* ASRC */ IMX_DMATYPE_ESAI, /* ESAI */ + IMX_DMATYPE_SSI_DUAL, /* SSI Dual FIFO */ }; enum imx_dma_prio { -- 1.8.4 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 2/3] ASoC: fsl_ssi: Add dual fifo mode support
By enabling dual fifo mode, it would allow SSI enter a better performance to transimit/receive data without occasional hardware underrun/overrun. [ Passed compile-test with mpc85xx_defconfig ] Signed-off-by: Nicolin Chen b42...@freescale.com --- sound/soc/fsl/fsl_ssi.c | 24 +++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c index 3797bf0..7ad01ce 100644 --- a/sound/soc/fsl/fsl_ssi.c +++ b/sound/soc/fsl/fsl_ssi.c @@ -146,6 +146,7 @@ struct fsl_ssi_private { bool ssi_on_imx; bool imx_ac97; bool use_dma; + bool use_dual_fifo; struct clk *clk; struct snd_dmaengine_dai_dma_data dma_params_tx; struct snd_dmaengine_dai_dma_data dma_params_rx; @@ -416,6 +417,16 @@ static int fsl_ssi_setup(struct fsl_ssi_private *ssi_private) write_ssi(CCSR_SSI_SOR_WAIT(3), ssi-sor); } + if (ssi_private-use_dual_fifo) { + write_ssi_mask(ssi-srcr, 0, CCSR_SSI_SRCR_RFEN1); + write_ssi_mask(ssi-stcr, 0, CCSR_SSI_STCR_TFEN1); + write_ssi_mask(ssi-scr, 0, CCSR_SSI_SCR_TCH_EN); + } else { + write_ssi_mask(ssi-srcr, CCSR_SSI_SRCR_RFEN1, 0); + write_ssi_mask(ssi-stcr, CCSR_SSI_STCR_TFEN1, 0); + write_ssi_mask(ssi-scr, CCSR_SSI_SCR_TCH_EN, 0); + } + return 0; } @@ -952,7 +963,7 @@ static int fsl_ssi_probe(struct platform_device *pdev) ssi_private-fifo_depth = 8; if (of_device_is_compatible(pdev-dev.of_node, fsl,imx21-ssi)) { - u32 dma_events[2]; + u32 dma_events[2], dmas[4]; ssi_private-ssi_on_imx = true; ssi_private-clk = devm_clk_get(pdev-dev, NULL); @@ -1006,6 +1017,17 @@ static int fsl_ssi_probe(struct platform_device *pdev) dma_events[0], shared ? IMX_DMATYPE_SSI_SP : IMX_DMATYPE_SSI); imx_pcm_dma_params_init_data(ssi_private-filter_data_rx, dma_events[1], shared ? IMX_DMATYPE_SSI_SP : IMX_DMATYPE_SSI); + if (!of_property_read_u32_array(pdev-dev.of_node, dmas, dmas, 4) +dmas[2] == IMX_DMATYPE_SSI_DUAL) { + ssi_private-use_dual_fifo = true; + /* When using dual fifo mode, we need to keep watermark +* as even numbers due to dma script limitation. +*/ + ssi_private-dma_params_tx.maxburst /= 2; + ssi_private-dma_params_tx.maxburst *= 2; + ssi_private-dma_params_rx.maxburst /= 2; + ssi_private-dma_params_rx.maxburst *= 2; + } } else if (ssi_private-use_dma) { /* The 'name' should not have any slashes in it. */ ret = devm_request_irq(pdev-dev, ssi_private-irq, -- 1.8.4 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH 3/3] ARM: dts: imx: use dual-fifo sdma script for ssi
Use dual-fifo sdma scripts instead of shared scripts for ssi on i.MX series. Signed-off-by: Nicolin Chen b42...@freescale.com --- arch/arm/boot/dts/imx51.dtsi | 4 ++-- arch/arm/boot/dts/imx53.dtsi | 4 ++-- arch/arm/boot/dts/imx6qdl.dtsi | 12 ++-- arch/arm/boot/dts/imx6sl.dtsi | 12 ++-- 4 files changed, 16 insertions(+), 16 deletions(-) diff --git a/arch/arm/boot/dts/imx51.dtsi b/arch/arm/boot/dts/imx51.dtsi index 54cee65..1a71eac 100644 --- a/arch/arm/boot/dts/imx51.dtsi +++ b/arch/arm/boot/dts/imx51.dtsi @@ -154,8 +154,8 @@ reg = 0x70014000 0x4000; interrupts = 30; clocks = clks 49; - dmas = sdma 24 1 0, - sdma 25 1 0; + dmas = sdma 24 22 0, + sdma 25 22 0; dma-names = rx, tx; fsl,fifo-depth = 15; fsl,ssi-dma-events = 25 24 23 22; /* TX0 RX0 TX1 RX1 */ diff --git a/arch/arm/boot/dts/imx53.dtsi b/arch/arm/boot/dts/imx53.dtsi index 4307e80..7208fde 100644 --- a/arch/arm/boot/dts/imx53.dtsi +++ b/arch/arm/boot/dts/imx53.dtsi @@ -153,8 +153,8 @@ reg = 0x50014000 0x4000; interrupts = 30; clocks = clks 49; - dmas = sdma 24 1 0, - sdma 25 1 0; + dmas = sdma 24 22 0, + sdma 25 22 0; dma-names = rx, tx; fsl,fifo-depth = 15; fsl,ssi-dma-events = 25 24 23 22; /* TX0 RX0 TX1 RX1 */ diff --git a/arch/arm/boot/dts/imx6qdl.dtsi b/arch/arm/boot/dts/imx6qdl.dtsi index 57e9c38..6e096ca 100644 --- a/arch/arm/boot/dts/imx6qdl.dtsi +++ b/arch/arm/boot/dts/imx6qdl.dtsi @@ -223,8 +223,8 @@ reg = 0x02028000 0x4000; interrupts = 0 46 0x04; clocks = clks 178; - dmas = sdma 37 1 0, - sdma 38 1 0; + dmas = sdma 37 22 0, + sdma 38 22 0; dma-names = rx, tx; fsl,fifo-depth = 15; fsl,ssi-dma-events = 38 37; @@ -236,8 +236,8 @@ reg = 0x0202c000 0x4000; interrupts = 0 47 0x04; clocks = clks 179; - dmas = sdma 41 1 0, - sdma 42 1 0; + dmas = sdma 41 22 0, + sdma 42 22 0; dma-names = rx, tx; fsl,fifo-depth = 15; fsl,ssi-dma-events = 42 41; @@ -249,8 +249,8 @@ reg = 0x0203 0x4000; interrupts = 0 48 0x04; clocks = clks 180; - dmas = sdma 45 1 0, - sdma 46 1 0; + dmas = sdma 45 22 0, + sdma 46 22 0; dma-names = rx, tx; fsl,fifo-depth = 15; fsl,ssi-dma-events = 46 45; diff --git a/arch/arm/boot/dts/imx6sl.dtsi b/arch/arm/boot/dts/imx6sl.dtsi index c46651e..b32ba99 100644 --- a/arch/arm/boot/dts/imx6sl.dtsi +++ b/arch/arm/boot/dts/imx6sl.dtsi @@ -195,8 +195,8 @@ reg = 0x02028000 0x4000; interrupts = 0 46 0x04; clocks = clks IMX6SL_CLK_SSI1; - dmas = sdma 37 1 0, - sdma 38 1 0; + dmas = sdma 37 22 0, + sdma 38 22 0; dma-names = rx, tx; fsl,fifo-depth = 15; status = disabled; @@ -207,8 +207,8 @@
Re: [PATCH] ASoC: fsl_ssi: separately enable and disable TIE/RIE in trigger()
Nicolin Chen wrote: The DMA request might be remaining high if not disabling it. Might? Are you just guessing? This would cause SDMA re-check this request, while it has no BD existing. For the other interrupts, if you don't like it, I can drop it. Just modification to the driver might not be less complicated. I'm only talking about this particular patch. ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH 2/3] ASoC: fsl_ssi: Add dual fifo mode support
Nicolin Chen wrote: By enabling dual fifo mode, it would allow SSI enter a better performance to transimit/receive data without occasional hardware underrun/overrun. Have you measured any real performance gain with this patch? I considered adding dual-FIFO support when I originally wrote this driver, but it didn't appear to have any real benefit, but it used twice as many DMA channels. I'm concerned that this is another patch that just enables a useless feature. ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH 2/3] ASoC: fsl_ssi: Add dual fifo mode support
Without dual fifo support, handware underrun would occasionally occur and then two audio channels would physically swap. This could be easily reproduced in low bus frequency situation, while it would be better if we enable dual fifo. Sent by Android device. Timur Tabi ti...@tabi.org wrote: Nicolin Chen wrote: By enabling dual fifo mode, it would allow SSI enter a better performance to transimit/receive data without occasional hardware underrun/overrun. Have you measured any real performance gain with this patch? I considered adding dual-FIFO support when I originally wrote this driver, but it didn't appear to have any real benefit, but it used twice as many DMA channels. I'm concerned that this is another patch that just enables a useless feature. ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH] ASoC: fsl_ssi: separately enable and disable TIE/RIE in trigger()
I mean there is a possibility. I'm sorry if my patch is kinda annoying and it really bother you, sir. I also want to make things better. If you really don't like it, we can drop it. It's all your call. And thank you for reviewing. Sent by Android device. Timur Tabi ti...@tabi.org wrote: Nicolin Chen wrote: The DMA request might be remaining high if not disabling it. Might? Are you just guessing? This would cause SDMA re-check this request, while it has no BD existing. For the other interrupts, if you don't like it, I can drop it. Just modification to the driver might not be less complicated. I'm only talking about this particular patch. ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH 2/3] ASoC: fsl_ssi: Add dual fifo mode support
Chen Guangyu-B42378 wrote: Without dual fifo support, handware underrun would occasionally occur and then two audio channels would physically swap. This could be easily reproduced in low bus frequency situation, while it would be better if we enable dual fifo. Ok. ACK. ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH 2/3] ASoC: fsl_ssi: Add dual fifo mode support
Thank you, sir. And sorry for taking your time. Sent by Android device. Timur Tabi ti...@tabi.org wrote: Chen Guangyu-B42378 wrote: Without dual fifo support, handware underrun would occasionally occur and then two audio channels would physically swap. This could be easily reproduced in low bus frequency situation, while it would be better if we enable dual fifo. Ok. ACK. ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH] ASoC: fsl_ssi: separately enable and disable TIE/RIE in trigger()
Chen Guangyu-B42378 wrote: I mean there is a possibility. I'm sorry if my patch is kinda annoying and it really bother you, sir. I also want to make things better. It does not bother me. I'm glad people are working on my driver. I just want to make sure that my driver does not get bloated. If you really don't like it, we can drop it. It's all your call. I think this patch should be dropped, because I don't see any real reason for it. ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH] ASoC: fsl_ssi: separately enable and disable TIE/RIE in trigger()
As you wish, sir. Sent by Android device. Timur Tabi ti...@tabi.org wrote: Chen Guangyu-B42378 wrote: I mean there is a possibility. I'm sorry if my patch is kinda annoying and it really bother you, sir. I also want to make things better. It does not bother me. I'm glad people are working on my driver. I just want to make sure that my driver does not get bloated. If you really don't like it, we can drop it. It's all your call. I think this patch should be dropped, because I don't see any real reason for it. ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH 1/3] sched: Fix nohz_kick_needed to consider the nr_busy of the parent domain's group
On Tue, Oct 29, 2013 at 09:00:52AM +0530, Preeti U Murthy wrote: Oh nice, that gets rid of the multiple atomics, and it nicely splits this nohz logic into per topology groups -- now if only we could split the rest too :-) I am sorry, I don't get you here. By the 'rest', do you refer to nohz_kick_needed() as below? Or am I missing something? Nah, the rest of the NOHZ infrastructure. Currently its global state; there were some patches a few years ago that attempted to make that per-node state, but that work stalled due to people switching jobs. + sd = highest_flag_domain(cpu, SD_ASYM_PACKING); + + if (sd (cpumask_first_and(nohz.idle_cpus_mask, +sched_domain_span(sd)) cpu)) + goto need_kick_unlock; + rcu_read_unlock(); return 0; This again is a bit sad; most archs will not have SD_ASYM_PACKING set at all; this means that they all will do a complete (and pointless) sched domain tree walk here. There will not be a 'complete' sched domain tree walk right? The iteration will break at the first level of the sched domain for those archs which do not have SD_ASYM_PACKING set at all. Ah indeed; I think I got confused due to me modifying highest_flag_domain() earlier to assume a flag is carried from the lowest domain upwards. But it is true that doing a sched domain tree walk regularly is a bad idea, might as well update the domain with SD_ASYM_PACKING flag set once and query this domain when required. I will send out the patch with sd_asym domain introduced rather than the above. Thanks ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH 1/3] dma: imx-sdma: Add ssi dual fifo script support
On Tue, Oct 29, 2013 at 08:33:15PM +0800, Nicolin Chen wrote: There's a script for SSI missing in current sdma script list. Thus add it. This script would allow SSI use its dual fifo mode to transimit/receive data without occasional hardware underrun/overrun. This patch also fixed a counting error for total number of scripts. Look at drivers/dma/imx-sdma.c: /** * struct sdma_firmware_header - Layout of the firmware image * * @magic SDMA * @version_major increased whenever layout of struct * sdma_script_start_addrs *changes. Can you image why this firmware has a version field? Right, it's because it encodes the layout of struct sdma_script_start_addrs. As the comment clearly states you have to *increase this field* when you add scripts. Obviously you missed that, as the firmware on lkml posted recently shows: : 414d4453 0001 0001 001c SDMA Still '1' 0010: 0026 00b4 067a 0282 ...z... 0020: 0030: 0040: 1a6a j... 0050: 02eb 18bb 0408 0060: 03c0 0070: 02ab 037b {... 0080: 044c 046e L...n... 0090: 1800 00a0: 1800 1862 1a16 b... ^ new script addresses introduced -#define SDMA_SCRIPT_ADDRS_ARRAY_SIZE_V1 34 +#define SDMA_SCRIPT_ADDRS_ARRAY_SIZE_V1 37 And no, this is not a bug. It's your firmware header that is buggy. What you need is: #define SDMA_SCRIPT_ADDRS_ARRAY_SIZE_V2 37 You (you as a company, not you as a person) knew that it was me who created this firmware format. So it was absolutely unnecessary to create an incompatible firmware instead of dropping me a short note. Please add a version check to the driver as necessary and provide a proper firmware. Sascha -- Pengutronix e.K. | | Industrial Linux Solutions | http://www.pengutronix.de/ | Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0| Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917- | ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: PCIE device errors after linux kernel upgrade
Nope , same situation, can't find whats wrong :( -- View this message in context: http://linuxppc.10917.n7.nabble.com/Re-PCIE-device-errors-after-linux-kernel-upgrade-tp74563p77605.html Sent from the linuxppc-dev mailing list archive at Nabble.com. ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH 1/3] dma: imx-sdma: Add ssi dual fifo script support
On Oct 29, 2013, at 7:33 AM, Nicolin Chen wrote: There's a script for SSI missing in current sdma script list. Thus add it. This script would allow SSI use its dual fifo mode to transimit/receive data without occasional hardware underrun/overrun. This patch also fixed a counting error for total number of scripts. Signed-off-by: Nicolin Chen b42...@freescale.com --- Documentation/devicetree/bindings/dma/fsl-imx-sdma.txt | 1 + drivers/dma/imx-sdma.c | 6 +- include/linux/platform_data/dma-imx-sdma.h | 2 ++ include/linux/platform_data/dma-imx.h | 1 + 4 files changed, 9 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/dma/fsl-imx-sdma.txt b/Documentation/devicetree/bindings/dma/fsl-imx-sdma.txt index 4fa814d..3b933c5 100644 --- a/Documentation/devicetree/bindings/dma/fsl-imx-sdma.txt +++ b/Documentation/devicetree/bindings/dma/fsl-imx-sdma.txt @@ -42,6 +42,7 @@ The full ID of peripheral types can be found below. 19 IPU Memory 20 ASRC 21 ESAI + 22 SSI Dual FIFO The third cell specifies the transfer priority as below. For the DT-Binding portion: Acked-by: Kumar Gala ga...@codeaurora.org - k -- Employee of Qualcomm Innovation Center, Inc. Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: perf events ring buffer memory barrier on powerpc
On 10/29, Peter Zijlstra wrote: On Tue, Oct 29, 2013 at 11:30:57AM +0100, Peter Zijlstra wrote: @@ -154,9 +175,11 @@ int perf_output_begin(struct perf_output * Userspace could choose to issue a mb() before updating the * tail pointer. So that all reads will be completed before the * write is issued. +* +* See perf_output_put_handle(). */ tail = ACCESS_ONCE(rb-user_page-data_tail); - smp_rmb(); + smp_mb(); offset = head = local_read(rb-head); head += size; if (unlikely(!perf_output_space(rb, tail, offset, head))) That said; it would be very nice to be able to remove this barrier. This is in every event write path :/ Yes.. And I'm afraid very much that I simply confused you. Perhaps Victor is right and we do not need this mb(). So I am waiting for the end of this story too. And btw I do not understand why we need it (or smp_rmb) right after ACCESS_ONCE(data_tail). Oleg. ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: perf events ring buffer memory barrier on powerpc
Peter Zijlstra pet...@infradead.org wrote: On Tue, Oct 29, 2013 at 11:21:31AM +0100, Peter Zijlstra wrote: On Mon, Oct 28, 2013 at 10:58:58PM +0200, Victor Kaplansky wrote: Oleg Nesterov o...@redhat.com wrote on 10/28/2013 10:17:35 PM: mb(); // : do we really need it? I think yes. Oh, it is hard to argue with feelings. Also, it is easy to be on conservative side and put the barrier here just in case. I'll make it a full mb for now and too am curious to see the end of this discussion explaining things ;-) That is, I've now got this queued: Can we also CC sta...@kernel.org? This has been around for a while. Mikey --- Subject: perf: Fix perf ring buffer memory ordering From: Peter Zijlstra pet...@infradead.org Date: Mon Oct 28 13:55:29 CET 2013 The PPC64 people noticed a missing memory barrier and crufty old comments in the perf ring buffer code. So update all the comments and add the missing barrier. When the architecture implements local_t using atomic_long_t there will be double barriers issued; but short of introducing more conditional barrier primitives this is the best we can do. Cc: Mathieu Desnoyers mathieu.desnoy...@polymtl.ca Cc: mich...@ellerman.id.au Cc: Paul McKenney paul...@linux.vnet.ibm.com Cc: Michael Neuling mi...@neuling.org Cc: Frederic Weisbecker fweis...@gmail.com Cc: an...@samba.org Cc: b...@kernel.crashing.org Reported-by: Victor Kaplansky vict...@il.ibm.com Tested-by: Victor Kaplansky vict...@il.ibm.com Signed-off-by: Peter Zijlstra pet...@infradead.org Link: http://lkml.kernel.org/r/20131025173749.gg19...@laptop.lan --- include/uapi/linux/perf_event.h | 12 +++- kernel/events/ring_buffer.c | 31 +++ 2 files changed, 34 insertions(+), 9 deletions(-) Index: linux-2.6/include/uapi/linux/perf_event.h === --- linux-2.6.orig/include/uapi/linux/perf_event.h +++ linux-2.6/include/uapi/linux/perf_event.h @@ -479,13 +479,15 @@ struct perf_event_mmap_page { /* * Control data for the mmap() data buffer. * - * User-space reading the @data_head value should issue an rmb(), on - * SMP capable platforms, after reading this value -- see - * perf_event_wakeup(). + * User-space reading the @data_head value should issue an smp_rmb(), + * after reading this value. * * When the mapping is PROT_WRITE the @data_tail value should be - * written by userspace to reflect the last read data. In this case - * the kernel will not over-write unread data. + * written by userspace to reflect the last read data, after issueing + * an smp_mb() to separate the data read from the -data_tail store. + * In this case the kernel will not over-write unread data. + * + * See perf_output_put_handle() for the data ordering. */ __u64 data_head; /* head in the data section */ __u64 data_tail; /* user-space written tail */ Index: linux-2.6/kernel/events/ring_buffer.c === --- linux-2.6.orig/kernel/events/ring_buffer.c +++ linux-2.6/kernel/events/ring_buffer.c @@ -87,10 +87,31 @@ static void perf_output_put_handle(struc goto out; /* - * Publish the known good head. Rely on the full barrier implied - * by atomic_dec_and_test() order the rb-head read and this - * write. + * Since the mmap() consumer (userspace) can run on a different CPU: + * + * kernel user + * + * READ -data_tail READ -data_head + * smp_mb() (A) smp_rmb() (C) + * WRITE $dataREAD $data + * smp_wmb() (B) smp_mb()(D) + * STORE -data_head WRITE -data_tail + * + * Where A pairs with D, and B pairs with C. + * + * I don't think A needs to be a full barrier because we won't in fact + * write data until we see the store from userspace. So we simply don't + * issue the data WRITE until we observe it. Be conservative for now. + * + * OTOH, D needs to be a full barrier since it separates the data READ + * from the tail WRITE. + * + * For B a WMB is sufficient since it separates two WRITEs, and for C + * an RMB is sufficient since it separates two READs. + * + * See perf_output_begin(). */ + smp_wmb(); rb-user_page-data_head = head; /* @@ -154,9 +175,11 @@ int perf_output_begin(struct perf_output * Userspace could choose to issue a mb() before updating the * tail pointer. So that all reads will be completed before the * write is issued. +
Re: [PATCH] ADB_PMU_LED_IDE selects LEDS_TRIGGER_IDE_DISK which has unmet direct dependencies
On Mon, 2013-10-28 at 04:26 -0700, Christian Kujau wrote: Hi, for quite some time the following is printed (twice) after doing make oldconfig: [...] scripts/kconfig/conf --oldconfig Kconfig warning: (ADB_PMU_LED_IDE) selects LEDS_TRIGGER_IDE_DISK which has unmet direct dependencies (NEW_LEDS IDE_GD_ATA LEDS_TRIGGERS) warning: (ADB_PMU_LED_IDE) selects LEDS_TRIGGER_IDE_DISK which has unmet direct dependencies (NEW_LEDS IDE_GD_ATA LEDS_TRIGGERS) I never got around to look into this. But I remember that (when I still had CONFIG_IDE selected, because CONFIG_PATA_MACIO was not working for my PowerBook G5), I always had ADB_PMU_LED_IDE selected, so this option was carried over to my current config. When doing make menuconfig with this generated config I could see that all 3 necessary options are selected: Support for PMU based PowerMacs CONFIG_ADB_PMU Support for the Power/iBook front LED CONFIG_ADB_PMU_LED Use front LED as IDE LED by default CONFIG_ADB_PMU_LED_IDE And CONFIG_ADB_PMU_LED_IDE selects CONFIG_LEDS_TRIGGER_IDE_DISK, which in turn depends on CONFIG_IDE_GD_ATA - but in make menuconfig I could still *unselect* CONFIG_IDE (since I'm using CONFIG_PATA_MACIO) and the 3 options above were still available. I guess make oldconfig noticed that and hence printed the warning above. The following patch causes ADB_PMU_LED to depend on IDE_GD_ATA, so that the options above are only available when IDE_GD_ATA is actually selected and thus eliminates the warning. Signed-off-by: Christian Kujau li...@nerdbynature.de diff --git a/drivers/macintosh/Kconfig b/drivers/macintosh/Kconfig index 696238b..f30ac9d 100644 --- a/drivers/macintosh/Kconfig +++ b/drivers/macintosh/Kconfig @@ -90,6 +90,7 @@ config ADB_PMU config ADB_PMU_LED bool Support for the Power/iBook front LED depends on ADB_PMU + depends on IDE_GD_ATA select NEW_LEDS select LEDS_CLASS help You probably want to do that to the ADB_PMU_LED_IDE entry not the ADB_PMU_LED one which doesn't have a dependency and isn't the one selecting LEDS_TRIGGER_IDE_DISK :-) Cheers, Ben. Being a kbuild n00b, I don't know if this is the correct approach though. After looking through the archives I found that this has been reported by Geert back in 2012 already: https://lkml.org/lkml/2012/3/13/556 Thanks, Christian. ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH 1/3] powerpc: Enable emulate_step In Little Endian Mode
On Fri, 2013-10-18 at 14:40 -0500, Tom Musta wrote: This patch modifies the endian chicken switch in the single step emulation code (emulate_step()). The old (big endian) code bailed early if a load or store instruction was to be emulated in little endian mode. The new code modifies the check and only bails in a cross-endian situation (LE mode in a kernel compiled for BE and vice verse). I get a malformed patch error, looks like it got wrapped. Cheers, Ben. Signed-off-by: Tom Musta tmu...@gmail.com --- arch/powerpc/lib/sstep.c | 12 +--- 1 files changed, 9 insertions(+), 3 deletions(-) diff --git a/arch/powerpc/lib/sstep.c b/arch/powerpc/lib/sstep.c index b1faa15..5e0d0e9 100644 --- a/arch/powerpc/lib/sstep.c +++ b/arch/powerpc/lib/sstep.c @@ -1222,12 +1222,18 @@ int __kprobes emulate_step(struct pt_regs *regs, unsigned int instr) } /* - * Following cases are for loads and stores, so bail out - * if we're in little-endian mode. + * Following cases are for loads and stores and this + * implementation does not support cross-endian. So + * bail out if this is the case. */ +#ifdef __BIG_ENDIAN__ if (regs-msr MSR_LE) return 0; - +#endif +#ifdef __LITTLE_ENDIAN__ + if (!regs-msr MSR_LE) + return 0; +#endif /* * Save register RA in case it's an update form load or store * and the access faults. ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH] powerpc: platforms: powernv: include asm/prom.h in rng.c
Need include the related header file, or can not pass compiling with allmodconfig. The related error (with allmodconfig): CC arch/powerpc/platforms/powernv/rng.o arch/powerpc/platforms/powernv/rng.c: In function ‘rng_init_per_cpu’: arch/powerpc/platforms/powernv/rng.c:64:2: error: implicit declaration of function ‘of_get_ibm_chip_id’ [-Werror=implicit-function-declaration] arch/powerpc/platforms/powernv/rng.c: In function ‘rng_create’: arch/powerpc/platforms/powernv/rng.c:85:2: error: implicit declaration of function ‘of_iomap’ [-Werror=implicit-function-declaration] arch/powerpc/platforms/powernv/rng.c:85:12: warning: assignment makes pointer from integer without a cast [enabled by default] Signed-off-by: Chen Gang gang.c...@asianux.com --- arch/powerpc/platforms/powernv/rng.c |1 + 1 files changed, 1 insertions(+), 0 deletions(-) diff --git a/arch/powerpc/platforms/powernv/rng.c b/arch/powerpc/platforms/powernv/rng.c index 02db7d7..b3e1ebc 100644 --- a/arch/powerpc/platforms/powernv/rng.c +++ b/arch/powerpc/platforms/powernv/rng.c @@ -16,6 +16,7 @@ #include asm/archrandom.h #include asm/io.h #include asm/machdep.h +#include asm/prom.h struct powernv_rng { -- 1.7.7.6 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH V2 0/2] sched: Cleanups,fixes in nohz_kick_needed()
Changes from V1:https://lkml.org/lkml/2013/10/21/248 1. Swapped the order of PATCH1 and PATCH2 in V1 so as to not mess with the nr_busy_cpus parameter computation during asymmetric balancing, while fixing it. 2. nohz_busy_cpus parameter is to be updated and queried at only one level of the sched domain-sd_busy where it is relevant. 3. Introduce sd_asym to represent the sched domain where asymmetric load balancing has to be done. --- Preeti U Murthy (1): sched: Remove un-necessary iteration over sched domains to update nr_busy_cpus Vaidyanathan Srinivasan (1): sched: Fix asymmetric scheduling for POWER7 kernel/sched/core.c |6 ++ kernel/sched/fair.c | 38 -- kernel/sched/sched.h |2 ++ 3 files changed, 28 insertions(+), 18 deletions(-) ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH V2 2/2] sched: Remove un-necessary iteration over sched domains to update nr_busy_cpus
nr_busy_cpus parameter is used by nohz_kick_needed() to find out the number of busy cpus in a sched domain which has SD_SHARE_PKG_RESOURCES flag set. Therefore instead of updating nr_busy_cpus at every level of sched domain, since it is irrelevant, we can update this parameter only at the parent domain of the sd which has this flag set. Introduce a per-cpu parameter sd_busy which represents this parent domain. In nohz_kick_needed() we directly query the nr_busy_cpus parameter associated with the groups of sd_busy. By associating sd_busy with the highest domain which has SD_SHARE_PKG_RESOURCES flag set, we cover all lower level domains which could have this flag set and trigger nohz_idle_balancing if any of the levels have more than one busy cpu. sd_busy is irrelevant for asymmetric load balancing. While we are at it, we might as well change the nohz_idle parameter to be updated at the sd_busy domain level alone and not the base domain level of a CPU. This will unify the concept of busy cpus at just one level of sched domain where it is currently used. Signed-off-by: Preeti U Murthypre...@linux.vnet.ibm.com --- kernel/sched/core.c |6 ++ kernel/sched/fair.c | 38 -- kernel/sched/sched.h |2 ++ 3 files changed, 28 insertions(+), 18 deletions(-) diff --git a/kernel/sched/core.c b/kernel/sched/core.c index c06b8d3..e6a6244 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c @@ -5271,6 +5271,8 @@ DEFINE_PER_CPU(struct sched_domain *, sd_llc); DEFINE_PER_CPU(int, sd_llc_size); DEFINE_PER_CPU(int, sd_llc_id); DEFINE_PER_CPU(struct sched_domain *, sd_numa); +DEFINE_PER_CPU(struct sched_domain *, sd_busy); +DEFINE_PER_CPU(struct sched_domain *, sd_asym); static void update_top_cache_domain(int cpu) { @@ -5282,6 +5284,7 @@ static void update_top_cache_domain(int cpu) if (sd) { id = cpumask_first(sched_domain_span(sd)); size = cpumask_weight(sched_domain_span(sd)); + rcu_assign_pointer(per_cpu(sd_busy, cpu), sd-parent); } rcu_assign_pointer(per_cpu(sd_llc, cpu), sd); @@ -5290,6 +5293,9 @@ static void update_top_cache_domain(int cpu) sd = lowest_flag_domain(cpu, SD_NUMA); rcu_assign_pointer(per_cpu(sd_numa, cpu), sd); + + sd = highest_flag_domain(cpu, SD_ASYM_PACKING); + rcu_assign_pointer(per_cpu(sd_asym, cpu), sd); } /* diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index e9c9549..8602b2c 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -6515,16 +6515,16 @@ static inline void nohz_balance_exit_idle(int cpu) static inline void set_cpu_sd_state_busy(void) { struct sched_domain *sd; + int cpu = smp_processor_id(); rcu_read_lock(); - sd = rcu_dereference_check_sched_domain(this_rq()-sd); + sd = rcu_dereference(per_cpu(sd_busy, cpu)); if (!sd || !sd-nohz_idle) goto unlock; sd-nohz_idle = 0; - for (; sd; sd = sd-parent) - atomic_inc(sd-groups-sgp-nr_busy_cpus); + atomic_inc(sd-groups-sgp-nr_busy_cpus); unlock: rcu_read_unlock(); } @@ -6532,16 +6532,16 @@ unlock: void set_cpu_sd_state_idle(void) { struct sched_domain *sd; + int cpu = smp_processor_id(); rcu_read_lock(); - sd = rcu_dereference_check_sched_domain(this_rq()-sd); + sd = rcu_dereference(per_cpu(sd_busy, cpu)); if (!sd || sd-nohz_idle) goto unlock; sd-nohz_idle = 1; - for (; sd; sd = sd-parent) - atomic_dec(sd-groups-sgp-nr_busy_cpus); + atomic_dec(sd-groups-sgp-nr_busy_cpus); unlock: rcu_read_unlock(); } @@ -6748,6 +6748,8 @@ static inline int nohz_kick_needed(struct rq *rq, int cpu) { unsigned long now = jiffies; struct sched_domain *sd; + struct sched_group_power *sgp; + int nr_busy; if (unlikely(idle_cpu(cpu))) return 0; @@ -6773,22 +6775,22 @@ static inline int nohz_kick_needed(struct rq *rq, int cpu) goto need_kick; rcu_read_lock(); - for_each_domain(cpu, sd) { - struct sched_group *sg = sd-groups; - struct sched_group_power *sgp = sg-sgp; - int nr_busy = atomic_read(sgp-nr_busy_cpus); + sd = rcu_dereference(per_cpu(sd_busy, cpu)); - if (sd-flags SD_SHARE_PKG_RESOURCES nr_busy 1) - goto need_kick_unlock; + if (sd) { + sgp = sd-groups-sgp; + nr_busy = atomic_read(sgp-nr_busy_cpus); - if (sd-flags SD_ASYM_PACKING -(cpumask_first_and(nohz.idle_cpus_mask, - sched_domain_span(sd)) cpu)) + if (nr_busy 1) goto need_kick_unlock; - - if (!(sd-flags (SD_SHARE_PKG_RESOURCES | SD_ASYM_PACKING))) -
Re: [PATCH V2 2/2] sched: Remove un-necessary iteration over sched domains to update nr_busy_cpus
The changelog has missed mentioning the introduction of sd_asym per_cpu sched domain. Apologies for this. The patch with the changelog including mention of sd_asym is pasted below. Regards Preeti U Murthy --- sched: Remove un-necessary iteration over sched domains to update nr_busy_cpus From: Preeti U Murthy pre...@linux.vnet.ibm.com nr_busy_cpus parameter is used by nohz_kick_needed() to find out the number of busy cpus in a sched domain which has SD_SHARE_PKG_RESOURCES flag set. Therefore instead of updating nr_busy_cpus at every level of sched domain, since it is irrelevant, we can update this parameter only at the parent domain of the sd which has this flag set. Introduce a per-cpu parameter sd_busy which represents this parent domain. In nohz_kick_needed() we directly query the nr_busy_cpus parameter associated with the groups of sd_busy. By associating sd_busy with the highest domain which has SD_SHARE_PKG_RESOURCES flag set, we cover all lower level domains which could have this flag set and trigger nohz_idle_balancing if any of the levels have more than one busy cpu. sd_busy is irrelevant for asymmetric load balancing. However sd_asym has been introduced to represent the highest sched domain which has SD_ASYM_PACKING flag set so that it can be queried directly when required. While we are at it, we might as well change the nohz_idle parameter to be updated at the sd_busy domain level alone and not the base domain level of a CPU. This will unify the concept of busy cpus at just one level of sched domain where it is currently used. Signed-off-by: Preeti U Murthypre...@linux.vnet.ibm.com --- kernel/sched/core.c |6 ++ kernel/sched/fair.c | 38 -- kernel/sched/sched.h |2 ++ 3 files changed, 28 insertions(+), 18 deletions(-) diff --git a/kernel/sched/core.c b/kernel/sched/core.c index c06b8d3..e6a6244 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c @@ -5271,6 +5271,8 @@ DEFINE_PER_CPU(struct sched_domain *, sd_llc); DEFINE_PER_CPU(int, sd_llc_size); DEFINE_PER_CPU(int, sd_llc_id); DEFINE_PER_CPU(struct sched_domain *, sd_numa); +DEFINE_PER_CPU(struct sched_domain *, sd_busy); +DEFINE_PER_CPU(struct sched_domain *, sd_asym); static void update_top_cache_domain(int cpu) { @@ -5282,6 +5284,7 @@ static void update_top_cache_domain(int cpu) if (sd) { id = cpumask_first(sched_domain_span(sd)); size = cpumask_weight(sched_domain_span(sd)); + rcu_assign_pointer(per_cpu(sd_busy, cpu), sd-parent); } rcu_assign_pointer(per_cpu(sd_llc, cpu), sd); @@ -5290,6 +5293,9 @@ static void update_top_cache_domain(int cpu) sd = lowest_flag_domain(cpu, SD_NUMA); rcu_assign_pointer(per_cpu(sd_numa, cpu), sd); + + sd = highest_flag_domain(cpu, SD_ASYM_PACKING); + rcu_assign_pointer(per_cpu(sd_asym, cpu), sd); } /* diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index e9c9549..8602b2c 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -6515,16 +6515,16 @@ static inline void nohz_balance_exit_idle(int cpu) static inline void set_cpu_sd_state_busy(void) { struct sched_domain *sd; + int cpu = smp_processor_id(); rcu_read_lock(); - sd = rcu_dereference_check_sched_domain(this_rq()-sd); + sd = rcu_dereference(per_cpu(sd_busy, cpu)); if (!sd || !sd-nohz_idle) goto unlock; sd-nohz_idle = 0; - for (; sd; sd = sd-parent) - atomic_inc(sd-groups-sgp-nr_busy_cpus); + atomic_inc(sd-groups-sgp-nr_busy_cpus); unlock: rcu_read_unlock(); } @@ -6532,16 +6532,16 @@ unlock: void set_cpu_sd_state_idle(void) { struct sched_domain *sd; + int cpu = smp_processor_id(); rcu_read_lock(); - sd = rcu_dereference_check_sched_domain(this_rq()-sd); + sd = rcu_dereference(per_cpu(sd_busy, cpu)); if (!sd || sd-nohz_idle) goto unlock; sd-nohz_idle = 1; - for (; sd; sd = sd-parent) - atomic_dec(sd-groups-sgp-nr_busy_cpus); + atomic_dec(sd-groups-sgp-nr_busy_cpus); unlock: rcu_read_unlock(); } @@ -6748,6 +6748,8 @@ static inline int nohz_kick_needed(struct rq *rq, int cpu) { unsigned long now = jiffies; struct sched_domain *sd; + struct sched_group_power *sgp; + int nr_busy; if (unlikely(idle_cpu(cpu))) return 0; @@ -6773,22 +6775,22 @@ static inline int nohz_kick_needed(struct rq *rq, int cpu) goto need_kick; rcu_read_lock(); - for_each_domain(cpu, sd) { - struct sched_group *sg = sd-groups; - struct sched_group_power *sgp = sg-sgp; - int nr_busy = atomic_read(sgp-nr_busy_cpus); + sd = rcu_dereference(per_cpu(sd_busy, cpu)); - if (sd-flags SD_SHARE_PKG_RESOURCES nr_busy 1) -
Re: [PATCH] ADB_PMU_LED_IDE selects LEDS_TRIGGER_IDE_DISK which has unmet direct dependencies
On Wed, 30 Oct 2013 at 10:13, Benjamin Herrenschmidt wrote: You probably want to do that to the ADB_PMU_LED_IDE entry not the ADB_PMU_LED one which doesn't have a dependency and isn't the one selecting LEDS_TRIGGER_IDE_DISK :-) Right you are, sorry for the mixup. Let me try again: Signed-off-by: Christian Kujau li...@nerdbynature.de diff --git a/drivers/macintosh/Kconfig b/drivers/macintosh/Kconfig index 696238b..d26a312 100644 --- a/drivers/macintosh/Kconfig +++ b/drivers/macintosh/Kconfig @@ -103,6 +103,7 @@ config ADB_PMU_LED_IDE bool Use front LED as IDE LED by default depends on ADB_PMU_LED depends on LEDS_CLASS + depends on IDE_GD_ATA select LEDS_TRIGGERS select LEDS_TRIGGER_IDE_DISK help C. -- BOFH excuse #378: Operators killed by year 2000 bug bite. ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH 1/3] dma: imx-sdma: Add ssi dual fifo script support
Hi Sascha, On Tue, Oct 29, 2013 at 02:51:43PM +0100, Sascha Hauer wrote: Look at drivers/dma/imx-sdma.c: /** * struct sdma_firmware_header - Layout of the firmware image * * @magic SDMA * @version_major increased whenever layout of struct * sdma_script_start_addrs * changes. Can you image why this firmware has a version field? Right, it's because it encodes the layout of struct sdma_script_start_addrs. As the comment clearly states you have to *increase this field* when you add scripts. Obviously you missed that, as the firmware on lkml posted recently shows: : 414d4453 0001 0001 001c SDMA Still '1' 0010: 0026 00b4 067a 0282 ...z... 0020: 0030: 0040: 1a6a j... 0050: 02eb 18bb 0408 0060: 03c0 0070: 02ab 037b {... 0080: 044c 046e L...n... 0090: 1800 00a0: 1800 1862 1a16 b... ^ new script addresses introduced -#define SDMA_SCRIPT_ADDRS_ARRAY_SIZE_V134 +#define SDMA_SCRIPT_ADDRS_ARRAY_SIZE_V137 And no, this is not a bug. It's your firmware header that is buggy. I wasn't aware that the problem is far more complicated than I thought. And thank you for telling me all this. What you need is: #define SDMA_SCRIPT_ADDRS_ARRAY_SIZE_V2 37 You (you as a company, not you as a person) knew that it was me who created this firmware format. So it was absolutely unnecessary to create an incompatible firmware instead of dropping me a short note. Please add a version check to the driver as necessary and provide a proper firmware. Just currently it's not easy for me to create a new proper firmware, and I's been told that besides this version number, it also lacks a decent license info. So may I just refine this patch as you suggested to add a version check and add those new scripts first? Thank you, Nicolin Chen Sascha -- Pengutronix e.K. | | Industrial Linux Solutions | http://www.pengutronix.de/ | Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0| Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917- | ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
RE: [PATCH v9 01/13] KVM: PPC: POWERNV: move iommu_add_device earlier
Hi Alex, Looks like this patch is not picked by anyone, Are you going to pick this patch? My vfio/iommu patches have dependency on this patch (this is already tested by me). Thanks -Bharat -Original Message- From: Linuxppc-dev [mailto:linuxppc-dev- bounces+bharat.bhushan=freescale@lists.ozlabs.org] On Behalf Of Alexey Kardashevskiy Sent: Wednesday, August 28, 2013 2:08 PM To: linuxppc-dev@lists.ozlabs.org Cc: k...@vger.kernel.org; Gleb Natapov; Alexey Kardashevskiy; Alexander Graf; kvm-...@vger.kernel.org; linux-ker...@vger.kernel.org; linux...@kvack.org; Paul Mackerras; Paolo Bonzini; David Gibson Subject: [PATCH v9 01/13] KVM: PPC: POWERNV: move iommu_add_device earlier The current implementation of IOMMU on sPAPR does not use iommu_ops and therefore does not call IOMMU API's bus_set_iommu() which 1) sets iommu_ops for a bus 2) registers a bus notifier Instead, PCI devices are added to IOMMU groups from subsys_initcall_sync(tce_iommu_init) which does basically the same thing without using iommu_ops callbacks. However Freescale PAMU driver (https://lkml.org/lkml/2013/7/1/158) implements iommu_ops and when tce_iommu_init is called, every PCI device is already added to some group so there is a conflict. This patch does 2 things: 1. removes the loop in which PCI devices were added to groups and adds explicit iommu_add_device() calls to add devices as soon as they get the iommu_table pointer assigned to them. 2. moves a bus notifier to powernv code in order to avoid conflict with the notifier from Freescale driver. iommu_add_device() and iommu_del_device() are public now. Signed-off-by: Alexey Kardashevskiy a...@ozlabs.ru --- Changes: v8: * added the check for iommu_group!=NULL before removing device from a group as suggested by Wei Yang weiy...@linux.vnet.ibm.com v2: * added a helper - set_iommu_table_base_and_group - which does set_iommu_table_base() and iommu_add_device() --- arch/powerpc/include/asm/iommu.h| 9 +++ arch/powerpc/kernel/iommu.c | 41 +++-- arch/powerpc/platforms/powernv/pci-ioda.c | 8 +++--- arch/powerpc/platforms/powernv/pci-p5ioc2.c | 2 +- arch/powerpc/platforms/powernv/pci.c| 33 ++- arch/powerpc/platforms/pseries/iommu.c | 8 +++--- 6 files changed, 55 insertions(+), 46 deletions(-) diff --git a/arch/powerpc/include/asm/iommu.h b/arch/powerpc/include/asm/iommu.h index c34656a..19ad77f 100644 --- a/arch/powerpc/include/asm/iommu.h +++ b/arch/powerpc/include/asm/iommu.h @@ -103,6 +103,15 @@ extern struct iommu_table *iommu_init_table(struct iommu_table * tbl, int nid); extern void iommu_register_group(struct iommu_table *tbl, int pci_domain_number, unsigned long pe_num); +extern int iommu_add_device(struct device *dev); extern void +iommu_del_device(struct device *dev); + +static inline void set_iommu_table_base_and_group(struct device *dev, + void *base) +{ + set_iommu_table_base(dev, base); + iommu_add_device(dev); +} extern int iommu_map_sg(struct device *dev, struct iommu_table *tbl, struct scatterlist *sglist, int nelems, diff --git a/arch/powerpc/kernel/iommu.c b/arch/powerpc/kernel/iommu.c index b20ff17..15f8ca8 100644 --- a/arch/powerpc/kernel/iommu.c +++ b/arch/powerpc/kernel/iommu.c @@ -1105,7 +1105,7 @@ void iommu_release_ownership(struct iommu_table *tbl) } EXPORT_SYMBOL_GPL(iommu_release_ownership); -static int iommu_add_device(struct device *dev) +int iommu_add_device(struct device *dev) { struct iommu_table *tbl; int ret = 0; @@ -1134,46 +1134,13 @@ static int iommu_add_device(struct device *dev) return ret; } +EXPORT_SYMBOL_GPL(iommu_add_device); -static void iommu_del_device(struct device *dev) +void iommu_del_device(struct device *dev) { iommu_group_remove_device(dev); } - -static int iommu_bus_notifier(struct notifier_block *nb, - unsigned long action, void *data) -{ - struct device *dev = data; - - switch (action) { - case BUS_NOTIFY_ADD_DEVICE: - return iommu_add_device(dev); - case BUS_NOTIFY_DEL_DEVICE: - iommu_del_device(dev); - return 0; - default: - return 0; - } -} - -static struct notifier_block tce_iommu_bus_nb = { - .notifier_call = iommu_bus_notifier, -}; - -static int __init tce_iommu_init(void) -{ - struct pci_dev *pdev = NULL; - - BUILD_BUG_ON(PAGE_SIZE IOMMU_PAGE_SIZE); - - for_each_pci_dev(pdev) - iommu_add_device(pdev-dev); - - bus_register_notifier(pci_bus_type, tce_iommu_bus_nb); - return 0; -} - -subsys_initcall_sync(tce_iommu_init); +EXPORT_SYMBOL_GPL(iommu_del_device);