Re: [git pull] Please pull powerpc.git merge branch

2014-01-15 Thread Linus Torvalds
On Wed, Jan 15, 2014 at 12:01 PM, Benjamin Herrenschmidt
b...@kernel.crashing.org wrote:

 My original intend was to put it in powerpc-next and then shoot it to
 stable, but it got a tad annoying (due to churn it needs to be applied
 at least on rc4 or later while my next is at rc1 and clean that way), so
 I put it in the merge branch.

Quite frankly, I'll prefer to not merge it now, and then 3.13 will get
it from stable, when it does things like this.

Partly because it fixes a power-only bug, but potentially changes
non-power behavior. If it was all in arch/powerpc, I wouldn't mind.

   Linus
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH V5 0/8] cpuidle/ppc: Enable deep idle states on PowerNV

2014-01-15 Thread Preeti U Murthy
On PowerPC, when CPUs enter certain deep idle states, the local timers stop
and the time base could go out of sync with the rest of the cores in the system.

This patchset adds support to wake up CPUs in such idle states by
broadcasting IPIs to them at their next timer events using the tick broadcast
framework in the Linux kernel. We refer to these IPIs as the tick
broadcast IPIs in this patchset.

However the tick broadcast framework as it exists today makes use of an external
clock device to wakeup CPUs in such idle states. But not all implementations of
PowerPC provides such an external clock device.

Hence Patch[6/8]:
[time/cpuidle: Support in tick broadcast framework for archs without external
clock device] adds support in the tick broadcast framework for such
use cases by queuing a hrtimer on one of the CPUs which is meant to handle the 
wakeup
of CPUs in deep idle states.
This patch was posted separately at: https://lkml.org/lkml/2013/12/12/687.

Patches 1-3 adds support in powerpc to hook onto the tick broadcast framework.

The patchset also includes support for resyncing of time base with the rest of 
the
cores in the system and context management for fast sleep. PATCH[4/8] and
PATCH[5/8] address these issues.

With the required support for deep idle states thus in place, the
patchset adds Fast-Sleep idle state into cpuidle (Patches 7 and 8). 
Fast-Sleep
is a deep idle state on Power8 in which the above mentioned challenges
exist. Fast-Sleep can yield us significantly more power
savings than the idle states that we have in cpuidle so far.

This patchset is based on mainline commit-id:8ae516aa8b8161254d3,  and the
cpuidle driver for powernv posted by Deepthi Dharwar:
https://lkml.org/lkml/2014/1/14/172


Changes in V5:
-
The primary change in this version is in Patch[6/8].
As per the discussions in V4 posting of this patchset, it was decided to
refine handling the wakeup of CPUs in fast-sleep by doing the following:

1. In V4, a polling mechanism was used by the CPU handling broadcast to
find out the time of next wakeup of the CPUs in deep idle states. V5 avoids
polling by a way described under PATCH[6/8] in this patchset.

2. The mechanism of broadcast handling of CPUs in deep idle in the absence of an
external wakeup device should be generic and not arch specific code. Hence in 
this
version this functionality has been integrated into the tick broadcast 
framework in
the kernel unlike before where it was handled in powerpc specific code.

3. It was suggested that the broadcast cpu can be the time keeping cpu
itself. However this has challenges of its own:

 a. The time keeping cpu need not exist when all cpus are idle. Hence there
are phases in time when time keeping cpu is absent. But for the use case that
this patchset is trying to address we rely on the presence of a broadcast cpu
all the time.

 b. The nomination and un-assignment of the time keeping cpu is not protected
by a lock today and need not be as well since such is its use case in the
kernel. However we would need locks if we double up the time keeping cpu as the
broadcast cpu.

Hence the broadcast cpu is independent of the time-keeping cpu. However 
PATCH[6/8]
proposes a simpler solution to pick a broadcast cpu in this version.



Changes in V4:
-
https://lkml.org/lkml/2013/11/29/97

1. Add Fast Sleep CPU idle state on PowerNV.

2. Add the required context management for Fast Sleep and the call to OPAL
to synchronize time base after wakeup from fast sleep.

4. Add parsing of CPU idle states from the device tree to populate the
cpuidle
state table.

5. Rename ambiguous functions in the code around waking up of CPUs from fast
sleep.

6. Fixed a bug in re-programming of the hrtimer that is queued to wakeup the
CPUs in fast sleep and modified Changelogs.

7. Added the ARCH_HAS_TICK_BROADCAST option. This signifies that we have a
arch specific function to perform broadcast.


Changes in V3:
-
http://thread.gmane.org/gmane.linux.power-management.general/38113

1. Fix the way in which a broadcast ipi is handled on the idling cpus. Timer
handling on a broadcast ipi is being done now without missing out any timer
stats generation.

2. Fix a bug in the programming of the hrtimer meant to do broadcast. Program
it to trigger at the earlier of a broadcast period, and the next wakeup
event. By introducing the broadcast period as the maximum period after
which the broadcast hrtimer can fire, we ensure that we do not miss
wakeups in corner cases.

3. On hotplug of a broadcast cpu, trigger the hrtimer meant to do broadcast
to fire immediately on the new broadcast cpu. This will ensure we do not miss
doing a broadcast pending in the nearest future.

4. Change the type of allocation from GFP_KERNEL to GFP_NOWAIT while
initializing bc_hrtimer since we are in an atomic context and cannot sleep.

5. Use the broadcast ipi to wakeup the newly nominated broadcast cpu on
hotplug of the old instead of 

[PATCH V5 1/8] powerpc: Free up the slot of PPC_MSG_CALL_FUNC_SINGLE IPI message

2014-01-15 Thread Preeti U Murthy
From: Srivatsa S. Bhat srivatsa.b...@linux.vnet.ibm.com

The IPI handlers for both PPC_MSG_CALL_FUNC and PPC_MSG_CALL_FUNC_SINGLE map
to a common implementation - generic_smp_call_function_single_interrupt(). So,
we can consolidate them and save one of the IPI message slots, (which are
precious on powerpc, since only 4 of those slots are available).

So, implement the functionality of PPC_MSG_CALL_FUNC_SINGLE using
PPC_MSG_CALL_FUNC itself and release its IPI message slot, so that it can be
used for something else in the future, if desired.

Signed-off-by: Srivatsa S. Bhat srivatsa.b...@linux.vnet.ibm.com
Signed-off-by: Preeti U. Murthy pre...@linux.vnet.ibm.com
Acked-by: Geoff Levand ge...@infradead.org [For the PS3 part]
---

 arch/powerpc/include/asm/smp.h  |2 +-
 arch/powerpc/kernel/smp.c   |   12 +---
 arch/powerpc/platforms/cell/interrupt.c |2 +-
 arch/powerpc/platforms/ps3/smp.c|2 +-
 4 files changed, 8 insertions(+), 10 deletions(-)

diff --git a/arch/powerpc/include/asm/smp.h b/arch/powerpc/include/asm/smp.h
index 084e080..9f7356b 100644
--- a/arch/powerpc/include/asm/smp.h
+++ b/arch/powerpc/include/asm/smp.h
@@ -120,7 +120,7 @@ extern int cpu_to_core_id(int cpu);
  * in /proc/interrupts will be wrong!!! --Troy */
 #define PPC_MSG_CALL_FUNCTION   0
 #define PPC_MSG_RESCHEDULE  1
-#define PPC_MSG_CALL_FUNC_SINGLE   2
+#define PPC_MSG_UNUSED 2
 #define PPC_MSG_DEBUGGER_BREAK  3
 
 /* for irq controllers that have dedicated ipis per message (4) */
diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c
index a3b64f3..c2bd8d6 100644
--- a/arch/powerpc/kernel/smp.c
+++ b/arch/powerpc/kernel/smp.c
@@ -145,9 +145,9 @@ static irqreturn_t reschedule_action(int irq, void *data)
return IRQ_HANDLED;
 }
 
-static irqreturn_t call_function_single_action(int irq, void *data)
+static irqreturn_t unused_action(int irq, void *data)
 {
-   generic_smp_call_function_single_interrupt();
+   /* This slot is unused and hence available for use, if needed */
return IRQ_HANDLED;
 }
 
@@ -168,14 +168,14 @@ static irqreturn_t debug_ipi_action(int irq, void *data)
 static irq_handler_t smp_ipi_action[] = {
[PPC_MSG_CALL_FUNCTION] =  call_function_action,
[PPC_MSG_RESCHEDULE] = reschedule_action,
-   [PPC_MSG_CALL_FUNC_SINGLE] = call_function_single_action,
+   [PPC_MSG_UNUSED] = unused_action,
[PPC_MSG_DEBUGGER_BREAK] = debug_ipi_action,
 };
 
 const char *smp_ipi_name[] = {
[PPC_MSG_CALL_FUNCTION] =  ipi call function,
[PPC_MSG_RESCHEDULE] = ipi reschedule,
-   [PPC_MSG_CALL_FUNC_SINGLE] = ipi call function single,
+   [PPC_MSG_UNUSED] = ipi unused,
[PPC_MSG_DEBUGGER_BREAK] = ipi debugger,
 };
 
@@ -251,8 +251,6 @@ irqreturn_t smp_ipi_demux(void)
generic_smp_call_function_interrupt();
if (all  IPI_MESSAGE(PPC_MSG_RESCHEDULE))
scheduler_ipi();
-   if (all  IPI_MESSAGE(PPC_MSG_CALL_FUNC_SINGLE))
-   generic_smp_call_function_single_interrupt();
if (all  IPI_MESSAGE(PPC_MSG_DEBUGGER_BREAK))
debug_ipi_action(0, NULL);
} while (info-messages);
@@ -280,7 +278,7 @@ EXPORT_SYMBOL_GPL(smp_send_reschedule);
 
 void arch_send_call_function_single_ipi(int cpu)
 {
-   do_message_pass(cpu, PPC_MSG_CALL_FUNC_SINGLE);
+   do_message_pass(cpu, PPC_MSG_CALL_FUNCTION);
 }
 
 void arch_send_call_function_ipi_mask(const struct cpumask *mask)
diff --git a/arch/powerpc/platforms/cell/interrupt.c 
b/arch/powerpc/platforms/cell/interrupt.c
index 2d42f3b..adf3726 100644
--- a/arch/powerpc/platforms/cell/interrupt.c
+++ b/arch/powerpc/platforms/cell/interrupt.c
@@ -215,7 +215,7 @@ void iic_request_IPIs(void)
 {
iic_request_ipi(PPC_MSG_CALL_FUNCTION);
iic_request_ipi(PPC_MSG_RESCHEDULE);
-   iic_request_ipi(PPC_MSG_CALL_FUNC_SINGLE);
+   iic_request_ipi(PPC_MSG_UNUSED);
iic_request_ipi(PPC_MSG_DEBUGGER_BREAK);
 }
 
diff --git a/arch/powerpc/platforms/ps3/smp.c b/arch/powerpc/platforms/ps3/smp.c
index 4b35166..00d1a7c 100644
--- a/arch/powerpc/platforms/ps3/smp.c
+++ b/arch/powerpc/platforms/ps3/smp.c
@@ -76,7 +76,7 @@ static int __init ps3_smp_probe(void)
 
BUILD_BUG_ON(PPC_MSG_CALL_FUNCTION!= 0);
BUILD_BUG_ON(PPC_MSG_RESCHEDULE   != 1);
-   BUILD_BUG_ON(PPC_MSG_CALL_FUNC_SINGLE != 2);
+   BUILD_BUG_ON(PPC_MSG_UNUSED   != 2);
BUILD_BUG_ON(PPC_MSG_DEBUGGER_BREAK   != 3);
 
for (i = 0; i  MSG_COUNT; i++) {

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH V5 2/8] powerpc: Implement tick broadcast IPI as a fixed IPI message

2014-01-15 Thread Preeti U Murthy
From: Srivatsa S. Bhat srivatsa.b...@linux.vnet.ibm.com

For scalability and performance reasons, we want the tick broadcast IPIs
to be handled as efficiently as possible. Fixed IPI messages
are one of the most efficient mechanisms available - they are faster than
the smp_call_function mechanism because the IPI handlers are fixed and hence
they don't involve costly operations such as adding IPI handlers to the target
CPU's function queue, acquiring locks for synchronization etc.

Luckily we have an unused IPI message slot, so use that to implement
tick broadcast IPIs efficiently.

Signed-off-by: Srivatsa S. Bhat srivatsa.b...@linux.vnet.ibm.com
[Functions renamed to tick_broadcast* and Changelog modified by
 Preeti U. Murthypre...@linux.vnet.ibm.com]
Signed-off-by: Preeti U. Murthy pre...@linux.vnet.ibm.com
Acked-by: Geoff Levand ge...@infradead.org [For the PS3 part]
---

 arch/powerpc/include/asm/smp.h  |2 +-
 arch/powerpc/include/asm/time.h |1 +
 arch/powerpc/kernel/smp.c   |   19 +++
 arch/powerpc/kernel/time.c  |5 +
 arch/powerpc/platforms/cell/interrupt.c |2 +-
 arch/powerpc/platforms/ps3/smp.c|2 +-
 6 files changed, 24 insertions(+), 7 deletions(-)

diff --git a/arch/powerpc/include/asm/smp.h b/arch/powerpc/include/asm/smp.h
index 9f7356b..ff51046 100644
--- a/arch/powerpc/include/asm/smp.h
+++ b/arch/powerpc/include/asm/smp.h
@@ -120,7 +120,7 @@ extern int cpu_to_core_id(int cpu);
  * in /proc/interrupts will be wrong!!! --Troy */
 #define PPC_MSG_CALL_FUNCTION   0
 #define PPC_MSG_RESCHEDULE  1
-#define PPC_MSG_UNUSED 2
+#define PPC_MSG_TICK_BROADCAST 2
 #define PPC_MSG_DEBUGGER_BREAK  3
 
 /* for irq controllers that have dedicated ipis per message (4) */
diff --git a/arch/powerpc/include/asm/time.h b/arch/powerpc/include/asm/time.h
index c1f2676..1d428e6 100644
--- a/arch/powerpc/include/asm/time.h
+++ b/arch/powerpc/include/asm/time.h
@@ -28,6 +28,7 @@ extern struct clock_event_device decrementer_clockevent;
 struct rtc_time;
 extern void to_tm(int tim, struct rtc_time * tm);
 extern void GregorianDay(struct rtc_time *tm);
+extern void tick_broadcast_ipi_handler(void);
 
 extern void generic_calibrate_decr(void);
 
diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c
index c2bd8d6..c77c6d7 100644
--- a/arch/powerpc/kernel/smp.c
+++ b/arch/powerpc/kernel/smp.c
@@ -35,6 +35,7 @@
 #include asm/ptrace.h
 #include linux/atomic.h
 #include asm/irq.h
+#include asm/hw_irq.h
 #include asm/page.h
 #include asm/pgtable.h
 #include asm/prom.h
@@ -145,9 +146,9 @@ static irqreturn_t reschedule_action(int irq, void *data)
return IRQ_HANDLED;
 }
 
-static irqreturn_t unused_action(int irq, void *data)
+static irqreturn_t tick_broadcast_ipi_action(int irq, void *data)
 {
-   /* This slot is unused and hence available for use, if needed */
+   tick_broadcast_ipi_handler();
return IRQ_HANDLED;
 }
 
@@ -168,14 +169,14 @@ static irqreturn_t debug_ipi_action(int irq, void *data)
 static irq_handler_t smp_ipi_action[] = {
[PPC_MSG_CALL_FUNCTION] =  call_function_action,
[PPC_MSG_RESCHEDULE] = reschedule_action,
-   [PPC_MSG_UNUSED] = unused_action,
+   [PPC_MSG_TICK_BROADCAST] = tick_broadcast_ipi_action,
[PPC_MSG_DEBUGGER_BREAK] = debug_ipi_action,
 };
 
 const char *smp_ipi_name[] = {
[PPC_MSG_CALL_FUNCTION] =  ipi call function,
[PPC_MSG_RESCHEDULE] = ipi reschedule,
-   [PPC_MSG_UNUSED] = ipi unused,
+   [PPC_MSG_TICK_BROADCAST] = ipi tick-broadcast,
[PPC_MSG_DEBUGGER_BREAK] = ipi debugger,
 };
 
@@ -251,6 +252,8 @@ irqreturn_t smp_ipi_demux(void)
generic_smp_call_function_interrupt();
if (all  IPI_MESSAGE(PPC_MSG_RESCHEDULE))
scheduler_ipi();
+   if (all  IPI_MESSAGE(PPC_MSG_TICK_BROADCAST))
+   tick_broadcast_ipi_handler();
if (all  IPI_MESSAGE(PPC_MSG_DEBUGGER_BREAK))
debug_ipi_action(0, NULL);
} while (info-messages);
@@ -289,6 +292,14 @@ void arch_send_call_function_ipi_mask(const struct cpumask 
*mask)
do_message_pass(cpu, PPC_MSG_CALL_FUNCTION);
 }
 
+void tick_broadcast(const struct cpumask *mask)
+{
+   unsigned int cpu;
+
+   for_each_cpu(cpu, mask)
+   do_message_pass(cpu, PPC_MSG_TICK_BROADCAST);
+}
+
 #if defined(CONFIG_DEBUGGER) || defined(CONFIG_KEXEC)
 void smp_send_debugger_break(void)
 {
diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c
index b3b1441..42269c7 100644
--- a/arch/powerpc/kernel/time.c
+++ b/arch/powerpc/kernel/time.c
@@ -813,6 +813,11 @@ static void decrementer_set_mode(enum clock_event_mode 
mode,
decrementer_set_next_event(DECREMENTER_MAX, dev);
 }
 
+/* Interrupt handler for the timer broadcast IPI */
+void tick_broadcast_ipi_handler(void)
+{
+}
+
 static void 

[PATCH V5 5/8] powermgt: Add OPAL call to resync timebase on wakeup

2014-01-15 Thread Preeti U Murthy
From: Vaidyanathan Srinivasan sva...@linux.vnet.ibm.com

During Fast-sleep and deeper power savings state, decrementer and
timebase could be stopped making it out of sync with rest
of the cores in the system.

Add a firmware call to request platform to resync timebase
using low level platform methods.

Signed-off-by: Vaidyanathan Srinivasan sva...@linux.vnet.ibm.com
Signed-off-by: Preeti U. Murthy pre...@linux.vnet.ibm.com
---

 arch/powerpc/include/asm/opal.h|2 ++
 arch/powerpc/kernel/exceptions-64s.S   |2 +-
 arch/powerpc/kernel/idle_power7.S  |   27 
 arch/powerpc/platforms/powernv/opal-wrappers.S |1 +
 4 files changed, 31 insertions(+), 1 deletion(-)

diff --git a/arch/powerpc/include/asm/opal.h b/arch/powerpc/include/asm/opal.h
index 033c06b..a662d06 100644
--- a/arch/powerpc/include/asm/opal.h
+++ b/arch/powerpc/include/asm/opal.h
@@ -132,6 +132,7 @@ extern int opal_enter_rtas(struct rtas_args *args,
 #define OPAL_FLASH_VALIDATE76
 #define OPAL_FLASH_MANAGE  77
 #define OPAL_FLASH_UPDATE  78
+#define OPAL_RESYNC_TIMEBASE   79
 
 #ifndef __ASSEMBLY__
 
@@ -763,6 +764,7 @@ extern void opal_flash_init(void);
 extern int opal_machine_check(struct pt_regs *regs);
 
 extern void opal_shutdown(void);
+extern int opal_resync_timebase(void);
 
 extern void opal_lpc_init(void);
 
diff --git a/arch/powerpc/kernel/exceptions-64s.S 
b/arch/powerpc/kernel/exceptions-64s.S
index b8139fb..91e6417 100644
--- a/arch/powerpc/kernel/exceptions-64s.S
+++ b/arch/powerpc/kernel/exceptions-64s.S
@@ -145,7 +145,7 @@ BEGIN_FTR_SECTION
 
/* Fast Sleep wakeup on PowerNV */
 8: GET_PACA(r13)
-   b   .power7_wakeup_loss
+   b   .power7_wakeup_tb_loss
 
 9:
 END_FTR_SECTION_IFSET(CPU_FTR_HVMODE | CPU_FTR_ARCH_206)
diff --git a/arch/powerpc/kernel/idle_power7.S 
b/arch/powerpc/kernel/idle_power7.S
index e4bbca2..34c71e8 100644
--- a/arch/powerpc/kernel/idle_power7.S
+++ b/arch/powerpc/kernel/idle_power7.S
@@ -17,6 +17,7 @@
 #include asm/ppc-opcode.h
 #include asm/hw_irq.h
 #include asm/kvm_book3s_asm.h
+#include asm/opal.h
 
 #undef DEBUG
 
@@ -124,6 +125,32 @@ _GLOBAL(power7_sleep)
b   power7_powersave_common
/* No return */
 
+_GLOBAL(power7_wakeup_tb_loss)
+   ld  r2,PACATOC(r13);
+   ld  r1,PACAR1(r13)
+
+   /* Time base re-sync */
+   li  r0,OPAL_RESYNC_TIMEBASE
+   LOAD_REG_ADDR(r11,opal);
+   ld  r12,8(r11);
+   ld  r2,0(r11);
+   mtctr   r12
+   bctrl
+
+   /* TODO: Check r3 for failure */
+
+   REST_NVGPRS(r1)
+   REST_GPR(2, r1)
+   ld  r3,_CCR(r1)
+   ld  r4,_MSR(r1)
+   ld  r5,_NIP(r1)
+   addir1,r1,INT_FRAME_SIZE
+   mtcrr3
+   mfspr   r3,SPRN_SRR1/* Return SRR1 */
+   mtspr   SPRN_SRR1,r4
+   mtspr   SPRN_SRR0,r5
+   rfid
+
 _GLOBAL(power7_wakeup_loss)
ld  r1,PACAR1(r13)
REST_NVGPRS(r1)
diff --git a/arch/powerpc/platforms/powernv/opal-wrappers.S 
b/arch/powerpc/platforms/powernv/opal-wrappers.S
index e780650..ddfe95a 100644
--- a/arch/powerpc/platforms/powernv/opal-wrappers.S
+++ b/arch/powerpc/platforms/powernv/opal-wrappers.S
@@ -126,3 +126,4 @@ OPAL_CALL(opal_return_cpu,  
OPAL_RETURN_CPU);
 OPAL_CALL(opal_validate_flash, OPAL_FLASH_VALIDATE);
 OPAL_CALL(opal_manage_flash,   OPAL_FLASH_MANAGE);
 OPAL_CALL(opal_update_flash,   OPAL_FLASH_UPDATE);
+OPAL_CALL(opal_resync_timebase,OPAL_RESYNC_TIMEBASE);

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH V5 4/8] powernv/cpuidle: Add context management for Fast Sleep

2014-01-15 Thread Preeti U Murthy
From: Vaidyanathan Srinivasan sva...@linux.vnet.ibm.com

Before adding Fast-Sleep into the cpuidle framework, some low level
support needs to be added to enable it. This includes saving and
restoring of certain registers at entry and exit time of this state
respectively just like we do in the NAP idle state.

Signed-off-by: Vaidyanathan Srinivasan sva...@linux.vnet.ibm.com
[Changelog modified by Preeti U. Murthy pre...@linux.vnet.ibm.com]
Signed-off-by: Preeti U. Murthy pre...@linux.vnet.ibm.com
---

 arch/powerpc/include/asm/processor.h |1 +
 arch/powerpc/kernel/exceptions-64s.S |   10 -
 arch/powerpc/kernel/idle_power7.S|   63 --
 3 files changed, 53 insertions(+), 21 deletions(-)

diff --git a/arch/powerpc/include/asm/processor.h 
b/arch/powerpc/include/asm/processor.h
index 027fefd..22e547a 100644
--- a/arch/powerpc/include/asm/processor.h
+++ b/arch/powerpc/include/asm/processor.h
@@ -444,6 +444,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);
+extern void power7_sleep(void);
 extern void flush_instruction_cache(void);
 extern void hard_reset_now(void);
 extern void poweroff_now(void);
diff --git a/arch/powerpc/kernel/exceptions-64s.S 
b/arch/powerpc/kernel/exceptions-64s.S
index 9f905e4..b8139fb 100644
--- a/arch/powerpc/kernel/exceptions-64s.S
+++ b/arch/powerpc/kernel/exceptions-64s.S
@@ -121,9 +121,10 @@ BEGIN_FTR_SECTION
cmpwi   cr1,r13,2
/* Total loss of HV state is fatal, we could try to use the
 * PIR to locate a PACA, then use an emergency stack etc...
-* but for now, let's just stay stuck here
+* OPAL v3 based powernv platforms have new idle states
+* which fall in this catagory.
 */
-   bgt cr1,.
+   bgt cr1,8f
GET_PACA(r13)
 
 #ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE
@@ -141,6 +142,11 @@ BEGIN_FTR_SECTION
beq cr1,2f
b   .power7_wakeup_noloss
 2: b   .power7_wakeup_loss
+
+   /* Fast Sleep wakeup on PowerNV */
+8: GET_PACA(r13)
+   b   .power7_wakeup_loss
+
 9:
 END_FTR_SECTION_IFSET(CPU_FTR_HVMODE | CPU_FTR_ARCH_206)
 #endif /* CONFIG_PPC_P7_NAP */
diff --git a/arch/powerpc/kernel/idle_power7.S 
b/arch/powerpc/kernel/idle_power7.S
index 847e40e..e4bbca2 100644
--- a/arch/powerpc/kernel/idle_power7.S
+++ b/arch/powerpc/kernel/idle_power7.S
@@ -20,17 +20,27 @@
 
 #undef DEBUG
 
-   .text
+/* Idle state entry routines */
 
-_GLOBAL(power7_idle)
-   /* Now check if user or arch enabled NAP mode */
-   LOAD_REG_ADDRBASE(r3,powersave_nap)
-   lwz r4,ADDROFF(powersave_nap)(r3)
-   cmpwi   0,r4,0
-   beqlr
-   /* fall through */
+#defineIDLE_STATE_ENTER_SEQ(IDLE_INST) \
+   /* Magic NAP/SLEEP/WINKLE mode enter sequence */\
+   std r0,0(r1);   \
+   ptesync;\
+   ld  r0,0(r1);   \
+1: cmp cr0,r0,r0;  \
+   bne 1b; \
+   IDLE_INST;  \
+   b   .
 
-_GLOBAL(power7_nap)
+   .text
+
+/*
+ * Pass requested state in r3:
+ * 0 - nap
+ * 1 - sleep
+ */
+_GLOBAL(power7_powersave_common)
+   /* Use r3 to pass state nap/sleep/winkle */
/* NAP is a state loss, we create a regs frame on the
 * stack, fill it up with the state we care about and
 * stick a pointer to it in PACAR1. We really only
@@ -79,8 +89,8 @@ _GLOBAL(power7_nap)
/* Continue saving state */
SAVE_GPR(2, r1)
SAVE_NVGPRS(r1)
-   mfcrr3
-   std r3,_CCR(r1)
+   mfcrr4
+   std r4,_CCR(r1)
std r9,_MSR(r1)
std r1,PACAR1(r13)
 
@@ -89,15 +99,30 @@ _GLOBAL(power7_nap)
li  r4,KVM_HWTHREAD_IN_NAP
stb r4,HSTATE_HWTHREAD_STATE(r13)
 #endif
+   cmpwi   cr0,r3,1
+   beq 2f
+   IDLE_STATE_ENTER_SEQ(PPC_NAP)
+   /* No return */
+2: IDLE_STATE_ENTER_SEQ(PPC_SLEEP)
+   /* No return */
 
-   /* Magic NAP mode enter sequence */
-   std r0,0(r1)
-   ptesync
-   ld  r0,0(r1)
-1: cmp cr0,r0,r0
-   bne 1b
-   PPC_NAP
-   b   .
+_GLOBAL(power7_idle)
+   /* Now check if user or arch enabled NAP mode */
+   LOAD_REG_ADDRBASE(r3,powersave_nap)
+   lwz r4,ADDROFF(powersave_nap)(r3)
+   cmpwi   0,r4,0
+   beqlr
+   /* fall through */
+
+_GLOBAL(power7_nap)
+   li  r3,0
+   b   power7_powersave_common
+   /* No return */
+
+_GLOBAL(power7_sleep)
+   li  r3,1
+   b   power7_powersave_common
+   /* No return */
 
 

[PATCH V5 7/8] cpuidle/powernv: Add Fast-Sleep CPU idle state

2014-01-15 Thread Preeti U Murthy
Fast sleep is one of the deep idle states on Power8 in which local timers of
CPUs stop. On PowerPC we do not have an external clock device which can
handle wakeup of such CPUs. Now that we have the support in the tick broadcast
framework for archs that do not sport such a device and the low level support
for fast sleep, enable it in the cpuidle framework on PowerNV.

Signed-off-by: Preeti U Murthy pre...@linux.vnet.ibm.com
---

 arch/powerpc/Kconfig  |2 ++
 arch/powerpc/kernel/time.c|2 +-
 drivers/cpuidle/cpuidle-powernv.c |   39 +
 3 files changed, 42 insertions(+), 1 deletion(-)

diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index b44b52c..cafa788 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -129,6 +129,8 @@ config PPC
select GENERIC_CMOS_UPDATE
select GENERIC_TIME_VSYSCALL_OLD
select GENERIC_CLOCKEVENTS
+   select GENERIC_CLOCKEVENTS_BROADCAST
+   select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST
select GENERIC_STRNCPY_FROM_USER
select GENERIC_STRNLEN_USER
select HAVE_MOD_ARCH_SPECIFIC
diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c
index 42cb603..d9efd93 100644
--- a/arch/powerpc/kernel/time.c
+++ b/arch/powerpc/kernel/time.c
@@ -106,7 +106,7 @@ struct clock_event_device decrementer_clockevent = {
.irq= 0,
.set_next_event = decrementer_set_next_event,
.set_mode   = decrementer_set_mode,
-   .features   = CLOCK_EVT_FEAT_ONESHOT,
+   .features   = CLOCK_EVT_FEAT_ONESHOT | CLOCK_EVT_FEAT_C3STOP,
 };
 EXPORT_SYMBOL(decrementer_clockevent);
 
diff --git a/drivers/cpuidle/cpuidle-powernv.c 
b/drivers/cpuidle/cpuidle-powernv.c
index 78fd174..e3aa62f 100644
--- a/drivers/cpuidle/cpuidle-powernv.c
+++ b/drivers/cpuidle/cpuidle-powernv.c
@@ -11,6 +11,7 @@
 #include linux/cpuidle.h
 #include linux/cpu.h
 #include linux/notifier.h
+#include linux/clockchips.h
 
 #include asm/machdep.h
 #include asm/firmware.h
@@ -49,6 +50,37 @@ static int nap_loop(struct cpuidle_device *dev,
return index;
 }
 
+static int fastsleep_loop(struct cpuidle_device *dev,
+   struct cpuidle_driver *drv,
+   int index)
+{
+   int cpu = dev-cpu;
+   unsigned long old_lpcr = mfspr(SPRN_LPCR);
+   unsigned long new_lpcr;
+
+   new_lpcr = old_lpcr;
+   new_lpcr = ~(LPCR_MER | LPCR_PECE); /* lpcr[mer] must be 0 */
+
+   /* exit powersave upon external interrupt, but not decrementer
+* interrupt, Emulate sleep.
+*/
+   new_lpcr |= LPCR_PECE0;
+
+   if (clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, cpu)) {
+   new_lpcr |= LPCR_PECE1;
+   mtspr(SPRN_LPCR, new_lpcr);
+   power7_nap();
+   } else {
+   mtspr(SPRN_LPCR, new_lpcr);
+   power7_sleep();
+   clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, cpu);
+   }
+
+   mtspr(SPRN_LPCR, old_lpcr);
+
+   return index;
+}
+
 /*
  * States for dedicated partition case.
  */
@@ -67,6 +99,13 @@ static struct cpuidle_state powernv_states[] = {
.exit_latency = 10,
.target_residency = 100,
.enter = nap_loop },
+{ /* Fastsleep */
+   .name = fastsleep,
+   .desc = fastsleep,
+   .flags = CPUIDLE_FLAG_TIME_VALID,
+   .exit_latency = 10,
+   .target_residency = 100,
+   .enter = fastsleep_loop },
 };
 
 static int powernv_cpuidle_add_cpu_notifier(struct notifier_block *n,

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH V5 6/8] time/cpuidle: Support in tick broadcast framework in the absence of external clock device

2014-01-15 Thread Preeti U Murthy
On some architectures, in certain CPU deep idle states the local timers stop.
An external clock device is used to wakeup these CPUs. The kernel support for 
the
wakeup of these CPUs is provided by the tick broadcast framework by using the
external clock device as the wakeup source.

However not all implementations of architectures provide such an external
clock device such as some PowerPC ones. This patch includes support in the
broadcast framework to handle the wakeup of the CPUs in deep idle states on such
systems by queuing a hrtimer on one of the CPUs, meant to handle the wakeup of
CPUs in deep idle states. This CPU is identified as the bc_cpu.

Each time the hrtimer expires, it is reprogrammed for the next wakeup of the
CPUs in deep idle state after handling broadcast. However when a CPU is about
to enter  deep idle state with its wakeup time earlier than the time at which
the hrtimer is currently programmed, it *becomes the new bc_cpu* and restarts
the hrtimer on itself. This way the job of doing broadcast is handed around to
the CPUs that ask for the earliest wakeup just before entering deep idle
state. This is consistent with what happens in cases where an external clock
device is present. The smp affinity of this clock device is set to the CPU
with the earliest wakeup.

The important point here is that the bc_cpu cannot enter deep idle state
since it has a hrtimer queued to wakeup the other CPUs in deep idle. Hence it
cannot have its local timer stopped. Therefore for such a CPU, the
BROADCAST_ENTER notification has to fail implying that it cannot enter deep
idle state. On architectures where an external clock device is present, all
CPUs can enter deep idle.

During hotplug of the bc_cpu, the job of doing a broadcast is assigned to the
first cpu in the broadcast mask. This newly nominated bc_cpu is woken up by
an IPI so as to queue the above mentioned hrtimer on it.

Signed-off-by: Preeti U Murthy pre...@linux.vnet.ibm.com
---

 include/linux/clockchips.h   |4 -
 kernel/time/clockevents.c|9 +-
 kernel/time/tick-broadcast.c |  192 ++
 kernel/time/tick-internal.h  |8 +-
 4 files changed, 186 insertions(+), 27 deletions(-)

diff --git a/include/linux/clockchips.h b/include/linux/clockchips.h
index 493aa02..bbda37b 100644
--- a/include/linux/clockchips.h
+++ b/include/linux/clockchips.h
@@ -186,9 +186,9 @@ static inline int tick_check_broadcast_expired(void) { 
return 0; }
 #endif
 
 #ifdef CONFIG_GENERIC_CLOCKEVENTS
-extern void clockevents_notify(unsigned long reason, void *arg);
+extern int clockevents_notify(unsigned long reason, void *arg);
 #else
-static inline void clockevents_notify(unsigned long reason, void *arg) {}
+static inline int clockevents_notify(unsigned long reason, void *arg) {}
 #endif
 
 #else /* CONFIG_GENERIC_CLOCKEVENTS_BUILD */
diff --git a/kernel/time/clockevents.c b/kernel/time/clockevents.c
index 086ad60..d61404e 100644
--- a/kernel/time/clockevents.c
+++ b/kernel/time/clockevents.c
@@ -524,12 +524,13 @@ void clockevents_resume(void)
 #ifdef CONFIG_GENERIC_CLOCKEVENTS
 /**
  * clockevents_notify - notification about relevant events
+ * Returns non zero on error.
  */
-void clockevents_notify(unsigned long reason, void *arg)
+int clockevents_notify(unsigned long reason, void *arg)
 {
struct clock_event_device *dev, *tmp;
unsigned long flags;
-   int cpu;
+   int cpu, ret = 0;
 
raw_spin_lock_irqsave(clockevents_lock, flags);
 
@@ -542,11 +543,12 @@ void clockevents_notify(unsigned long reason, void *arg)
 
case CLOCK_EVT_NOTIFY_BROADCAST_ENTER:
case CLOCK_EVT_NOTIFY_BROADCAST_EXIT:
-   tick_broadcast_oneshot_control(reason);
+   ret = tick_broadcast_oneshot_control(reason);
break;
 
case CLOCK_EVT_NOTIFY_CPU_DYING:
tick_handover_do_timer(arg);
+   tick_handover_broadcast_cpu(arg);
break;
 
case CLOCK_EVT_NOTIFY_SUSPEND:
@@ -585,6 +587,7 @@ void clockevents_notify(unsigned long reason, void *arg)
break;
}
raw_spin_unlock_irqrestore(clockevents_lock, flags);
+   return ret;
 }
 EXPORT_SYMBOL_GPL(clockevents_notify);
 
diff --git a/kernel/time/tick-broadcast.c b/kernel/time/tick-broadcast.c
index 9532690..1c23912 100644
--- a/kernel/time/tick-broadcast.c
+++ b/kernel/time/tick-broadcast.c
@@ -20,6 +20,7 @@
 #include linux/sched.h
 #include linux/smp.h
 #include linux/module.h
+#include linux/slab.h
 
 #include tick-internal.h
 
@@ -35,6 +36,15 @@ static cpumask_var_t tmpmask;
 static DEFINE_RAW_SPINLOCK(tick_broadcast_lock);
 static int tick_broadcast_force;
 
+/*
+ * Helper variables for handling broadcast in the absence of a
+ * tick_broadcast_device.
+ * */
+static struct hrtimer *bc_hrtimer;
+static int bc_cpu = -1;
+static ktime_t bc_next_wakeup;
+static int hrtimer_initialized = 0;
+
 #ifdef CONFIG_TICK_ONESHOT
 static void 

[PATCH V5 8/8] cpuidle/powernv: Parse device tree to setup idle states

2014-01-15 Thread Preeti U Murthy
Add deep idle states such as nap and fast sleep to the cpuidle state table
only if they are discovered from the device tree during cpuidle initialization.

Signed-off-by: Preeti U Murthy pre...@linux.vnet.ibm.com
---

 drivers/cpuidle/cpuidle-powernv.c |   81 +
 1 file changed, 64 insertions(+), 17 deletions(-)

diff --git a/drivers/cpuidle/cpuidle-powernv.c 
b/drivers/cpuidle/cpuidle-powernv.c
index e3aa62f..b01987d 100644
--- a/drivers/cpuidle/cpuidle-powernv.c
+++ b/drivers/cpuidle/cpuidle-powernv.c
@@ -12,10 +12,17 @@
 #include linux/cpu.h
 #include linux/notifier.h
 #include linux/clockchips.h
+#include linux/of.h
 
 #include asm/machdep.h
 #include asm/firmware.h
 
+/* Flags and constants used in PowerNV platform */
+
+#define MAX_POWERNV_IDLE_STATES8
+#define IDLE_USE_INST_NAP  0x0001 /* Use nap instruction */
+#define IDLE_USE_INST_SLEEP0x0002 /* Use sleep instruction */
+
 struct cpuidle_driver powernv_idle_driver = {
.name = powernv_idle,
.owner= THIS_MODULE,
@@ -84,7 +91,7 @@ static int fastsleep_loop(struct cpuidle_device *dev,
 /*
  * States for dedicated partition case.
  */
-static struct cpuidle_state powernv_states[] = {
+static struct cpuidle_state powernv_states[MAX_POWERNV_IDLE_STATES] = {
{ /* Snooze */
.name = snooze,
.desc = snooze,
@@ -92,20 +99,6 @@ static struct cpuidle_state powernv_states[] = {
.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 },
-{ /* Fastsleep */
-   .name = fastsleep,
-   .desc = fastsleep,
-   .flags = CPUIDLE_FLAG_TIME_VALID,
-   .exit_latency = 10,
-   .target_residency = 100,
-   .enter = fastsleep_loop },
 };
 
 static int powernv_cpuidle_add_cpu_notifier(struct notifier_block *n,
@@ -166,19 +159,73 @@ static int powernv_cpuidle_driver_init(void)
return 0;
 }
 
+static int powernv_add_idle_states(void)
+{
+   struct device_node *power_mgt;
+   struct property *prop;
+   int nr_idle_states = 1; /* Snooze */
+   int dt_idle_states;
+   u32 *flags;
+   int i;
+
+   /* Currently we have snooze statically defined */
+
+   power_mgt = of_find_node_by_path(/ibm,opal/power-mgt);
+   if (!power_mgt) {
+   pr_warn(opal: PowerMgmt Node not found\n);
+   return nr_idle_states;
+   }
+
+   prop = of_find_property(power_mgt, ibm,cpu-idle-state-flags, NULL);
+   if (!prop) {
+   pr_warn(DT-PowerMgmt: missing ibm,cpu-idle-state-flags\n);
+   return nr_idle_states;
+   }
+
+   dt_idle_states = prop-length / sizeof(u32);
+   flags = (u32 *) prop-value;
+
+   for (i = 0; i  dt_idle_states; i++) {
+
+   if (flags[i]  IDLE_USE_INST_NAP) {
+   /* Add NAP state */
+   strcpy(powernv_states[nr_idle_states].name, Nap);
+   strcpy(powernv_states[nr_idle_states].desc, Nap);
+   powernv_states[nr_idle_states].flags = 
CPUIDLE_FLAG_TIME_VALID;
+   powernv_states[nr_idle_states].exit_latency = 10;
+   powernv_states[nr_idle_states].target_residency = 100;
+   powernv_states[nr_idle_states].enter = nap_loop;
+   nr_idle_states++;
+   }
+
+   if (flags[i]  IDLE_USE_INST_SLEEP) {
+   /* Add FASTSLEEP state */
+   strcpy(powernv_states[nr_idle_states].name, 
FastSleep);
+   strcpy(powernv_states[nr_idle_states].desc, 
FastSleep);
+   powernv_states[nr_idle_states].flags = 
CPUIDLE_FLAG_TIME_VALID;
+   powernv_states[nr_idle_states].exit_latency = 300;
+   powernv_states[nr_idle_states].target_residency = 
100;
+   powernv_states[nr_idle_states].enter = fastsleep_loop;
+   nr_idle_states++;
+   }
+   }
+
+   return nr_idle_states;
+}
+
 /*
  * powernv_idle_probe()
  * Choose state table for shared versus dedicated partition
  */
 static int powernv_idle_probe(void)
 {
-
if (cpuidle_disable != IDLE_NO_OVERRIDE)
return -ENODEV;
 
if (firmware_has_feature(FW_FEATURE_OPALv3)) {
cpuidle_state_table = powernv_states;
-   max_idle_state = ARRAY_SIZE(powernv_states);
+   /* Device tree can indicate more idle states */
+   max_idle_state = powernv_add_idle_states();
} else
return 

Re: [git pull] Please pull powerpc.git merge branch

2014-01-15 Thread Benjamin Herrenschmidt
On Wed, 2014-01-15 at 15:05 +0700, Linus Torvalds wrote:
 On Wed, Jan 15, 2014 at 12:01 PM, Benjamin Herrenschmidt
 b...@kernel.crashing.org wrote:
 
  My original intend was to put it in powerpc-next and then shoot it to
  stable, but it got a tad annoying (due to churn it needs to be applied
  at least on rc4 or later while my next is at rc1 and clean that way), so
  I put it in the merge branch.
 
 Quite frankly, I'll prefer to not merge it now, and then 3.13 will get
 it from stable, when it does things like this.
 
 Partly because it fixes a power-only bug, but potentially changes
 non-power behavior. If it was all in arch/powerpc, I wouldn't mind.

Right, I wasn't too comfortable either. I'll resend the pull request
after the merge window is open.

Cheers,
Ben.

Linus
 --
 To unsubscribe from this list: send the line unsubscribe linux-kernel in
 the body of a message to majord...@vger.kernel.org
 More majordomo info at  http://vger.kernel.org/majordomo-info.html
 Please read the FAQ at  http://www.tux.org/lkml/


___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


Re: Disable sleep states on P7+

2014-01-15 Thread Deepthi Dharwar
Hi Steven,

On 01/14/2014 08:06 PM, Steven Pratt wrote:
 I am looking for info on when and how we are able to disable power saving 
 features of current (P7, P7+) chips in order to reduce latency. This is often 
 done in latency sensitive applications when

 power consumption is not an issue. On Intel boxes we can disable
P-state frequency changes as well as disabling C-State or sleep state
changes. In fact we can control how deep a sleep the processor can go
into.

I know we have control Dynamic Processor Scaling and Idle Power Savings,
but what states do these really affect?  Can I really disable Nap mode
of a processor? If so how?  Can I disable even the lightest winkle mode?

Looking for current information (read RHEL 6 and SLES11), future changes
are interesting.
 

On POWERVM platforms idle states currently supported are:
Snooze - reducing thread priority.
Nap
Sleep.

Snooze and Nap can be controlled through in-band kernel mechanisms and
Sleep state through AEM.

Currently you can turn off Idle Power Savings mode and run in dynamic
processor scaling mode. By doing so you will disable entry into Sleep
state on all CPUS.

If you further want to disable NAP, then you could just boot the kernel
with powersave=off. This will disable the entry into any of the idle
state like nap and just reduce the priority of the thread when there is
no work to be done. This is part of cpuidle framework which is available
on SLES 11 SP3 and RHEL7.

In the newer kernels cpuidle framework is adopted for POWERVM platform
but in case if you are using RHEL 6 or SLES 11 SP1/2, then you could use
the ppc64_cpu util and set a high smt-snooze-delay value say 1000.first

# ppc64_cpu --smt-snooze-delay=1000.

smt-snooze-delay variable potentially delays entry to NAP state.
So if the idle time predicted on a cpu = 1000us and smt-snooze-delay is
set to 100 (which is default value), then on RHEL 6 and SLES 11 SP1/2
kernels cpus would reduce the thread priority and spin for  first 100us
and if the cpu continues to be idle further then automatically go to NAP
state for remaining (1000-100us) time.

By setting a very high value, one would always be looping  This could
potentially delay ure entry to NAP state and effectively disable entry
into NAP state most of the time.

Please let me know if you have any queries around it.

Regards,
Deepthi






 Steve
 
 ___
 Linuxppc-dev mailing list
 Linuxppc-dev@lists.ozlabs.org
 https://lists.ozlabs.org/listinfo/linuxppc-dev
 

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH 2/2][v2] powerpc/config: Enable memory driver

2014-01-15 Thread Prabhakar Kushwaha
As Freescale IFC controller has been moved to driver to driver/memory.

So enable memory driver in powerpc config

Signed-off-by: Prabhakar Kushwaha prabha...@freescale.com
---
 changes for v2: Sending as it is

 arch/powerpc/configs/corenet32_smp_defconfig |1 +
 arch/powerpc/configs/corenet64_smp_defconfig |1 +
 arch/powerpc/configs/mpc85xx_defconfig   |1 +
 arch/powerpc/configs/mpc85xx_smp_defconfig   |1 +
 4 files changed, 4 insertions(+)

diff --git a/arch/powerpc/configs/corenet32_smp_defconfig 
b/arch/powerpc/configs/corenet32_smp_defconfig
index bbd794d..087d437 100644
--- a/arch/powerpc/configs/corenet32_smp_defconfig
+++ b/arch/powerpc/configs/corenet32_smp_defconfig
@@ -142,6 +142,7 @@ CONFIG_RTC_DRV_DS3232=y
 CONFIG_RTC_DRV_CMOS=y
 CONFIG_UIO=y
 CONFIG_STAGING=y
+CONFIG_MEMORY=y
 CONFIG_VIRT_DRIVERS=y
 CONFIG_FSL_HV_MANAGER=y
 CONFIG_EXT2_FS=y
diff --git a/arch/powerpc/configs/corenet64_smp_defconfig 
b/arch/powerpc/configs/corenet64_smp_defconfig
index 63508dd..25b03f8 100644
--- a/arch/powerpc/configs/corenet64_smp_defconfig
+++ b/arch/powerpc/configs/corenet64_smp_defconfig
@@ -129,6 +129,7 @@ CONFIG_EDAC=y
 CONFIG_EDAC_MM_EDAC=y
 CONFIG_DMADEVICES=y
 CONFIG_FSL_DMA=y
+CONFIG_MEMORY=y
 CONFIG_EXT2_FS=y
 CONFIG_EXT3_FS=y
 CONFIG_ISO9660_FS=m
diff --git a/arch/powerpc/configs/mpc85xx_defconfig 
b/arch/powerpc/configs/mpc85xx_defconfig
index d2e0fab..87aad6d 100644
--- a/arch/powerpc/configs/mpc85xx_defconfig
+++ b/arch/powerpc/configs/mpc85xx_defconfig
@@ -213,6 +213,7 @@ CONFIG_RTC_CLASS=y
 CONFIG_RTC_DRV_CMOS=y
 CONFIG_DMADEVICES=y
 CONFIG_FSL_DMA=y
+CONFIG_MEMORY=y
 # CONFIG_NET_DMA is not set
 CONFIG_EXT2_FS=y
 CONFIG_EXT3_FS=y
diff --git a/arch/powerpc/configs/mpc85xx_smp_defconfig 
b/arch/powerpc/configs/mpc85xx_smp_defconfig
index 4cb7b59..d5d6915 100644
--- a/arch/powerpc/configs/mpc85xx_smp_defconfig
+++ b/arch/powerpc/configs/mpc85xx_smp_defconfig
@@ -214,6 +214,7 @@ CONFIG_RTC_CLASS=y
 CONFIG_RTC_DRV_CMOS=y
 CONFIG_DMADEVICES=y
 CONFIG_FSL_DMA=y
+CONFIG_MEMORY=y
 # CONFIG_NET_DMA is not set
 CONFIG_EXT2_FS=y
 CONFIG_EXT3_FS=y
-- 
1.7.9.5



___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH 1/2][v2] driver/memory:Move Freescale IFC driver to a common driver

2014-01-15 Thread Prabhakar Kushwaha
Freescale IFC controller has been used for mpc8xxx. It will be used
for ARM-based SoC as well. This patch moves the driver to driver/memory
and fix the header file includes.

Also remove module_platform_driver() and  instead call
platform_driver_register() from subsys_initcall() to make sure this module
has been loaded before MTD partition parsing starts.

Signed-off-by: Prabhakar Kushwaha prabha...@freescale.com
---
Changes for v2:
- Move fsl_ifc in driver/memory

 arch/powerpc/sysdev/Makefile   |1 -
 drivers/memory/Makefile|1 +
 {arch/powerpc/sysdev = drivers/memory}/fsl_ifc.c  |8 ++--
 drivers/mtd/nand/fsl_ifc_nand.c|2 +-
 .../include/asm = include/linux}/fsl_ifc.h|0
 5 files changed, 8 insertions(+), 4 deletions(-)
 rename {arch/powerpc/sysdev = drivers/memory}/fsl_ifc.c (98%)
 rename {arch/powerpc/include/asm = include/linux}/fsl_ifc.h (100%)

diff --git a/arch/powerpc/sysdev/Makefile b/arch/powerpc/sysdev/Makefile
index f67ac90..afbcc37 100644
--- a/arch/powerpc/sysdev/Makefile
+++ b/arch/powerpc/sysdev/Makefile
@@ -21,7 +21,6 @@ obj-$(CONFIG_FSL_SOC) += fsl_soc.o fsl_mpic_err.o
 obj-$(CONFIG_FSL_PCI)  += fsl_pci.o $(fsl-msi-obj-y)
 obj-$(CONFIG_FSL_PMC)  += fsl_pmc.o
 obj-$(CONFIG_FSL_LBC)  += fsl_lbc.o
-obj-$(CONFIG_FSL_IFC)  += fsl_ifc.o
 obj-$(CONFIG_FSL_GTM)  += fsl_gtm.o
 obj-$(CONFIG_FSL_85XX_CACHE_SRAM)  += fsl_85xx_l2ctlr.o 
fsl_85xx_cache_sram.o
 obj-$(CONFIG_SIMPLE_GPIO)  += simple_gpio.o
diff --git a/drivers/memory/Makefile b/drivers/memory/Makefile
index 969d923..f2bf25c 100644
--- a/drivers/memory/Makefile
+++ b/drivers/memory/Makefile
@@ -6,6 +6,7 @@ ifeq ($(CONFIG_DDR),y)
 obj-$(CONFIG_OF)   += of_memory.o
 endif
 obj-$(CONFIG_TI_EMIF)  += emif.o
+obj-$(CONFIG_FSL_IFC)  += fsl_ifc.o
 obj-$(CONFIG_MVEBU_DEVBUS) += mvebu-devbus.o
 obj-$(CONFIG_TEGRA20_MC)   += tegra20-mc.o
 obj-$(CONFIG_TEGRA30_MC)   += tegra30-mc.o
diff --git a/arch/powerpc/sysdev/fsl_ifc.c b/drivers/memory/fsl_ifc.c
similarity index 98%
rename from arch/powerpc/sysdev/fsl_ifc.c
rename to drivers/memory/fsl_ifc.c
index d7fc722..135a950 100644
--- a/arch/powerpc/sysdev/fsl_ifc.c
+++ b/drivers/memory/fsl_ifc.c
@@ -30,8 +30,8 @@
 #include linux/of.h
 #include linux/of_device.h
 #include linux/platform_device.h
+#include linux/fsl_ifc.h
 #include asm/prom.h
-#include asm/fsl_ifc.h
 
 struct fsl_ifc_ctrl *fsl_ifc_ctrl_dev;
 EXPORT_SYMBOL(fsl_ifc_ctrl_dev);
@@ -299,7 +299,11 @@ static struct platform_driver fsl_ifc_ctrl_driver = {
.remove  = fsl_ifc_ctrl_remove,
 };
 
-module_platform_driver(fsl_ifc_ctrl_driver);
+static int __init fsl_ifc_init(void)
+{
+   return platform_driver_register(fsl_ifc_ctrl_driver);
+}
+subsys_initcall(fsl_ifc_init);
 
 MODULE_LICENSE(GPL);
 MODULE_AUTHOR(Freescale Semiconductor);
diff --git a/drivers/mtd/nand/fsl_ifc_nand.c b/drivers/mtd/nand/fsl_ifc_nand.c
index 4335577..865b323 100644
--- a/drivers/mtd/nand/fsl_ifc_nand.c
+++ b/drivers/mtd/nand/fsl_ifc_nand.c
@@ -30,7 +30,7 @@
 #include linux/mtd/nand.h
 #include linux/mtd/partitions.h
 #include linux/mtd/nand_ecc.h
-#include asm/fsl_ifc.h
+#include linux/fsl_ifc.h
 
 #define FSL_IFC_V1_1_0 0x0101
 #define ERR_BYTE   0xFF /* Value returned for read
diff --git a/arch/powerpc/include/asm/fsl_ifc.h b/include/linux/fsl_ifc.h
similarity index 100%
rename from arch/powerpc/include/asm/fsl_ifc.h
rename to include/linux/fsl_ifc.h
-- 
1.7.9.5



___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


Re: [PATCH 1/2][v2] driver/memory:Move Freescale IFC driver to a common driver

2014-01-15 Thread Arnd Bergmann
On Wednesday 15 January 2014, Prabhakar Kushwaha wrote:
 Freescale IFC controller has been used for mpc8xxx. It will be used
 for ARM-based SoC as well. This patch moves the driver to driver/memory
 and fix the header file includes.
 
 Also remove module_platform_driver() and  instead call
 platform_driver_register() from subsys_initcall() to make sure this module
 has been loaded before MTD partition parsing starts.
 
 Signed-off-by: Prabhakar Kushwaha prabha...@freescale.com

Acked-by: Arnd Bergmann a...@arndb.de

provided that you also move the binding from powerpc/fsl/ifc.txt to
memory/fsl-ifc.txt.
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


Re: [PATCH V5 0/8] cpuidle/ppc: Enable deep idle states on PowerNV

2014-01-15 Thread Paul Gortmaker
On 14-01-15 03:07 AM, Preeti U Murthy wrote:

[...]

 
 This patchset is based on mainline commit-id:8ae516aa8b8161254d3,  and the

I figured I'd give this a quick sanity build test for a few
configs, but v3.13-rc1-141-g8ae516aa8b81 seems too old; Ben's
ppc next branch is at v3.13-rc1-160-gfac515db4520 and it fails:

---
$ git am ppc-idle
Applying: powerpc: Free up the slot of PPC_MSG_CALL_FUNC_SINGLE IPI message
Applying: powerpc: Implement tick broadcast IPI as a fixed IPI message
Applying: cpuidle/ppc: Split timer_interrupt() into timer handling and 
interrupt handling routines
error: patch failed: arch/powerpc/kernel/time.c:510
error: arch/powerpc/kernel/time.c: patch does not apply
Patch failed at 0003 cpuidle/ppc: Split timer_interrupt() into timer handling 
and interrupt handling routines
The copy of the patch that failed is found in:
   /home/paul/git/linux-head/.git/rebase-apply/patch
When you have resolved this problem, run git am --continue.
If you prefer to skip this patch, run git am --skip instead.
To restore the original branch and stop patching, run git am --abort.
$ dry-run
patching file arch/powerpc/kernel/time.c
Hunk #3 FAILED at 544.
Hunk #4 FAILED at 554.
Hunk #5 succeeded at 862 (offset 12 lines).
2 out of 5 hunks FAILED -- saving rejects to file arch/powerpc/kernel/time.c.rej


It appears to conflict with:

commit 0215f7d8c53fb192cd4491ede0ece5cca6b5db57
Author: Benjamin Herrenschmidt b...@kernel.crashing.org
Date:   Tue Jan 14 17:11:39 2014 +1100

powerpc: Fix races with irq_work


Paul.
--

 cpuidle driver for powernv posted by Deepthi Dharwar:
 https://lkml.org/lkml/2014/1/14/172
 
 
 Changes in V5:
 -
 The primary change in this version is in Patch[6/8].
 As per the discussions in V4 posting of this patchset, it was decided to
 refine handling the wakeup of CPUs in fast-sleep by doing the following:
 
 1. In V4, a polling mechanism was used by the CPU handling broadcast to
 find out the time of next wakeup of the CPUs in deep idle states. V5 avoids
 polling by a way described under PATCH[6/8] in this patchset.
 
 2. The mechanism of broadcast handling of CPUs in deep idle in the absence of 
 an
 external wakeup device should be generic and not arch specific code. Hence in 
 this
 version this functionality has been integrated into the tick broadcast 
 framework in
 the kernel unlike before where it was handled in powerpc specific code.
 
 3. It was suggested that the broadcast cpu can be the time keeping cpu
 itself. However this has challenges of its own:
 
  a. The time keeping cpu need not exist when all cpus are idle. Hence there
 are phases in time when time keeping cpu is absent. But for the use case that
 this patchset is trying to address we rely on the presence of a broadcast cpu
 all the time.
 
  b. The nomination and un-assignment of the time keeping cpu is not protected
 by a lock today and need not be as well since such is its use case in the
 kernel. However we would need locks if we double up the time keeping cpu as 
 the
 broadcast cpu.
 
 Hence the broadcast cpu is independent of the time-keeping cpu. However 
 PATCH[6/8]
 proposes a simpler solution to pick a broadcast cpu in this version.
 
 
 
 Changes in V4:
 -
 https://lkml.org/lkml/2013/11/29/97
 
 1. Add Fast Sleep CPU idle state on PowerNV.
 
 2. Add the required context management for Fast Sleep and the call to OPAL
 to synchronize time base after wakeup from fast sleep.
 
 4. Add parsing of CPU idle states from the device tree to populate the
 cpuidle
 state table.
 
 5. Rename ambiguous functions in the code around waking up of CPUs from fast
 sleep.
 
 6. Fixed a bug in re-programming of the hrtimer that is queued to wakeup the
 CPUs in fast sleep and modified Changelogs.
 
 7. Added the ARCH_HAS_TICK_BROADCAST option. This signifies that we have a
 arch specific function to perform broadcast.
 
 
 Changes in V3:
 -
 http://thread.gmane.org/gmane.linux.power-management.general/38113
 
 1. Fix the way in which a broadcast ipi is handled on the idling cpus. Timer
 handling on a broadcast ipi is being done now without missing out any timer
 stats generation.
 
 2. Fix a bug in the programming of the hrtimer meant to do broadcast. Program
 it to trigger at the earlier of a broadcast period, and the next wakeup
 event. By introducing the broadcast period as the maximum period after
 which the broadcast hrtimer can fire, we ensure that we do not miss
 wakeups in corner cases.
 
 3. On hotplug of a broadcast cpu, trigger the hrtimer meant to do broadcast
 to fire immediately on the new broadcast cpu. This will ensure we do not miss
 doing a broadcast pending in the nearest future.
 
 4. Change the type of allocation from GFP_KERNEL to GFP_NOWAIT while
 initializing bc_hrtimer since we are in an atomic context and cannot sleep.
 
 5. Use the broadcast ipi to wakeup the newly nominated broadcast cpu on
 hotplug of the old instead of 

[PATCH] powerpc: mm: fix mmap errno when MAP_FIXED is set and mapping exceeds the allowed address space

2014-01-15 Thread Jerome Marchand
According to Posix, if MAP_FIXED is specified mmap shall set ENOMEM if
the requested mapping exceeds the allowed range for address space of
the process. The generic code set it right, but the specific powerpc
slice_get_unmapped_area() function currently returns -EINVAL in that
case.
This patch corrects it.

Signed-off-by: Jerome Marchand jmarc...@redhat.com
---
 arch/powerpc/mm/slice.c |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/arch/powerpc/mm/slice.c b/arch/powerpc/mm/slice.c
index 7ce9cf3..b0c75cc 100644
--- a/arch/powerpc/mm/slice.c
+++ b/arch/powerpc/mm/slice.c
@@ -408,7 +408,7 @@ unsigned long slice_get_unmapped_area(unsigned long addr, 
unsigned long len,
if (fixed  (addr  ((1ul  pshift) - 1)))
return -EINVAL;
if (fixed  addr  (mm-task_size - len))
-   return -EINVAL;
+   return -ENOMEM;
 
/* If hint, make sure it matches our alignment restrictions */
if (!fixed  addr) {
-- 
1.7.7.6

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


Please pull 'next' branch of 5xxx tree

2014-01-15 Thread Anatolij Gustschin
Hi Ben !

please pull mpc5xxx patches for v3.14:

Switch mpc512x to the common clock framework and adapt mpc512x
drivers to use the new clock driver. Old PPC_CLOCK code is
removed entirely since there are no users any more.

All these patches have been in linux-next for more then
two weeks now.

Thanks,
Anatolij

The following changes since commit dece8ada993e1764a115bdff0f1eaa5fc8dc:

  Merge branch 'merge' into next (2013-12-30 15:19:31 +1100)

are available in the git repository at:


  git://git.denx.de/linux-2.6-agust.git next

for you to fetch changes up to bc75059422338197ce487d338ac9c898761e1e61:

  powerpc/512x: dts: add MPC5125 clock specs (2014-01-12 18:59:50 +0100)


Gerhard Sittig (20):
  dts: mpc512x: introduce dt-bindings/clock/ header
  dts: mpc512x: add clock related device tree specs
  clk: mpc512x: introduce COMMON_CLK for MPC512x (disabled)
  clk: mpc512x: add backwards compat to the CCF code
  dts: mpc512x: add clock specs for client lookups
  clk: mpc5xxx: switch to COMMON_CLK, retire PPC_CLOCK
  spi: mpc512x: adjust to OF based clock lookup
  serial: mpc512x: adjust for OF based clock lookup
  serial: mpc512x: setup the PSC FIFO clock as well
  USB: fsl-mph-dr-of: adjust for OF based clock lookup
  mtd: mpc5121_nfc: adjust for OF based clock lookup
  fsl-viu: adjust for OF based clock lookup
  net: can: mscan: adjust to common clock support for mpc512x
  net: can: mscan: remove non-CCF code for MPC512x
  powerpc/mpc512x: improve DIU related clock setup
  clk: mpc512x: remove migration support workarounds
  powerpc/512x: clk: minor comment updates
  powerpc/512x: clk: enforce even SDHC divider values
  powerpc/512x: clk: support MPC5121/5123/5125 SoC variants
  powerpc/512x: dts: add MPC5125 clock specs

 arch/powerpc/Kconfig  |5 -
 arch/powerpc/boot/dts/ac14xx.dts  |7 +
 arch/powerpc/boot/dts/mpc5121.dtsi|  113 ++-
 arch/powerpc/boot/dts/mpc5125twr.dts  |   53 +-
 arch/powerpc/include/asm/clk_interface.h  |   20 -
 arch/powerpc/include/asm/mpc5121.h|7 +-
 arch/powerpc/kernel/Makefile  |1 -
 arch/powerpc/kernel/clock.c   |   82 --
 arch/powerpc/platforms/512x/Kconfig   |2 +-
 arch/powerpc/platforms/512x/Makefile  |3 +-
 arch/powerpc/platforms/512x/clock-commonclk.c | 1221 +
 arch/powerpc/platforms/512x/clock.c   |  754 ---
 arch/powerpc/platforms/512x/mpc512x_shared.c  |  169 ++--
 arch/powerpc/platforms/52xx/Kconfig   |2 +-
 drivers/media/platform/fsl-viu.c  |2 +-
 drivers/mtd/nand/mpc5121_nfc.c|2 +-
 drivers/net/can/mscan/mpc5xxx_can.c   |  270 +++---
 drivers/spi/spi-mpc512x-psc.c |   26 +-
 drivers/tty/serial/mpc52xx_uart.c |   90 +-
 drivers/usb/host/fsl-mph-dr-of.c  |   13 +-
 include/dt-bindings/clock/mpc512x-clock.h |   76 ++
 include/linux/clk-provider.h  |   16 +
 22 files changed, 1840 insertions(+), 1094 deletions(-)
 delete mode 100644 arch/powerpc/include/asm/clk_interface.h
 delete mode 100644 arch/powerpc/kernel/clock.c
 create mode 100644 arch/powerpc/platforms/512x/clock-commonclk.c
 delete mode 100644 arch/powerpc/platforms/512x/clock.c
 create mode 100644 include/dt-bindings/clock/mpc512x-clock.h
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH] drivers/tty/hvc: don't use module_init in non-modular hyp. console code

2014-01-15 Thread Paul Gortmaker
The HVC_OPAL/RTAS/UDBG options are all bool, and hence their support
is either present or absent.  It will never be modular, so using
module_init as an alias for __initcall is rather misleading.

Fix this up now, so that we can relocate module_init from
init.h into module.h in the future.  If we don't do this, we'd
have to add module.h to obviously non-modular code, and that
would be a worse thing.

Note that direct use of __initcall is discouraged, vs. one
of the priority categorized subgroups.  As __initcall gets
mapped onto device_initcall, our use of device_initcall
directly in this change means that the runtime impact is
zero -- it will remain at level 6 in initcall ordering.

Also the __exitcall functions have been outright deleted since
they are only ever of interest to UML, and UML will never be
using any of this code.

Cc: Richard Weinberger rich...@nod.at
Cc: Greg Kroah-Hartman gre...@linuxfoundation.org
Signed-off-by: Paul Gortmaker paul.gortma...@windriver.com

diff --git a/drivers/tty/hvc/hvc_opal.c b/drivers/tty/hvc/hvc_opal.c
index 6496872e2e47..b01659bd4f7c 100644
--- a/drivers/tty/hvc/hvc_opal.c
+++ b/drivers/tty/hvc/hvc_opal.c
@@ -255,13 +255,7 @@ static int __init hvc_opal_init(void)
/* Register as a vio device to receive callbacks */
return platform_driver_register(hvc_opal_driver);
 }
-module_init(hvc_opal_init);
-
-static void __exit hvc_opal_exit(void)
-{
-   platform_driver_unregister(hvc_opal_driver);
-}
-module_exit(hvc_opal_exit);
+device_initcall(hvc_opal_init);
 
 static void udbg_opal_putc(char c)
 {
diff --git a/drivers/tty/hvc/hvc_rtas.c b/drivers/tty/hvc/hvc_rtas.c
index 0069bb86ba49..08c87920b74a 100644
--- a/drivers/tty/hvc/hvc_rtas.c
+++ b/drivers/tty/hvc/hvc_rtas.c
@@ -102,17 +102,7 @@ static int __init hvc_rtas_init(void)
 
return 0;
 }
-module_init(hvc_rtas_init);
-
-/* This will tear down the tty portion of the driver */
-static void __exit hvc_rtas_exit(void)
-{
-   /* Really the fun isn't over until the worker thread breaks down and
-* the tty cleans up */
-   if (hvc_rtas_dev)
-   hvc_remove(hvc_rtas_dev);
-}
-module_exit(hvc_rtas_exit);
+device_initcall(hvc_rtas_init);
 
 /* This will happen prior to module init.  There is no tty at this time? */
 static int __init hvc_rtas_console_init(void)
diff --git a/drivers/tty/hvc/hvc_udbg.c b/drivers/tty/hvc/hvc_udbg.c
index 72228276fe31..9cf573d06a29 100644
--- a/drivers/tty/hvc/hvc_udbg.c
+++ b/drivers/tty/hvc/hvc_udbg.c
@@ -80,14 +80,7 @@ static int __init hvc_udbg_init(void)
 
return 0;
 }
-module_init(hvc_udbg_init);
-
-static void __exit hvc_udbg_exit(void)
-{
-   if (hvc_udbg_dev)
-   hvc_remove(hvc_udbg_dev);
-}
-module_exit(hvc_udbg_exit);
+device_initcall(hvc_udbg_init);
 
 static int __init hvc_udbg_console_init(void)
 {
diff --git a/drivers/tty/hvc/hvc_xen.c b/drivers/tty/hvc/hvc_xen.c
index 636c9baad7a5..2dc2831840ca 100644
--- a/drivers/tty/hvc/hvc_xen.c
+++ b/drivers/tty/hvc/hvc_xen.c
@@ -561,18 +561,7 @@ static int __init xen_hvc_init(void)
 #endif
return r;
 }
-
-static void __exit xen_hvc_fini(void)
-{
-   struct xencons_info *entry, *next;
-
-   if (list_empty(xenconsoles))
-   return;
-
-   list_for_each_entry_safe(entry, next, xenconsoles, list) {
-   xen_console_remove(entry);
-   }
-}
+device_initcall(xen_hvc_init);
 
 static int xen_cons_init(void)
 {
@@ -598,10 +587,6 @@ static int xen_cons_init(void)
hvc_instantiate(HVC_COOKIE, 0, ops);
return 0;
 }
-
-
-module_init(xen_hvc_init);
-module_exit(xen_hvc_fini);
 console_initcall(xen_cons_init);
 
 #ifdef CONFIG_EARLY_PRINTK
-- 
1.8.5.2

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH v2] drivers/tty/hvc: don't use module_init in non-modular hyp. console code

2014-01-15 Thread Paul Gortmaker
The HVC_OPAL/RTAS/UDBG/XEN options are all bool, and hence their support
is either present or absent.  It will never be modular, so using
module_init as an alias for __initcall is rather misleading.

Fix this up now, so that we can relocate module_init from
init.h into module.h in the future.  If we don't do this, we'd
have to add module.h to obviously non-modular code, and that
would be a worse thing.

Note that direct use of __initcall is discouraged, vs. one
of the priority categorized subgroups.  As __initcall gets
mapped onto device_initcall, our use of device_initcall
directly in this change means that the runtime impact is
zero -- it will remain at level 6 in initcall ordering.

Also the __exitcall functions have been outright deleted since
they are only ever of interest to UML, and UML will never be
using any of this code.

Cc: Richard Weinberger rich...@nod.at
Cc: Konrad Rzeszutek Wilk konrad.w...@oracle.com
Cc: Boris Ostrovsky boris.ostrov...@oracle.com
Cc: David Vrabel david.vra...@citrix.com
Cc: Greg Kroah-Hartman gre...@linuxfoundation.org
Signed-off-by: Paul Gortmaker paul.gortma...@windriver.com
---

[v2: unchanged; just added xen guys to Cc list, as hvc_xen isnt
 hooked into the MAINTAINERS file as of yet, so I forgot them.]

diff --git a/drivers/tty/hvc/hvc_opal.c b/drivers/tty/hvc/hvc_opal.c
index 6496872e2e47..b01659bd4f7c 100644
--- a/drivers/tty/hvc/hvc_opal.c
+++ b/drivers/tty/hvc/hvc_opal.c
@@ -255,13 +255,7 @@ static int __init hvc_opal_init(void)
/* Register as a vio device to receive callbacks */
return platform_driver_register(hvc_opal_driver);
 }
-module_init(hvc_opal_init);
-
-static void __exit hvc_opal_exit(void)
-{
-   platform_driver_unregister(hvc_opal_driver);
-}
-module_exit(hvc_opal_exit);
+device_initcall(hvc_opal_init);
 
 static void udbg_opal_putc(char c)
 {
diff --git a/drivers/tty/hvc/hvc_rtas.c b/drivers/tty/hvc/hvc_rtas.c
index 0069bb86ba49..08c87920b74a 100644
--- a/drivers/tty/hvc/hvc_rtas.c
+++ b/drivers/tty/hvc/hvc_rtas.c
@@ -102,17 +102,7 @@ static int __init hvc_rtas_init(void)
 
return 0;
 }
-module_init(hvc_rtas_init);
-
-/* This will tear down the tty portion of the driver */
-static void __exit hvc_rtas_exit(void)
-{
-   /* Really the fun isn't over until the worker thread breaks down and
-* the tty cleans up */
-   if (hvc_rtas_dev)
-   hvc_remove(hvc_rtas_dev);
-}
-module_exit(hvc_rtas_exit);
+device_initcall(hvc_rtas_init);
 
 /* This will happen prior to module init.  There is no tty at this time? */
 static int __init hvc_rtas_console_init(void)
diff --git a/drivers/tty/hvc/hvc_udbg.c b/drivers/tty/hvc/hvc_udbg.c
index 72228276fe31..9cf573d06a29 100644
--- a/drivers/tty/hvc/hvc_udbg.c
+++ b/drivers/tty/hvc/hvc_udbg.c
@@ -80,14 +80,7 @@ static int __init hvc_udbg_init(void)
 
return 0;
 }
-module_init(hvc_udbg_init);
-
-static void __exit hvc_udbg_exit(void)
-{
-   if (hvc_udbg_dev)
-   hvc_remove(hvc_udbg_dev);
-}
-module_exit(hvc_udbg_exit);
+device_initcall(hvc_udbg_init);
 
 static int __init hvc_udbg_console_init(void)
 {
diff --git a/drivers/tty/hvc/hvc_xen.c b/drivers/tty/hvc/hvc_xen.c
index 636c9baad7a5..2dc2831840ca 100644
--- a/drivers/tty/hvc/hvc_xen.c
+++ b/drivers/tty/hvc/hvc_xen.c
@@ -561,18 +561,7 @@ static int __init xen_hvc_init(void)
 #endif
return r;
 }
-
-static void __exit xen_hvc_fini(void)
-{
-   struct xencons_info *entry, *next;
-
-   if (list_empty(xenconsoles))
-   return;
-
-   list_for_each_entry_safe(entry, next, xenconsoles, list) {
-   xen_console_remove(entry);
-   }
-}
+device_initcall(xen_hvc_init);
 
 static int xen_cons_init(void)
 {
@@ -598,10 +587,6 @@ static int xen_cons_init(void)
hvc_instantiate(HVC_COOKIE, 0, ops);
return 0;
 }
-
-
-module_init(xen_hvc_init);
-module_exit(xen_hvc_fini);
 console_initcall(xen_cons_init);
 
 #ifdef CONFIG_EARLY_PRINTK
-- 
1.8.5.2

___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


Re: powerpc/powernv: Call OPAL sync before kexec'ing

2014-01-15 Thread Benjamin Herrenschmidt
On Thu, 2014-01-16 at 11:58 +1100, Michael Ellerman wrote:
 On Wed, 2014-01-15 at 17:02 +1100, Benjamin Herrenschmidt wrote:
  From: Vasant Hegde hegdevas...@linux.vnet.ibm.com
  
  Its possible that OPAL may be writing to host memory during
  kexec (like dump retrieve scenario). In this situation we might
  end up corrupting host memory.
 
 Are we happy with that happening during kdump? (which doesn't call any of the
 shutdown paths)

Obviously not ... There's a problem there. Not sure what the right fix
is. Might need some ifdef KDUMP to take over in the new driver.

Ben.


___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


Re: [PATCH V5 0/8] cpuidle/ppc: Enable deep idle states on PowerNV

2014-01-15 Thread Preeti U Murthy
Hi Paul,

On 01/15/2014 08:59 PM, Paul Gortmaker wrote:
 On 14-01-15 03:07 AM, Preeti U Murthy wrote:
 
 [...]
 

 This patchset is based on mainline commit-id:8ae516aa8b8161254d3,  and the
 
 I figured I'd give this a quick sanity build test for a few
 configs, but v3.13-rc1-141-g8ae516aa8b81 seems too old; Ben's
 ppc next branch is at v3.13-rc1-160-gfac515db4520 and it fails:
 
 ---
 $ git am ppc-idle
 Applying: powerpc: Free up the slot of PPC_MSG_CALL_FUNC_SINGLE IPI message
 Applying: powerpc: Implement tick broadcast IPI as a fixed IPI message
 Applying: cpuidle/ppc: Split timer_interrupt() into timer handling and 
 interrupt handling routines
 error: patch failed: arch/powerpc/kernel/time.c:510
 error: arch/powerpc/kernel/time.c: patch does not apply
 Patch failed at 0003 cpuidle/ppc: Split timer_interrupt() into timer handling 
 and interrupt handling routines
 The copy of the patch that failed is found in:
/home/paul/git/linux-head/.git/rebase-apply/patch
 When you have resolved this problem, run git am --continue.
 If you prefer to skip this patch, run git am --skip instead.
 To restore the original branch and stop patching, run git am --abort.
 $ dry-run
 patching file arch/powerpc/kernel/time.c
 Hunk #3 FAILED at 544.
 Hunk #4 FAILED at 554.
 Hunk #5 succeeded at 862 (offset 12 lines).
 2 out of 5 hunks FAILED -- saving rejects to file 
 arch/powerpc/kernel/time.c.rej
 
 
 It appears to conflict with:
 
 commit 0215f7d8c53fb192cd4491ede0ece5cca6b5db57
 Author: Benjamin Herrenschmidt b...@kernel.crashing.org
 Date:   Tue Jan 14 17:11:39 2014 +1100
 
 powerpc: Fix races with irq_work
 
 

Thanks for the build test.I will base it on the mainline at the latest
commit as well as on Ben's tree and send out this patchset.

Regards
Preeti U Murthy
 Paul.
 --
 
 cpuidle driver for powernv posted by Deepthi Dharwar:
 https://lkml.org/lkml/2014/1/14/172


 Changes in V5:
 -
 The primary change in this version is in Patch[6/8].
 As per the discussions in V4 posting of this patchset, it was decided to
 refine handling the wakeup of CPUs in fast-sleep by doing the following:

 1. In V4, a polling mechanism was used by the CPU handling broadcast to
 find out the time of next wakeup of the CPUs in deep idle states. V5 avoids
 polling by a way described under PATCH[6/8] in this patchset.

 2. The mechanism of broadcast handling of CPUs in deep idle in the absence 
 of an
 external wakeup device should be generic and not arch specific code. Hence 
 in this
 version this functionality has been integrated into the tick broadcast 
 framework in
 the kernel unlike before where it was handled in powerpc specific code.

 3. It was suggested that the broadcast cpu can be the time keeping cpu
 itself. However this has challenges of its own:

  a. The time keeping cpu need not exist when all cpus are idle. Hence there
 are phases in time when time keeping cpu is absent. But for the use case that
 this patchset is trying to address we rely on the presence of a broadcast cpu
 all the time.

  b. The nomination and un-assignment of the time keeping cpu is not protected
 by a lock today and need not be as well since such is its use case in the
 kernel. However we would need locks if we double up the time keeping cpu as 
 the
 broadcast cpu.

 Hence the broadcast cpu is independent of the time-keeping cpu. However 
 PATCH[6/8]
 proposes a simpler solution to pick a broadcast cpu in this version.



 Changes in V4:
 -
 https://lkml.org/lkml/2013/11/29/97

 1. Add Fast Sleep CPU idle state on PowerNV.

 2. Add the required context management for Fast Sleep and the call to OPAL
 to synchronize time base after wakeup from fast sleep.

 4. Add parsing of CPU idle states from the device tree to populate the
 cpuidle
 state table.

 5. Rename ambiguous functions in the code around waking up of CPUs from fast
 sleep.

 6. Fixed a bug in re-programming of the hrtimer that is queued to wakeup the
 CPUs in fast sleep and modified Changelogs.

 7. Added the ARCH_HAS_TICK_BROADCAST option. This signifies that we have a
 arch specific function to perform broadcast.


 Changes in V3:
 -
 http://thread.gmane.org/gmane.linux.power-management.general/38113

 1. Fix the way in which a broadcast ipi is handled on the idling cpus. Timer
 handling on a broadcast ipi is being done now without missing out any timer
 stats generation.

 2. Fix a bug in the programming of the hrtimer meant to do broadcast. Program
 it to trigger at the earlier of a broadcast period, and the next wakeup
 event. By introducing the broadcast period as the maximum period after
 which the broadcast hrtimer can fire, we ensure that we do not miss
 wakeups in corner cases.

 3. On hotplug of a broadcast cpu, trigger the hrtimer meant to do broadcast
 to fire immediately on the new broadcast cpu. This will ensure we do not miss
 doing a broadcast pending in the nearest future.

 4. Change the type of allocation from 

Re: [PATCH 3/3] powerpc/fsl: Use the new interface to save or restore registers

2014-01-15 Thread Scott Wood
On Tue, 2014-01-14 at 20:57 -0600, Wang Dongsheng-B40534 wrote:
 
  -Original Message-
  From: Wood Scott-B07421
  Sent: Wednesday, January 15, 2014 7:30 AM
  To: Wang Dongsheng-B40534
  Cc: b...@kernel.crashing.org; Zhao Chenhui-B35336; an...@enomsg.org; 
  linuxppc-
  d...@lists.ozlabs.org
  Subject: Re: [PATCH 3/3] powerpc/fsl: Use the new interface to save or 
  restore
  registers
  
  On Tue, 2014-01-14 at 15:59 +0800, Dongsheng Wang wrote:
   From: Wang Dongsheng dongsheng.w...@freescale.com
  
   Use fsl_cpu_state_save/fsl_cpu_state_restore to save/restore registers.
   Use the functions to save/restore registers, so we don't need to
   maintain the code.
  
   Signed-off-by: Wang Dongsheng dongsheng.w...@freescale.com
  
  Is there any functional change with this patchset (e.g. suspend
  supported on chips where it wasn't before), or is it just cleanup?  A
  cover letter would be useful to describe the purpose of the overall
  patchset when it isn't obvious.
  
 
 Yes, just cleanup..

It seems to be introducing complexity rather than removing it.  Is this
cleanup needed to prepare for adding new functionality?

Plus, I'm skeptical that this is functionally equivalent.  It looks like
the new code saves a lot more than the old code does.  Why?

   +
   + /* Restore base register */
   + li  r4, 0
   + bl  fsl_cpu_state_restore
  
  Why are you calling anything with fsl in the name from code that is
  supposed to be for all booke?
  
 E200, E300 not support.
 Support E500, E500v2, E500MC, E5500, E6500.
 
 Do you have any suggestions about this?

What about non-FSL booke such as 44x?

Or if this file never supported 44x, rename it appropriately.

-Scott


___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


Re: [PATCH 2/3] powerpc/85xx: Provide two functions to save/restore the core registers

2014-01-15 Thread Scott Wood
On Tue, 2014-01-14 at 21:30 -0600, Wang Dongsheng-B40534 wrote:
 
  -Original Message-
  From: Wood Scott-B07421
  Sent: Wednesday, January 15, 2014 7:51 AM
  To: Wang Dongsheng-B40534
  Cc: b...@kernel.crashing.org; Zhao Chenhui-B35336; an...@enomsg.org; 
  linuxppc-
  d...@lists.ozlabs.org
  Subject: Re: [PATCH 2/3] powerpc/85xx: Provide two functions to 
  save/restore the
  core registers
  
  On Tue, 2014-01-14 at 15:59 +0800, Dongsheng Wang wrote:
   From: Wang Dongsheng dongsheng.w...@freescale.com
  
   Add fsl_cpu_state_save/fsl_cpu_state_restore functions, used for deep
   sleep and hibernation to save/restore core registers. We abstract out
   save/restore code for use in various modules, to make them don't need
   to maintain.
  
   Currently supported processors type are E6500, E5500, E500MC, E500v2
   and E500v1.
  
   Signed-off-by: Wang Dongsheng dongsheng.w...@freescale.com
  
  What is there that is specfic to a particular core type that can't be 
  handled
  from C code?
  
 
 In the context of the calling, maybe not in C environment.(Deep sleep without
 C environment when calling those interfaces)

Could you provide a concrete example?

   + /*
   +  * Need to save float-point registers if MSR[FP] = 1.
   +  */
   + mfmsr   r12
   + andi.   r12, r12, MSR_FP
   + beq 1f
   + do_sr_fpr_regs(save)
  
  C code should have already ensured that MSR[FP] is not 1 (and thus the FP
  context has been saved).
  
 
 Yes, right. But I mean if the FP still use in core save flow, we need to save 
 it.
 In this process, i don't care what other code do, we need to focus on not 
 losing
 valuable data.

It is not allowed to use FP at that point.

-Scott


___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH 2/2][v3] powerpc/config: Enable memory driver

2014-01-15 Thread Prabhakar Kushwaha
As Freescale IFC controller has been moved to driver to driver/memory.

So enable memory driver in powerpc config

Signed-off-by: Prabhakar Kushwaha prabha...@freescale.com
---
 Changes for v2: Sending as it is
 Changes for v3: Sending as it is

 arch/powerpc/configs/corenet32_smp_defconfig |1 +
 arch/powerpc/configs/corenet64_smp_defconfig |1 +
 arch/powerpc/configs/mpc85xx_defconfig   |1 +
 arch/powerpc/configs/mpc85xx_smp_defconfig   |1 +
 4 files changed, 4 insertions(+)

diff --git a/arch/powerpc/configs/corenet32_smp_defconfig 
b/arch/powerpc/configs/corenet32_smp_defconfig
index bbd794d..087d437 100644
--- a/arch/powerpc/configs/corenet32_smp_defconfig
+++ b/arch/powerpc/configs/corenet32_smp_defconfig
@@ -142,6 +142,7 @@ CONFIG_RTC_DRV_DS3232=y
 CONFIG_RTC_DRV_CMOS=y
 CONFIG_UIO=y
 CONFIG_STAGING=y
+CONFIG_MEMORY=y
 CONFIG_VIRT_DRIVERS=y
 CONFIG_FSL_HV_MANAGER=y
 CONFIG_EXT2_FS=y
diff --git a/arch/powerpc/configs/corenet64_smp_defconfig 
b/arch/powerpc/configs/corenet64_smp_defconfig
index 63508dd..25b03f8 100644
--- a/arch/powerpc/configs/corenet64_smp_defconfig
+++ b/arch/powerpc/configs/corenet64_smp_defconfig
@@ -129,6 +129,7 @@ CONFIG_EDAC=y
 CONFIG_EDAC_MM_EDAC=y
 CONFIG_DMADEVICES=y
 CONFIG_FSL_DMA=y
+CONFIG_MEMORY=y
 CONFIG_EXT2_FS=y
 CONFIG_EXT3_FS=y
 CONFIG_ISO9660_FS=m
diff --git a/arch/powerpc/configs/mpc85xx_defconfig 
b/arch/powerpc/configs/mpc85xx_defconfig
index d2e0fab..87aad6d 100644
--- a/arch/powerpc/configs/mpc85xx_defconfig
+++ b/arch/powerpc/configs/mpc85xx_defconfig
@@ -213,6 +213,7 @@ CONFIG_RTC_CLASS=y
 CONFIG_RTC_DRV_CMOS=y
 CONFIG_DMADEVICES=y
 CONFIG_FSL_DMA=y
+CONFIG_MEMORY=y
 # CONFIG_NET_DMA is not set
 CONFIG_EXT2_FS=y
 CONFIG_EXT3_FS=y
diff --git a/arch/powerpc/configs/mpc85xx_smp_defconfig 
b/arch/powerpc/configs/mpc85xx_smp_defconfig
index 4cb7b59..d5d6915 100644
--- a/arch/powerpc/configs/mpc85xx_smp_defconfig
+++ b/arch/powerpc/configs/mpc85xx_smp_defconfig
@@ -214,6 +214,7 @@ CONFIG_RTC_CLASS=y
 CONFIG_RTC_DRV_CMOS=y
 CONFIG_DMADEVICES=y
 CONFIG_FSL_DMA=y
+CONFIG_MEMORY=y
 # CONFIG_NET_DMA is not set
 CONFIG_EXT2_FS=y
 CONFIG_EXT3_FS=y
-- 
1.7.9.5



___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH 0/7] DMA: Freescale: driver cleanups and enhancements

2014-01-15 Thread hongbo.zhang
From: Hongbo Zhang hongbo.zh...@freescale.com

Hi Vinod Koul and Dan Williams,
Please have a look at these patches.

Note that patch 2~6 had beed sent out for upstream before, but were together
with other storage patches at that time, that was not easy for being reviewed
and merged, so I send them separately this time.

Thanks.

Hongbo Zhang (7):
  DMA: Freescale: unify register access methods
  DMA: Freescale: remove attribute DMA_INTERRUPT of dmaengine
  DMA: Freescale: add fsl_dma_free_descriptor() to reduce code
duplication
  DMA: Freescale: move functions to avoid forward declarations
  DMA: Freescale: change descriptor release process for supporting
async_tx
  DMA: Freescale: use spin_lock_bh instead of spin_lock_irqsave
  DMA: Freescale: add suspend resume functions for DMA driver

 drivers/dma/fsldma.c |  592 --
 drivers/dma/fsldma.h |   33 ++-
 2 files changed, 412 insertions(+), 213 deletions(-)

-- 
1.7.9.5



___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH 2/7] DMA: Freescale: remove attribute DMA_INTERRUPT of dmaengine

2014-01-15 Thread hongbo.zhang
From: Hongbo Zhang hongbo.zh...@freescale.com

Delete attribute DMA_INTERRUPT because fsldma doesn't support this function,
exception will be thrown if talitos is used to offload xor at the same time.

Signed-off-by: Hongbo Zhang hongbo.zh...@freescale.com
Signed-off-by: Qiang Liu qiang@freescale.com
---
 drivers/dma/fsldma.c |   31 ---
 1 file changed, 31 deletions(-)

diff --git a/drivers/dma/fsldma.c b/drivers/dma/fsldma.c
index fbf19d3..95236e6 100644
--- a/drivers/dma/fsldma.c
+++ b/drivers/dma/fsldma.c
@@ -534,35 +534,6 @@ static void fsl_dma_free_chan_resources(struct dma_chan 
*dchan)
 }
 
 static struct dma_async_tx_descriptor *
-fsl_dma_prep_interrupt(struct dma_chan *dchan, unsigned long flags)
-{
-   struct fsldma_chan *chan;
-   struct fsl_desc_sw *new;
-
-   if (!dchan)
-   return NULL;
-
-   chan = to_fsl_chan(dchan);
-
-   new = fsl_dma_alloc_descriptor(chan);
-   if (!new) {
-   chan_err(chan, %s\n, msg_ld_oom);
-   return NULL;
-   }
-
-   new-async_tx.cookie = -EBUSY;
-   new-async_tx.flags = flags;
-
-   /* Insert the link descriptor to the LD ring */
-   list_add_tail(new-node, new-tx_list);
-
-   /* Set End-of-link to the last link descriptor of new list */
-   set_ld_eol(chan, new);
-
-   return new-async_tx;
-}
-
-static struct dma_async_tx_descriptor *
 fsl_dma_prep_memcpy(struct dma_chan *dchan,
dma_addr_t dma_dst, dma_addr_t dma_src,
size_t len, unsigned long flags)
@@ -1318,12 +1289,10 @@ static int fsldma_of_probe(struct platform_device *op)
fdev-irq = irq_of_parse_and_map(op-dev.of_node, 0);
 
dma_cap_set(DMA_MEMCPY, fdev-common.cap_mask);
-   dma_cap_set(DMA_INTERRUPT, fdev-common.cap_mask);
dma_cap_set(DMA_SG, fdev-common.cap_mask);
dma_cap_set(DMA_SLAVE, fdev-common.cap_mask);
fdev-common.device_alloc_chan_resources = fsl_dma_alloc_chan_resources;
fdev-common.device_free_chan_resources = fsl_dma_free_chan_resources;
-   fdev-common.device_prep_dma_interrupt = fsl_dma_prep_interrupt;
fdev-common.device_prep_dma_memcpy = fsl_dma_prep_memcpy;
fdev-common.device_prep_dma_sg = fsl_dma_prep_sg;
fdev-common.device_tx_status = fsl_tx_status;
-- 
1.7.9.5



___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH 3/7] DMA: Freescale: add fsl_dma_free_descriptor() to reduce code duplication

2014-01-15 Thread hongbo.zhang
From: Hongbo Zhang hongbo.zh...@freescale.com

There are several places where descriptors are freed using identical code.
This patch puts this code into a function to reduce code duplication.

Signed-off-by: Hongbo Zhang hongbo.zh...@freescale.com
Signed-off-by: Qiang Liu qiang@freescale.com
---
 drivers/dma/fsldma.c |   38 --
 1 file changed, 20 insertions(+), 18 deletions(-)

diff --git a/drivers/dma/fsldma.c b/drivers/dma/fsldma.c
index 95236e6..ad73538 100644
--- a/drivers/dma/fsldma.c
+++ b/drivers/dma/fsldma.c
@@ -418,6 +418,21 @@ static dma_cookie_t fsl_dma_tx_submit(struct 
dma_async_tx_descriptor *tx)
 }
 
 /**
+ * fsl_dma_free_descriptor - Free descriptor from channel's DMA pool.
+ * @chan : Freescale DMA channel
+ * @desc: descriptor to be freed
+ */
+static void fsl_dma_free_descriptor(struct fsldma_chan *chan,
+   struct fsl_desc_sw *desc)
+{
+   list_del(desc-node);
+#ifdef FSL_DMA_LD_DEBUG
+   chan_dbg(chan, LD %p free\n, desc);
+#endif
+   dma_pool_free(chan-desc_pool, desc, desc-async_tx.phys);
+}
+
+/**
  * fsl_dma_alloc_descriptor - Allocate descriptor from channel's DMA pool.
  * @chan : Freescale DMA channel
  *
@@ -491,13 +506,8 @@ static void fsldma_free_desc_list(struct fsldma_chan *chan,
 {
struct fsl_desc_sw *desc, *_desc;
 
-   list_for_each_entry_safe(desc, _desc, list, node) {
-   list_del(desc-node);
-#ifdef FSL_DMA_LD_DEBUG
-   chan_dbg(chan, LD %p free\n, desc);
-#endif
-   dma_pool_free(chan-desc_pool, desc, desc-async_tx.phys);
-   }
+   list_for_each_entry_safe(desc, _desc, list, node)
+   fsl_dma_free_descriptor(chan, desc);
 }
 
 static void fsldma_free_desc_list_reverse(struct fsldma_chan *chan,
@@ -505,13 +515,8 @@ static void fsldma_free_desc_list_reverse(struct 
fsldma_chan *chan,
 {
struct fsl_desc_sw *desc, *_desc;
 
-   list_for_each_entry_safe_reverse(desc, _desc, list, node) {
-   list_del(desc-node);
-#ifdef FSL_DMA_LD_DEBUG
-   chan_dbg(chan, LD %p free\n, desc);
-#endif
-   dma_pool_free(chan-desc_pool, desc, desc-async_tx.phys);
-   }
+   list_for_each_entry_safe_reverse(desc, _desc, list, node)
+   fsl_dma_free_descriptor(chan, desc);
 }
 
 /**
@@ -827,10 +832,7 @@ static void fsldma_cleanup_descriptor(struct fsldma_chan 
*chan,
dma_run_dependencies(txd);
 
dma_descriptor_unmap(txd);
-#ifdef FSL_DMA_LD_DEBUG
-   chan_dbg(chan, LD %p free\n, desc);
-#endif
-   dma_pool_free(chan-desc_pool, desc, txd-phys);
+   fsl_dma_free_descriptor(chan, desc);
 }
 
 /**
-- 
1.7.9.5



___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH 1/7] DMA: Freescale: unify register access methods

2014-01-15 Thread hongbo.zhang
From: Hongbo Zhang hongbo.zh...@freescale.com

Methods of accessing DMA contorller registers are inconsistent, some registers
are accessed by DMA_IN/OUT directly, while others are accessed by functions
get/set_* which are wrappers of DMA_IN/OUT, and even for the BCR register, it
is read by get_bcr but written by DMA_OUT.
This patch unifies the inconsistent methods, all registers are accessed by
get/set_* now.

Signed-off-by: Hongbo Zhang hongbo.zh...@freescale.com
---
 drivers/dma/fsldma.c |   52 --
 1 file changed, 33 insertions(+), 19 deletions(-)

diff --git a/drivers/dma/fsldma.c b/drivers/dma/fsldma.c
index f157c6f..fbf19d3 100644
--- a/drivers/dma/fsldma.c
+++ b/drivers/dma/fsldma.c
@@ -61,6 +61,16 @@ static u32 get_sr(struct fsldma_chan *chan)
return DMA_IN(chan, chan-regs-sr, 32);
 }
 
+static void set_mr(struct fsldma_chan *chan, u32 val)
+{
+   DMA_OUT(chan, chan-regs-mr, val, 32);
+}
+
+static u32 get_mr(struct fsldma_chan *chan)
+{
+   return DMA_IN(chan, chan-regs-mr, 32);
+}
+
 static void set_cdar(struct fsldma_chan *chan, dma_addr_t addr)
 {
DMA_OUT(chan, chan-regs-cdar, addr | FSL_DMA_SNEN, 64);
@@ -71,6 +81,11 @@ static dma_addr_t get_cdar(struct fsldma_chan *chan)
return DMA_IN(chan, chan-regs-cdar, 64)  ~FSL_DMA_SNEN;
 }
 
+static void set_bcr(struct fsldma_chan *chan, u32 val)
+{
+   DMA_OUT(chan, chan-regs-bcr, val, 32);
+}
+
 static u32 get_bcr(struct fsldma_chan *chan)
 {
return DMA_IN(chan, chan-regs-bcr, 32);
@@ -135,7 +150,7 @@ static void set_ld_eol(struct fsldma_chan *chan, struct 
fsl_desc_sw *desc)
 static void dma_init(struct fsldma_chan *chan)
 {
/* Reset the channel */
-   DMA_OUT(chan, chan-regs-mr, 0, 32);
+   set_mr(chan, 0);
 
switch (chan-feature  FSL_DMA_IP_MASK) {
case FSL_DMA_IP_85XX:
@@ -144,16 +159,15 @@ static void dma_init(struct fsldma_chan *chan)
 * EOLNIE - End of links interrupt enable
 * BWC - Bandwidth sharing among channels
 */
-   DMA_OUT(chan, chan-regs-mr, FSL_DMA_MR_BWC
-   | FSL_DMA_MR_EIE | FSL_DMA_MR_EOLNIE, 32);
+   set_mr(chan, FSL_DMA_MR_BWC | FSL_DMA_MR_EIE
+   | FSL_DMA_MR_EOLNIE);
break;
case FSL_DMA_IP_83XX:
/* Set the channel to below modes:
 * EOTIE - End-of-transfer interrupt enable
 * PRC_RM - PCI read multiple
 */
-   DMA_OUT(chan, chan-regs-mr, FSL_DMA_MR_EOTIE
-   | FSL_DMA_MR_PRC_RM, 32);
+   set_mr(chan, FSL_DMA_MR_EOTIE | FSL_DMA_MR_PRC_RM);
break;
}
 }
@@ -175,10 +189,10 @@ static void dma_start(struct fsldma_chan *chan)
 {
u32 mode;
 
-   mode = DMA_IN(chan, chan-regs-mr, 32);
+   mode = get_mr(chan);
 
if (chan-feature  FSL_DMA_CHAN_PAUSE_EXT) {
-   DMA_OUT(chan, chan-regs-bcr, 0, 32);
+   set_bcr(chan, 0);
mode |= FSL_DMA_MR_EMP_EN;
} else {
mode = ~FSL_DMA_MR_EMP_EN;
@@ -191,7 +205,7 @@ static void dma_start(struct fsldma_chan *chan)
mode |= FSL_DMA_MR_CS;
}
 
-   DMA_OUT(chan, chan-regs-mr, mode, 32);
+   set_mr(chan, mode);
 }
 
 static void dma_halt(struct fsldma_chan *chan)
@@ -200,7 +214,7 @@ static void dma_halt(struct fsldma_chan *chan)
int i;
 
/* read the mode register */
-   mode = DMA_IN(chan, chan-regs-mr, 32);
+   mode = get_mr(chan);
 
/*
 * The 85xx controller supports channel abort, which will stop
@@ -209,14 +223,14 @@ static void dma_halt(struct fsldma_chan *chan)
 */
if ((chan-feature  FSL_DMA_IP_MASK) == FSL_DMA_IP_85XX) {
mode |= FSL_DMA_MR_CA;
-   DMA_OUT(chan, chan-regs-mr, mode, 32);
+   set_mr(chan, mode);
 
mode = ~FSL_DMA_MR_CA;
}
 
/* stop the DMA controller */
mode = ~(FSL_DMA_MR_CS | FSL_DMA_MR_EMS_EN);
-   DMA_OUT(chan, chan-regs-mr, mode, 32);
+   set_mr(chan, mode);
 
/* wait for the DMA controller to become idle */
for (i = 0; i  100; i++) {
@@ -245,7 +259,7 @@ static void fsl_chan_set_src_loop_size(struct fsldma_chan 
*chan, int size)
 {
u32 mode;
 
-   mode = DMA_IN(chan, chan-regs-mr, 32);
+   mode = get_mr(chan);
 
switch (size) {
case 0:
@@ -259,7 +273,7 @@ static void fsl_chan_set_src_loop_size(struct fsldma_chan 
*chan, int size)
break;
}
 
-   DMA_OUT(chan, chan-regs-mr, mode, 32);
+   set_mr(chan, mode);
 }
 
 /**
@@ -277,7 +291,7 @@ static void fsl_chan_set_dst_loop_size(struct fsldma_chan 
*chan, int size)
 {
u32 mode;
 
-   mode = DMA_IN(chan, chan-regs-mr, 32);
+   mode = get_mr(chan);
 
switch (size) {
case 

[PATCH 6/7] DMA: Freescale: use spin_lock_bh instead of spin_lock_irqsave

2014-01-15 Thread hongbo.zhang
From: Hongbo Zhang hongbo.zh...@freescale.com

The usage of spin_lock_irqsave() is a stronger locking mechanism than is
required throughout the driver. The minimum locking required should be used
instead. Interrupts will be turned off and context will be saved, it is
unnecessary to use irqsave.

This patch changes all instances of spin_lock_irqsave() to spin_lock_bh(). All
manipulation of protected fields is done using tasklet context or weaker, which
makes spin_lock_bh() the correct choice.

Signed-off-by: Hongbo Zhang hongbo.zh...@freescale.com
Signed-off-by: Qiang Liu qiang@freescale.com
---
 drivers/dma/fsldma.c |   25 ++---
 1 file changed, 10 insertions(+), 15 deletions(-)

diff --git a/drivers/dma/fsldma.c b/drivers/dma/fsldma.c
index bbace54..437794e 100644
--- a/drivers/dma/fsldma.c
+++ b/drivers/dma/fsldma.c
@@ -396,10 +396,9 @@ static dma_cookie_t fsl_dma_tx_submit(struct 
dma_async_tx_descriptor *tx)
struct fsldma_chan *chan = to_fsl_chan(tx-chan);
struct fsl_desc_sw *desc = tx_to_fsl_desc(tx);
struct fsl_desc_sw *child;
-   unsigned long flags;
dma_cookie_t cookie = -EINVAL;
 
-   spin_lock_irqsave(chan-desc_lock, flags);
+   spin_lock_bh(chan-desc_lock);
 
/*
 * assign cookies to all of the software descriptors
@@ -412,7 +411,7 @@ static dma_cookie_t fsl_dma_tx_submit(struct 
dma_async_tx_descriptor *tx)
/* put this transaction onto the tail of the pending queue */
append_ld_queue(chan, desc);
 
-   spin_unlock_irqrestore(chan-desc_lock, flags);
+   spin_unlock_bh(chan-desc_lock);
 
return cookie;
 }
@@ -731,15 +730,14 @@ static void fsldma_free_desc_list_reverse(struct 
fsldma_chan *chan,
 static void fsl_dma_free_chan_resources(struct dma_chan *dchan)
 {
struct fsldma_chan *chan = to_fsl_chan(dchan);
-   unsigned long flags;
 
chan_dbg(chan, free all channel resources\n);
-   spin_lock_irqsave(chan-desc_lock, flags);
+   spin_lock_bh(chan-desc_lock);
fsldma_cleanup_descriptors(chan);
fsldma_free_desc_list(chan, chan-ld_pending);
fsldma_free_desc_list(chan, chan-ld_running);
fsldma_free_desc_list(chan, chan-ld_completed);
-   spin_unlock_irqrestore(chan-desc_lock, flags);
+   spin_unlock_bh(chan-desc_lock);
 
dma_pool_destroy(chan-desc_pool);
chan-desc_pool = NULL;
@@ -958,7 +956,6 @@ static int fsl_dma_device_control(struct dma_chan *dchan,
 {
struct dma_slave_config *config;
struct fsldma_chan *chan;
-   unsigned long flags;
int size;
 
if (!dchan)
@@ -968,7 +965,7 @@ static int fsl_dma_device_control(struct dma_chan *dchan,
 
switch (cmd) {
case DMA_TERMINATE_ALL:
-   spin_lock_irqsave(chan-desc_lock, flags);
+   spin_lock_bh(chan-desc_lock);
 
/* Halt the DMA engine */
dma_halt(chan);
@@ -979,7 +976,7 @@ static int fsl_dma_device_control(struct dma_chan *dchan,
fsldma_free_desc_list(chan, chan-ld_completed);
chan-idle = true;
 
-   spin_unlock_irqrestore(chan-desc_lock, flags);
+   spin_unlock_bh(chan-desc_lock);
return 0;
 
case DMA_SLAVE_CONFIG:
@@ -1021,11 +1018,10 @@ static int fsl_dma_device_control(struct dma_chan 
*dchan,
 static void fsl_dma_memcpy_issue_pending(struct dma_chan *dchan)
 {
struct fsldma_chan *chan = to_fsl_chan(dchan);
-   unsigned long flags;
 
-   spin_lock_irqsave(chan-desc_lock, flags);
+   spin_lock_bh(chan-desc_lock);
fsl_chan_xfer_ld_queue(chan);
-   spin_unlock_irqrestore(chan-desc_lock, flags);
+   spin_unlock_bh(chan-desc_lock);
 }
 
 /**
@@ -1124,11 +1120,10 @@ static irqreturn_t fsldma_chan_irq(int irq, void *data)
 static void dma_do_tasklet(unsigned long data)
 {
struct fsldma_chan *chan = (struct fsldma_chan *)data;
-   unsigned long flags;
 
chan_dbg(chan, tasklet entry\n);
 
-   spin_lock_irqsave(chan-desc_lock, flags);
+   spin_lock_bh(chan-desc_lock);
 
/* the hardware is now idle and ready for more */
chan-idle = true;
@@ -1136,7 +1131,7 @@ static void dma_do_tasklet(unsigned long data)
/* Run all cleanup for descriptors which have been completed */
fsldma_cleanup_descriptors(chan);
 
-   spin_unlock_irqrestore(chan-desc_lock, flags);
+   spin_unlock_bh(chan-desc_lock);
 
chan_dbg(chan, tasklet exit\n);
 }
-- 
1.7.9.5



___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH 4/7] DMA: Freescale: move functions to avoid forward declarations

2014-01-15 Thread hongbo.zhang
From: Hongbo Zhang hongbo.zh...@freescale.com

These functions will be modified in the next patch in the series. By moving the
function in a patch separate from the changes, it will make review easier.

Signed-off-by: Hongbo Zhang hongbo.zh...@freescale.com
Signed-off-by: Qiang Liu qiang@freescale.com
---
 drivers/dma/fsldma.c |  192 +-
 1 file changed, 96 insertions(+), 96 deletions(-)

diff --git a/drivers/dma/fsldma.c b/drivers/dma/fsldma.c
index ad73538..7b6fd3c 100644
--- a/drivers/dma/fsldma.c
+++ b/drivers/dma/fsldma.c
@@ -463,6 +463,102 @@ static struct fsl_desc_sw 
*fsl_dma_alloc_descriptor(struct fsldma_chan *chan)
 }
 
 /**
+ * fsl_chan_xfer_ld_queue - transfer any pending transactions
+ * @chan : Freescale DMA channel
+ *
+ * HARDWARE STATE: idle
+ * LOCKING: must hold chan-desc_lock
+ */
+static void fsl_chan_xfer_ld_queue(struct fsldma_chan *chan)
+{
+   struct fsl_desc_sw *desc;
+
+   /*
+* If the list of pending descriptors is empty, then we
+* don't need to do any work at all
+*/
+   if (list_empty(chan-ld_pending)) {
+   chan_dbg(chan, no pending LDs\n);
+   return;
+   }
+
+   /*
+* The DMA controller is not idle, which means that the interrupt
+* handler will start any queued transactions when it runs after
+* this transaction finishes
+*/
+   if (!chan-idle) {
+   chan_dbg(chan, DMA controller still busy\n);
+   return;
+   }
+
+   /*
+* If there are some link descriptors which have not been
+* transferred, we need to start the controller
+*/
+
+   /*
+* Move all elements from the queue of pending transactions
+* onto the list of running transactions
+*/
+   chan_dbg(chan, idle, starting controller\n);
+   desc = list_first_entry(chan-ld_pending, struct fsl_desc_sw, node);
+   list_splice_tail_init(chan-ld_pending, chan-ld_running);
+
+   /*
+* The 85xx DMA controller doesn't clear the channel start bit
+* automatically at the end of a transfer. Therefore we must clear
+* it in software before starting the transfer.
+*/
+   if ((chan-feature  FSL_DMA_IP_MASK) == FSL_DMA_IP_85XX) {
+   u32 mode;
+
+   mode = get_mr(chan);
+   mode = ~FSL_DMA_MR_CS;
+   set_mr(chan, mode);
+   }
+
+   /*
+* Program the descriptor's address into the DMA controller,
+* then start the DMA transaction
+*/
+   set_cdar(chan, desc-async_tx.phys);
+   get_cdar(chan);
+
+   dma_start(chan);
+   chan-idle = false;
+}
+
+/**
+ * fsldma_cleanup_descriptor - cleanup and free a single link descriptor
+ * @chan: Freescale DMA channel
+ * @desc: descriptor to cleanup and free
+ *
+ * This function is used on a descriptor which has been executed by the DMA
+ * controller. It will run any callbacks, submit any dependencies, and then
+ * free the descriptor.
+ */
+static void fsldma_cleanup_descriptor(struct fsldma_chan *chan,
+ struct fsl_desc_sw *desc)
+{
+   struct dma_async_tx_descriptor *txd = desc-async_tx;
+
+   /* Run the link descriptor callback function */
+   if (txd-callback) {
+#ifdef FSL_DMA_LD_DEBUG
+   chan_dbg(chan, LD %p callback\n, desc);
+#endif
+   txd-callback(txd-callback_param);
+   }
+
+   /* Run any dependencies */
+   dma_run_dependencies(txd);
+
+   dma_descriptor_unmap(txd);
+   fsl_dma_free_descriptor(chan, desc);
+}
+
+/**
  * fsl_dma_alloc_chan_resources - Allocate resources for DMA channel.
  * @chan : Freescale DMA channel
  *
@@ -807,102 +903,6 @@ static int fsl_dma_device_control(struct dma_chan *dchan,
 }
 
 /**
- * fsldma_cleanup_descriptor - cleanup and free a single link descriptor
- * @chan: Freescale DMA channel
- * @desc: descriptor to cleanup and free
- *
- * This function is used on a descriptor which has been executed by the DMA
- * controller. It will run any callbacks, submit any dependencies, and then
- * free the descriptor.
- */
-static void fsldma_cleanup_descriptor(struct fsldma_chan *chan,
- struct fsl_desc_sw *desc)
-{
-   struct dma_async_tx_descriptor *txd = desc-async_tx;
-
-   /* Run the link descriptor callback function */
-   if (txd-callback) {
-#ifdef FSL_DMA_LD_DEBUG
-   chan_dbg(chan, LD %p callback\n, desc);
-#endif
-   txd-callback(txd-callback_param);
-   }
-
-   /* Run any dependencies */
-   dma_run_dependencies(txd);
-
-   dma_descriptor_unmap(txd);
-   fsl_dma_free_descriptor(chan, desc);
-}
-
-/**
- * fsl_chan_xfer_ld_queue - transfer any pending transactions
- * @chan : Freescale DMA channel
- *
- * HARDWARE STATE: idle
- * LOCKING: must hold chan-desc_lock
- */
-static void 

[PATCH 5/7] DMA: Freescale: change descriptor release process for supporting async_tx

2014-01-15 Thread hongbo.zhang
From: Hongbo Zhang hongbo.zh...@freescale.com

Fix the potential risk when enable config NET_DMA and ASYNC_TX. Async_tx is
lack of support in current release process of dma descriptor, all descriptors
will be released whatever is acked or no-acked by async_tx, so there is a
potential race condition when dma engine is uesd by others clients (e.g. when
enable NET_DMA to offload TCP).

In our case, a race condition which is raised when use both of talitos and
dmaengine to offload xor is because napi scheduler will sync all pending
requests in dma channels, it affects the process of raid operations due to
ack_tx is not checked in fsl dma. The no-acked descriptor is freed which is
submitted just now, as a dependent tx, this freed descriptor trigger
BUG_ON(async_tx_test_ack(depend_tx)) in async_tx_submit().

TASK = ee1a94a0[1390] 'md0_raid5' THREAD: ecf4 CPU: 0
GPR00: 0001 ecf41ca0 ee44/921a94a0 003f 0001 c00593e4  
0001
GPR08:  a7a7a7a7 0001 045/92002 42028042 100a38d4 ed576d98 

GPR16: ed5a11b0  2b162000 0200 046/92000 2d555000 ed3015e8 
c15a7aa0
GPR24:  c155fc40  ecb63220 ecf41d28 e47/92f640bb0 ef640c30 
ecf41ca0
NIP [c02b048c] async_tx_submit+0x6c/0x2b4
LR [c02b068c] async_tx_submit+0x26c/0x2b4
Call Trace:
[ecf41ca0] [c02b068c] async_tx_submit+0x26c/0x2b448/92 (unreliable)
[ecf41cd0] [c02b0a4c] async_memcpy+0x240/0x25c
[ecf41d20] [c0421064] async_copy_data+0xa0/0x17c
[ecf41d70] [c0421cf4] __raid_run_ops+0x874/0xe10
[ecf41df0] [c0426ee4] handle_stripe+0x820/0x25e8
[ecf41e90] [c0429080] raid5d+0x3d4/0x5b4
[ecf41f40] [c04329b8] md_thread+0x138/0x16c
[ecf41f90] [c008277c] kthread+0x8c/0x90
[ecf41ff0] [c0011630] kernel_thread+0x4c/0x68

Another modification in this patch is the change of completed descriptors,
there is a potential risk which caused by exception interrupt, all descriptors
in ld_running list are seemed completed when an interrupt raised, it works fine
under normal condition, but if there is an exception occured, it cannot work as
our excepted. Hardware should not be depend on s/w list, the right way is to
read current descriptor address register to find the last completed descriptor.
If an interrupt is raised by an error, all descriptors in ld_running should not
be seemed finished, or these unfinished descriptors in ld_running will be
released wrongly.

A simple way to reproduce:
Enable dmatest first, then insert some bad descriptors which can trigger
Programming Error interrupts before the good descriptors. Last, the good
descriptors will be freed before they are processsed because of the exception
intrerrupt.

Note: the bad descriptors are only for simulating an exception interrupt.  This
case can illustrate the potential risk in current fsl-dma very well.

Signed-off-by: Hongbo Zhang hongbo.zh...@freescale.com
Signed-off-by: Qiang Liu qiang@freescale.com
Signed-off-by: Ira W. Snyder i...@ovro.caltech.edu
---
 drivers/dma/fsldma.c |  199 --
 drivers/dma/fsldma.h |   17 -
 2 files changed, 160 insertions(+), 56 deletions(-)

diff --git a/drivers/dma/fsldma.c b/drivers/dma/fsldma.c
index 7b6fd3c..bbace54 100644
--- a/drivers/dma/fsldma.c
+++ b/drivers/dma/fsldma.c
@@ -463,6 +463,89 @@ static struct fsl_desc_sw *fsl_dma_alloc_descriptor(struct 
fsldma_chan *chan)
 }
 
 /**
+ * fsldma_clean_completed_descriptor - free all descriptors which
+ * has been completed and acked
+ * @chan: Freescale DMA channel
+ *
+ * This function is used on all completed and acked descriptors.
+ * All descriptors should only be freed in this function.
+ */
+static void fsldma_clean_completed_descriptor(struct fsldma_chan *chan)
+{
+   struct fsl_desc_sw *desc, *_desc;
+
+   /* Run the callback for each descriptor, in order */
+   list_for_each_entry_safe(desc, _desc, chan-ld_completed, node)
+   if (async_tx_test_ack(desc-async_tx))
+   fsl_dma_free_descriptor(chan, desc);
+}
+
+/**
+ * fsldma_run_tx_complete_actions - cleanup a single link descriptor
+ * @chan: Freescale DMA channel
+ * @desc: descriptor to cleanup and free
+ * @cookie: Freescale DMA transaction identifier
+ *
+ * This function is used on a descriptor which has been executed by the DMA
+ * controller. It will run any callbacks, submit any dependencies.
+ */
+static dma_cookie_t fsldma_run_tx_complete_actions(struct fsldma_chan *chan,
+   struct fsl_desc_sw *desc, dma_cookie_t cookie)
+{
+   struct dma_async_tx_descriptor *txd = desc-async_tx;
+
+   BUG_ON(txd-cookie  0);
+
+   if (txd-cookie  0) {
+   cookie = txd-cookie;
+
+   /* Run the link descriptor callback function */
+   if (txd-callback) {
+#ifdef FSL_DMA_LD_DEBUG
+   chan_dbg(chan, LD %p callback\n, desc);
+#endif
+   txd-callback(txd-callback_param);
+   }
+   }
+
+   /* Run any dependencies 

[PATCH 7/7] DMA: Freescale: add suspend resume functions for DMA driver

2014-01-15 Thread hongbo.zhang
From: Hongbo Zhang hongbo.zh...@freescale.com

This patch adds suspend resume functions for Freescale DMA driver.
.prepare callback is used to stop further descriptors from being added into the
pending queue, and also issue pending queues into execution if there is any.
.suspend callback makes sure all the pending jobs are cleaned up and all the
channels are idle, and save the mode registers.
.resume callback re-initializes the channels by restore the mode registers.

Signed-off-by: Hongbo Zhang hongbo.zh...@freescale.com
---
 drivers/dma/fsldma.c |   99 ++
 drivers/dma/fsldma.h |   16 
 2 files changed, 115 insertions(+)

diff --git a/drivers/dma/fsldma.c b/drivers/dma/fsldma.c
index 437794e..fb94eb3 100644
--- a/drivers/dma/fsldma.c
+++ b/drivers/dma/fsldma.c
@@ -400,6 +400,14 @@ static dma_cookie_t fsl_dma_tx_submit(struct 
dma_async_tx_descriptor *tx)
 
spin_lock_bh(chan-desc_lock);
 
+#ifdef CONFIG_PM
+   if (unlikely(chan-pm_state != RUNNING)) {
+   chan_dbg(chan, cannot submit due to suspend\n);
+   spin_unlock_bh(chan-desc_lock);
+   return -1;
+   }
+#endif
+
/*
 * assign cookies to all of the software descriptors
 * that make up this transaction
@@ -1317,6 +1325,9 @@ static int fsl_dma_chan_probe(struct fsldma_device *fdev,
INIT_LIST_HEAD(chan-ld_running);
INIT_LIST_HEAD(chan-ld_completed);
chan-idle = true;
+#ifdef CONFIG_PM
+   chan-pm_state = RUNNING;
+#endif
 
chan-common.device = fdev-common;
dma_cookie_init(chan-common);
@@ -1456,6 +1467,91 @@ static int fsldma_of_remove(struct platform_device *op)
return 0;
 }
 
+#ifdef CONFIG_PM
+static int fsldma_prepare(struct device *dev)
+{
+   struct platform_device *pdev = to_platform_device(dev);
+   struct fsldma_device *fdev = platform_get_drvdata(pdev);
+   struct fsldma_chan *chan;
+   int i;
+
+   for (i = 0; i  FSL_DMA_MAX_CHANS_PER_DEVICE; i++) {
+   chan = fdev-chan[i];
+   if (!chan)
+   continue;
+
+   spin_lock_bh(chan-desc_lock);
+   chan-pm_state = SUSPENDING;
+   if (!list_empty(chan-ld_pending))
+   fsl_chan_xfer_ld_queue(chan);
+   spin_unlock_bh(chan-desc_lock);
+   }
+
+   return 0;
+}
+
+static int fsldma_suspend(struct device *dev)
+{
+   struct platform_device *pdev = to_platform_device(dev);
+   struct fsldma_device *fdev = platform_get_drvdata(pdev);
+   struct fsldma_chan *chan;
+   int i;
+
+   for (i = 0; i  FSL_DMA_MAX_CHANS_PER_DEVICE; i++) {
+   chan = fdev-chan[i];
+   if (!chan)
+   continue;
+
+   spin_lock_bh(chan-desc_lock);
+   if (!chan-idle)
+   goto out;
+   chan-regs_save.mr = DMA_IN(chan, chan-regs-mr, 32);
+   chan-pm_state = SUSPENDED;
+   spin_unlock_bh(chan-desc_lock);
+   }
+   return 0;
+
+out:
+   for (; i = 0; i--) {
+   chan = fdev-chan[i];
+   if (!chan)
+   continue;
+   spin_unlock_bh(chan-desc_lock);
+   }
+   return -EBUSY;
+}
+
+static int fsldma_resume(struct device *dev)
+{
+   struct platform_device *pdev = to_platform_device(dev);
+   struct fsldma_device *fdev = platform_get_drvdata(pdev);
+   struct fsldma_chan *chan;
+   u32 mode;
+   int i;
+
+   for (i = 0; i  FSL_DMA_MAX_CHANS_PER_DEVICE; i++) {
+   chan = fdev-chan[i];
+   if (!chan)
+   continue;
+
+   spin_lock_bh(chan-desc_lock);
+   mode = chan-regs_save.mr
+~FSL_DMA_MR_CS  ~FSL_DMA_MR_CC  ~FSL_DMA_MR_CA;
+   DMA_OUT(chan, chan-regs-mr, mode, 32);
+   chan-pm_state = RUNNING;
+   spin_unlock_bh(chan-desc_lock);
+   }
+
+   return 0;
+}
+
+static const struct dev_pm_ops fsldma_pm_ops = {
+   .prepare= fsldma_prepare,
+   .suspend= fsldma_suspend,
+   .resume = fsldma_resume,
+};
+#endif
+
 static const struct of_device_id fsldma_of_ids[] = {
{ .compatible = fsl,elo3-dma, },
{ .compatible = fsl,eloplus-dma, },
@@ -1468,6 +1564,9 @@ static struct platform_driver fsldma_of_driver = {
.name = fsl-elo-dma,
.owner = THIS_MODULE,
.of_match_table = fsldma_of_ids,
+#ifdef CONFIG_PM
+   .pm = fsldma_pm_ops,
+#endif
},
.probe = fsldma_of_probe,
.remove = fsldma_of_remove,
diff --git a/drivers/dma/fsldma.h b/drivers/dma/fsldma.h
index ec19517..eecaf9e 100644
--- a/drivers/dma/fsldma.h
+++ b/drivers/dma/fsldma.h
@@ -134,6 +134,18 @@ struct fsldma_device {
 #define FSL_DMA_CHAN_PAUSE_EXT 0x1000
 #define 

[PATCH] DMA: Freescale: change BWC from 256 bytes to 1024 bytes

2014-01-15 Thread hongbo.zhang
From: Hongbo Zhang hongbo.zh...@freescale.com

Freescale DMA has a feature of BandWidth Control (ab. BWC), which is currently
256 bytes and should be changed to 1024 bytes for best DMA throughput.
Changing BWC from 256 to 1024 will improve DMA performance much, in cases
whatever one channel is running or multi channels are running simultanously,
large or small buffers are copied.  And this change doesn't impact memory
access performance remarkably, lmbench tests show that for some cases the
memory performance are decreased very slightly, while the others are even
better.
Tested on T4240.

Signed-off-by: Hongbo Zhang hongbo.zh...@freescale.com
---
 drivers/dma/fsldma.h |2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/dma/fsldma.h b/drivers/dma/fsldma.h
index 1ffc244..d56e835 100644
--- a/drivers/dma/fsldma.h
+++ b/drivers/dma/fsldma.h
@@ -41,7 +41,7 @@
  * channel is allowed to transfer before the DMA engine pauses
  * the current channel and switches to the next channel
  */
-#define FSL_DMA_MR_BWC 0x0800
+#define FSL_DMA_MR_BWC 0x0A00
 
 /* Special MR definition for MPC8349 */
 #define FSL_DMA_MR_EOTIE   0x0080
-- 
1.7.9.5



___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev