[PATCH 00/11] ARM: OMAP: core/hwmod: first set of fixes for 3.5-rc

2012-06-07 Thread Paul Walmsley
Hi,

Here is an initial set of fixes for power management and OMAP core
infrastructure for 3.5-rc.  Most of these patches address boot
warnings and power management problems on OMAP4, although a few of
them address more general issues.

Compile-test information is below.  The patches been boot-tested on
OMAP3530 ES3.0 BeagleBoard and OMAP4430 ES2.0 PandaBoard.  Suspend and
idle are broken on both of these platforms right now.  Unfortunately
my board farm is down at the moment, so I'm unable to do further
testing on other boards.  Boot logs, such as they are, are available
from:

http://www.pwsan.com/omap/bootlogs/20120606/omap_fixes_a_3.5rc__23a432a1860498d0dfbe36319de3b86d9832c6e7/

These patches are available via git from git://git.pwsan.com/linux-2.6
in the branch 'omap_fixes_a_3.5rc'.  Will plan to send a pull request
tomorrow unless there are actionable comments.


- Paul

---

object size (delta in bytes from v3.5-rc1 
(f8f5701bdaf9134b1f90e5044a82c66324d2073f)):
 textdata bss   total   kernel
0   0   0   0   5912osk_testconfig/vmlinux
 +352 +88   0+440   n800_multi_omap2xxx/vmlinux
 +384 +96   0+480   n800_testconfig/vmlinux
0   0   0   0   omap1510_defconfig/vmlinux
0   0   0   0   omap1_defconfig/vmlinux
 +352+312   0+664   omap2_4_testconfig/vmlinux
 +384+448   0+832   omap2plus_defconfig/vmlinux
 +384+384   0+768   omap2plus_no_pm/vmlinux
 +320+320   0+640   omap3_4_testconfig/vmlinux
 +320 +88   0+408   omap3_testconfig/vmlinux
 +320+256   0+576   omap4_testconfig/vmlinux


Djamil Elaidi (1):
  ARM: OMAP4+: hwmod: fix issue causing IPs not going back to Smart-Standby

Paul Walmsley (8):
  ARM: OMAP2+: hwmod: add setup_preprogram hook
  ARM: OMAP4+: AESS: enable internal auto-gating during initial setup
  ARM: OMAP4: hwmod data: add SL2IF hardreset line
  ARM: OMAP2+: hwmod code/data: fix 32K sync timer
  ARM: OMAP2+: CM: increase the module disable timeout
  ARM: OMAP4: clock data: add clockdomains for clocks used as main clocks
  ARM: OMAP2+: hwmod: add flag to prevent hwmod code from touching IP block 
during init
  ARM: OMAP4: hwmod data: do not enable or reset the McPDM during kernel 
init

Tero Kristo (1):
  ARM: OMAP2+: usb_host_fs: add custom reset for usb_host_fs (fsusb)

Todd Poynor (1):
  ARM: OMAP: PM: Lock clocks list while generating summary


 arch/arm/mach-omap2/Makefile |6 +--
 arch/arm/mach-omap2/aess.c   |   55 +++
 arch/arm/mach-omap2/clock44xx_data.c |5 ++
 arch/arm/mach-omap2/cm.h |   19 
 arch/arm/mach-omap2/cminst44xx.c |4 +-
 arch/arm/mach-omap2/common.h |2 +
 arch/arm/mach-omap2/omap_hwmod.c |   58 +---
 arch/arm/mach-omap2/omap_hwmod_44xx_data.c   |   23 ++
 arch/arm/mach-omap2/usb-fs.c |   62 ++
 arch/arm/plat-omap/clock.c   |2 +
 arch/arm/plat-omap/include/plat/omap_hwmod.h |   15 ++
 arch/arm/plat-omap/include/plat/usb.h|3 +
 12 files changed, 238 insertions(+), 16 deletions(-)
 create mode 100644 arch/arm/mach-omap2/aess.c

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 01/11] ARM: OMAP2+: hwmod: add setup_preprogram hook

2012-06-07 Thread Paul Walmsley
After reset, some IP blocks cannot indicate to the PRCM that they are
inactive until they are configured.  One example on OMAP4 is the AESS
IP block.

To fix this cleanly, this patch adds another optional function
pointer, setup_preprogram, to the IP block's hwmod data.  The function
that is pointed to is called by the hwmod code immediately after the
IP block is reset.

Signed-off-by: Paul Walmsley p...@pwsan.com
Cc: Benoît Cousson b-cous...@ti.com
Cc: Péter Ujfalusi peter.ujfal...@ti.com
---
 arch/arm/mach-omap2/omap_hwmod.c |   21 -
 arch/arm/plat-omap/include/plat/omap_hwmod.h |9 +
 2 files changed, 29 insertions(+), 1 deletion(-)

diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
index bf86f7e..b0d3064 100644
--- a/arch/arm/mach-omap2/omap_hwmod.c
+++ b/arch/arm/mach-omap2/omap_hwmod.c
@@ -2103,6 +2103,23 @@ static void __init _setup_iclk_autoidle(struct 
omap_hwmod *oh)
 }
 
 /**
+ * _setup_preprogram - Pre-program an IP block during the _setup() process
+ * @oh: struct omap_hwmod *
+ *
+ * Some IP blocks (such as AESS) require some additional programming
+ * after reset before they can enter idle.  If a function pointer to
+ * do so is present in the hwmod data, then call it and pass along the
+ * return value; otherwise, return 0.
+ */
+static int __init _setup_preprogram(struct omap_hwmod *oh)
+{
+   if (!oh-class-setup_preprogram)
+   return 0;
+
+   return oh-class-setup_preprogram(oh);
+}
+
+/**
  * _setup_reset - reset an IP block during the setup process
  * @oh: struct omap_hwmod *
  *
@@ -2224,8 +2241,10 @@ static int __init _setup(struct omap_hwmod *oh, void 
*data)
 
_setup_iclk_autoidle(oh);
 
-   if (!_setup_reset(oh))
+   if (!_setup_reset(oh)) {
+   _setup_preprogram(oh);
_setup_postsetup(oh);
+   }
 
return 0;
 }
diff --git a/arch/arm/plat-omap/include/plat/omap_hwmod.h 
b/arch/arm/plat-omap/include/plat/omap_hwmod.h
index c835b71..fdc4b2a 100644
--- a/arch/arm/plat-omap/include/plat/omap_hwmod.h
+++ b/arch/arm/plat-omap/include/plat/omap_hwmod.h
@@ -458,6 +458,7 @@ struct omap_hwmod_omap4_prcm {
  * @rev: revision of the IP class
  * @pre_shutdown: ptr to fn to be executed immediately prior to device shutdown
  * @reset: ptr to fn to be executed in place of the standard hwmod reset fn
+ * @setup_preprogram: ptr to fn to be executed after the reset in _setup()
  *
  * Represent the class of a OMAP hardware modules (e.g. timer,
  * smartreflex, gpio, uart...)
@@ -474,6 +475,13 @@ struct omap_hwmod_omap4_prcm {
  * executed in place of the standard hwmod _reset() code in
  * mach-omap2/omap_hwmod.c.  This is needed for IP blocks which have
  * unusual reset sequences - usually processor IP blocks like the IVA.
+ *
+ * @setup_preprogram is called between the calls to _setup_reset() and
+ * _setup_postsetup().  It is intended to be used for IP blocks that
+ * require some initial configuration during their first
+ * initialization.  (For example, the AESS IP block on OMAP4+ cannot
+ * enter idle until its internal autogating bit is set.)  Most IP blocks
+ * will not need this.
  */
 struct omap_hwmod_class {
const char  *name;
@@ -481,6 +489,7 @@ struct omap_hwmod_class {
u32 rev;
int (*pre_shutdown)(struct 
omap_hwmod *oh);
int (*reset)(struct omap_hwmod *oh);
+   int (*setup_preprogram)(struct 
omap_hwmod *oh);
 };
 
 /**


--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 04/11] ARM: OMAP2+: usb_host_fs: add custom reset for usb_host_fs (fsusb)

2012-06-07 Thread Paul Walmsley
From: Tero Kristo t-kri...@ti.com

Add a custom reset function for the usb_host_fs/fsusb IP block, and
connect it to the OMAP4 FSUSB block.

This is the first of two fixes required to get rid of the boot
warning:

omap_hwmod: usb_host_fs: _wait_target_disable failed

and to allow the module to idle.

It may be necessary to use this reset method for OMAP2xxx SoCs as
well; this is left for a future patch.

Signed-off-by: Tero Kristo t-kri...@ti.com
[p...@pwsan.com: rewrote the custom reset function, documented it and
 updated the commit message, and moved the code to mach-omap2/fs-usb.c]
Signed-off-by: Paul Walmsley p...@pwsan.com
Cc: Benoît Cousson b-cous...@ti.com
Cc: Felipe Balbi ba...@ti.com
---
 arch/arm/mach-omap2/Makefile   |4 --
 arch/arm/mach-omap2/cm.h   |8 +++-
 arch/arm/mach-omap2/omap_hwmod_44xx_data.c |1 
 arch/arm/mach-omap2/usb-fs.c   |   62 
 arch/arm/plat-omap/include/plat/usb.h  |3 +
 5 files changed, 73 insertions(+), 5 deletions(-)

diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
index bc2ac4f..fc2ff91 100644
--- a/arch/arm/mach-omap2/Makefile
+++ b/arch/arm/mach-omap2/Makefile
@@ -245,9 +245,7 @@ omap-hsmmc-$(CONFIG_MMC_OMAP_HS):= hsmmc.o
 obj-y  += $(omap-hsmmc-m) $(omap-hsmmc-y)
 
 
-usbfs-$(CONFIG_ARCH_OMAP_OTG)  := usb-fs.o
-obj-y  += $(usbfs-m) $(usbfs-y)
-obj-y  += usb-musb.o
+obj-y  += usb-fs.o usb-musb.o
 obj-y  += omap_phy_internal.o
 
 obj-$(CONFIG_MACH_OMAP2_TUSB6010)  += usb-tusb6010.o
diff --git a/arch/arm/mach-omap2/cm.h b/arch/arm/mach-omap2/cm.h
index a7bc096..99978c7 100644
--- a/arch/arm/mach-omap2/cm.h
+++ b/arch/arm/mach-omap2/cm.h
@@ -1,7 +1,7 @@
 /*
  * OMAP2+ Clock Management prototypes
  *
- * Copyright (C) 2007-2009 Texas Instruments, Inc.
+ * Copyright (C) 2007-2012 Texas Instruments, Inc.
  * Copyright (C) 2007-2009 Nokia Corporation
  *
  * Written by Paul Walmsley
@@ -14,6 +14,12 @@
 #define __ARCH_ASM_MACH_OMAP2_CM_H
 
 /*
+ * MAX_MODULE_SOFTRESET_TIME: maximum time in microseconds to wait for
+ * an IP block to finish an OCP SOFTRESET.
+ */
+#define MAX_MODULE_SOFTRESET_WAIT  1
+
+/*
  * MAX_MODULE_READY_TIME: max duration in microseconds to wait for the
  * PRCM to request that a module exit the inactive state in the case of
  * OMAP2  3.
diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c 
b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
index a93ce48..02daacc 100644
--- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
@@ -3314,6 +3314,7 @@ static struct omap_hwmod_class_sysconfig 
omap44xx_usb_host_fs_sysc = {
 static struct omap_hwmod_class omap44xx_usb_host_fs_hwmod_class = {
.name   = usb_host_fs,
.sysc   = omap44xx_usb_host_fs_sysc,
+   .reset  = omap_usb_host_fs_reset,
 };
 
 /* usb_host_fs */
diff --git a/arch/arm/mach-omap2/usb-fs.c b/arch/arm/mach-omap2/usb-fs.c
index 1481078..4faf0f7 100644
--- a/arch/arm/mach-omap2/usb-fs.c
+++ b/arch/arm/mach-omap2/usb-fs.c
@@ -1,7 +1,7 @@
 /*
  * Platform level USB initialization for FS USB OTG controller on omap1 and 
24xx
  *
- * Copyright (C) 2004 Texas Instruments, Inc.
+ * Copyright (C) 2004, 2012 Texas Instruments, Inc.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -32,6 +32,8 @@
 #include plat/usb.h
 #include plat/board.h
 
+#include cm.h
+#include common.h
 #include control.h
 #include mux.h
 
@@ -41,6 +43,64 @@
 #define INT_USB_IRQ_HGEN   INT_24XX_USB_IRQ_HGEN
 #define INT_USB_IRQ_OTGINT_24XX_USB_IRQ_OTG
 
+/* HCCOMMANDSTATUS: the register offset of the HCCOMMANDSTATUS register */
+#define HCCOMMANDSTATUS0x0008
+
+/* HCCOMMANDSTATUS_HCR: the bitmask of the host controller reset flag */
+#define HCCOMMANDSTATUS_HCR_MASK   (1  0)
+
+/**
+ * omap_usb_host_fs_reset - custom reset function for the FSUSB IP block
+ * @oh: struct omap_hwmod * of the usb_host_fs IP block
+ *
+ * Reset the FSUSB IP block.  This IP block requires a custom
+ * two-stage reset; otherwise the IP block won't idle-ack to the PRCM.
+ * First the OCP SOFTRESET method must be used.  Next, the IP block's
+ * internal reset bit must be toggled.  This will place the OHCI
+ * controller state into UsbSuspend, which allows the IP block to
+ * idle-ack to the PRCM.  Note that the FSUSB still takes almost 4
+ * milliseconds to idle-ack after this function returns.  Returns 0
+ * upon success, -EINVAL if the IP block softreset data wasn't
+ * supplied, or -EBUSY if the IP block reset times out.
+ */
+int omap_usb_host_fs_reset(struct omap_hwmod *oh)
+{
+   int c;
+
+   if (omap_hwmod_softreset(oh))
+   return 

[PATCH 05/11] ARM: OMAP2+: hwmod code/data: fix 32K sync timer

2012-06-07 Thread Paul Walmsley
Kevin discovered that commit c8d82ff68fb6873691536cf33021977efbf5593c
(ARM: OMAP2/3: hwmod data: Add 32k-sync timer data to hwmod
database) broke CORE idle on OMAP3.  This prevents device low power
states.

The root cause is that the 32K sync timer IP block does not support
smart-idle mode[1], and so the hwmod code keeps the IP block in
no-idle mode while it is active.  This in turn prevents the WKUP
clockdomain from transitioning to idle.  There is a hardcoded sleep
dependency that prevents the CORE_L3 and CORE_CM clockdomains from
transitioning to idle when the WKUP clockdomain is active[2], so the
chip cannot enter any device low power states.

It turns out that there is no need to take the 32k sync timer out of
idle.  The IP block itself probably does not have any native idle
handling at all, due to its simplicity.  Furthermore, the PRCM will
never request target idle for this IP block while the kernel is
running, due to the sleep dependency that prevents the WKUP
clockdomain from idling while the CORE_L3 clockdomain is active.  So
we can safely leave the 32k sync timer in target-no-idle mode, even
while we continue to access it.

This workaround is implemented by programming the force-idle mode for
any IP block that only supports the force-idle and no-idle modes.  If
an IP block is ever released that doesn't support smart-idle and
requires no-idle mode to be programmed while it's in use, we'll have
to change this behavior.

Another theoretically clean fix for this problem would be to implement
PM runtime-based control for 32k sync timer accesses.  These PM
runtime calls would need to located in a custom clocksource, since the
32k sync timer is currently used as an MMIO clocksource.  But in
practice, there would be little benefit to doing so; and there would
be some cost, due to the addition of unnecessary lines of code and the
additional CPU overhead of the PM runtime and hwmod code - unnecessary
in this case.

Another possible fix would have been to modify the pm34xx.c code to
force the IP block idle before entering WFI.  But this would not have
been an acceptable approach: we are trying to remove this type of
centralized IP block idle control from the PM code.

This patch is effectively a workaround for a hardware problem.  A
better hardware approach would have been to implement a smart-idle
target idle mode for this IP block.  The smart-idle mode in this case
would behave identically to the force-idle mode.  We consider the
force-idle and no-idle target idle mode settings to be intended for
debugging and automatic idle management bug workarounds only[4].

This patch is a collaboration between Kevin Hilman khil...@ti.com
and Paul Walmsley p...@pwsan.com.

References:

1. Table 16-96 REG_32KSYNCNT_SYSCONFIG of the OMAP34xx TRM Rev. ZU
   (SWPU223U), available from:
   http://www.ti.com/pdfs/wtbu/OMAP34x_ES3.1.x_PUBLIC_TRM_vzU.zip

2. Table 4-72 Sleep Dependencies of the OMAP34xx TRM Rev. ZU
   (SWPU223U)

3. ibid.

4. Section 3.1.1.1.2 Module-Level Clock Management of The
   OMAP4430 TRM Rev. vAA (SWPU231AA).

Cc: Tony Lindgren t...@atomide.com
Cc: Vaibhav Hiremath hvaib...@ti.com
Cc: Benoît Cousson b-cous...@ti.com
Tested-by: Kevin Hilman khil...@ti.com
Signed-off-by: Kevin Hilman khil...@ti.com
Signed-off-by: Paul Walmsley p...@pwsan.com
---
 arch/arm/mach-omap2/omap_hwmod.c |   32 ++--
 1 file changed, 26 insertions(+), 6 deletions(-)

diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
index b0d3064..6b4ae31 100644
--- a/arch/arm/mach-omap2/omap_hwmod.c
+++ b/arch/arm/mach-omap2/omap_hwmod.c
@@ -1124,10 +1124,12 @@ static struct omap_hwmod_addr_space * __init 
_find_mpu_rt_addr_space(struct omap
  * _enable_sysc - try to bring a module out of idle via OCP_SYSCONFIG
  * @oh: struct omap_hwmod *
  *
- * If module is marked as SWSUP_SIDLE, force the module out of slave
- * idle; otherwise, configure it for smart-idle.  If module is marked
- * as SWSUP_MSUSPEND, force the module out of master standby;
- * otherwise, configure it for smart-standby.  No return value.
+ * Ensure that the OCP_SYSCONFIG register for the IP block represented
+ * by @oh is set to indicate to the PRCM that the IP block is active.
+ * Usually this means placing the module into smart-idle mode and
+ * smart-standby, but if there is a bug in the automatic idle handling
+ * for the IP block, it may need to be placed into the force-idle or
+ * no-idle variants of these modes.  No return value.
  */
 static void _enable_sysc(struct omap_hwmod *oh)
 {
@@ -1141,8 +1143,26 @@ static void _enable_sysc(struct omap_hwmod *oh)
sf = oh-class-sysc-sysc_flags;
 
if (sf  SYSC_HAS_SIDLEMODE) {
-   idlemode = (oh-flags  HWMOD_SWSUP_SIDLE) ?
-   HWMOD_IDLEMODE_NO : HWMOD_IDLEMODE_SMART;
+   if (oh-flags  HWMOD_SWSUP_SIDLE) {
+   /*
+* IP blocks without smart idle should be left
+   

[PATCH 03/11] ARM: OMAP4: hwmod data: add SL2IF hardreset line

2012-06-07 Thread Paul Walmsley
On boot, the sl2if module can't be enabled.  The following message is
logged:

omap_hwmod: sl2if: cannot be enabled for reset (3)

This is probably because the SL2IF is still being held in hardreset.
The SL2IF's hardreset line is shared with one of the IVAHD's hardreset
lines; see for example Table 3-536 RM_IVAHD_RSTCTRL in the OMAP4430
TRM Rev. AA (SWPU231AA).  To work around this, add the SL2IF's
hardreset line to the hwmod data.  This is correct from a hardware
perspective and also will prevent the hwmod from attempting to enable
the SL2IF during reset.  The driver for this IP block will need to
handle its integration until the appropriate way to handle the IVAHD
integration can be elucidated.

Signed-off-by: Paul Walmsley p...@pwsan.com
Cc: Tero Kristo t-kri...@ti.com
---
 arch/arm/mach-omap2/omap_hwmod_44xx_data.c |7 +++
 1 file changed, 7 insertions(+)

diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c 
b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
index 4a2f2cc..a93ce48 100644
--- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
@@ -2597,15 +2597,22 @@ static struct omap_hwmod_class 
omap44xx_sl2if_hwmod_class = {
.name   = sl2if,
 };
 
+static struct omap_hwmod_rst_info omap44xx_sl2if_resets[] = {
+   { .name = logic, .rst_shift = 2 },
+};
+
 /* sl2if */
 static struct omap_hwmod omap44xx_sl2if_hwmod = {
.name   = sl2if,
.class  = omap44xx_sl2if_hwmod_class,
.clkdm_name = ivahd_clkdm,
+   .rst_lines  = omap44xx_sl2if_resets,
+   .rst_lines_cnt  = ARRAY_SIZE(omap44xx_sl2if_resets),
.prcm = {
.omap4 = {
.clkctrl_offs = OMAP4_CM_IVAHD_SL2_CLKCTRL_OFFSET,
.context_offs = OMAP4_RM_IVAHD_SL2_CONTEXT_OFFSET,
+   .rstctrl_offs = OMAP4_RM_IVAHD_RSTCTRL_OFFSET,
.modulemode   = MODULEMODE_HWCTRL,
},
},


--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 06/11] ARM: OMAP4+: hwmod: fix issue causing IPs not going back to Smart-Standby

2012-06-07 Thread Paul Walmsley
From: Djamil Elaidi d-ela...@ti.com

If an IP is configured in Smart-Standby-Wakeup, when disabling wakeup feature 
the
IP will not go back to Smart-Standby, but will remain in Smart-Standby-Wakeup.

Signed-off-by: Djamil Elaidi d-ela...@ti.com
Signed-off-by: Paul Walmsley p...@pwsan.com
---
 arch/arm/mach-omap2/omap_hwmod.c |2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
index 6b4ae31..d3afac5 100644
--- a/arch/arm/mach-omap2/omap_hwmod.c
+++ b/arch/arm/mach-omap2/omap_hwmod.c
@@ -530,7 +530,7 @@ static int _disable_wakeup(struct omap_hwmod *oh, u32 *v)
if (oh-class-sysc-idlemodes  SIDLE_SMART_WKUP)
_set_slave_idlemode(oh, HWMOD_IDLEMODE_SMART, v);
if (oh-class-sysc-idlemodes  MSTANDBY_SMART_WKUP)
-   _set_master_standbymode(oh, HWMOD_IDLEMODE_SMART_WKUP, v);
+   _set_master_standbymode(oh, HWMOD_IDLEMODE_SMART, v);
 
/* XXX test pwrdm_get_wken for this hwmod's subsystem */
 


--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 11/11] ARM: OMAP4: hwmod data: do not enable or reset the McPDM during kernel init

2012-06-07 Thread Paul Walmsley
Resolve this kernel boot message:

omap_hwmod: mcpdm: cannot be enabled for reset (3)

It appears that the McPDM on OMAP4 can only receive its functional
clock from an off-chip source.  This source is not guaranteed to be
present on the board, and when present, it is controlled by I2C.  This
would introduce a board dependency to the early hwmod code which it
was not designed to handle.  Also, neither the driver for this
off-chip clock provider nor the I2C code is available early in boot
when the hwmod code is attempting to enable and reset IP blocks.  This
effectively makes it impossible to enable and reset this device during
hwmod init.

At its core, this patch is a workaround for an OMAP hardware problem.
It should be possible to configure the OMAP to provide any IP block's
functional clock from an on-chip source.  (This is true for almost
every IP block on the chip.  As far as I know, McPDM is the only
exception.)  If the kernel cannot reset and configure IP blocks, it
cannot guarantee a sane SoC state.  Relying on an optional off-chip
clock also creates a board dependency which is beyond the scope of the
early hwmod code.

This patch works around the issue by marking the McPDM hwmod record
with the HWMOD_UNKNOWN_MAIN_FCLK_STATE flag.  This prevents the hwmod
code from touching the device early during boot.

Signed-off-by: Paul Walmsley p...@pwsan.com
Cc: Péter Ujfalusi peter.ujfal...@ti.com
Cc: Benoît Cousson b-cous...@ti.com
---
 arch/arm/mach-omap2/omap_hwmod_44xx_data.c |   12 
 1 file changed, 12 insertions(+)

diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c 
b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
index 20e45a6..cc1310a 100644
--- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
@@ -2090,6 +2090,18 @@ static struct omap_hwmod omap44xx_mcpdm_hwmod = {
.name   = mcpdm,
.class  = omap44xx_mcpdm_hwmod_class,
.clkdm_name = abe_clkdm,
+   /*
+* It's suspected that the McPDM requires an off-chip main
+* functional clock, controlled via I2C.  This IP block is
+* currently reset very early during boot, before I2C is
+* available, so it doesn't seem that we have any choice in
+* the kernel other than to avoid resetting it.  XXX This is
+* really a hardware issue workaround: every IP block should
+* be able to source its main functional clock from either
+* on-chip or off-chip sources.  McPDM seems to be the only
+* current exception.
+*/
+   .flags  = HWMOD_EXT_OPT_MAIN_CLK,
.mpu_irqs   = omap44xx_mcpdm_irqs,
.sdma_reqs  = omap44xx_mcpdm_sdma_reqs,
.main_clk   = mcpdm_fck,


--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 10/11] ARM: OMAP2+: hwmod: add flag to prevent hwmod code from touching IP block during init

2012-06-07 Thread Paul Walmsley
Add HWMOD_EXT_OPT_MAIN_CLK flag to indicate that this IP block is
dependent on an off-chip functional clock that is not guaranteed to be
present during initialization.  IP blocks marked with this flag are
left in the INITIALIZED state during kernel init.

This is a workaround for a hardware problem.  It should be possible to
guarantee that at least one clock source will be present and active
for any IP block's main functional clock.  This ensures that the hwmod
code can enable and reset the IP block.  Resetting the IP block during
kernel init prevents any bogus bootloader, ROM code, or previous OS
configuration from affecting the kernel.  Hopefully a clock
multiplexer can be added on future SoCs.

N.B., at some point in the future, it should be possible to query the
clock framework for this type of information.  Then this flag should
no longer be needed.

Signed-off-by: Paul Walmsley p...@pwsan.com
Cc: Benoît Cousson b-cous...@ti.com
---
 arch/arm/mach-omap2/omap_hwmod.c |3 +++
 arch/arm/plat-omap/include/plat/omap_hwmod.h |6 ++
 2 files changed, 9 insertions(+)

diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
index d3afac5..c8655c0 100644
--- a/arch/arm/mach-omap2/omap_hwmod.c
+++ b/arch/arm/mach-omap2/omap_hwmod.c
@@ -2155,6 +2155,9 @@ static int __init _setup_reset(struct omap_hwmod *oh)
if (oh-_state != _HWMOD_STATE_INITIALIZED)
return -EINVAL;
 
+   if (oh-flags  HWMOD_EXT_OPT_MAIN_CLK)
+   return -EPERM;
+
if (oh-rst_lines_cnt == 0) {
r = _enable(oh);
if (r) {
diff --git a/arch/arm/plat-omap/include/plat/omap_hwmod.h 
b/arch/arm/plat-omap/include/plat/omap_hwmod.h
index fdc4b2a..d117931 100644
--- a/arch/arm/plat-omap/include/plat/omap_hwmod.h
+++ b/arch/arm/plat-omap/include/plat/omap_hwmod.h
@@ -409,6 +409,11 @@ struct omap_hwmod_omap4_prcm {
  * in order to complete the reset. Optional clocks will be disabled
  * again after the reset.
  * HWMOD_16BIT_REG: Module has 16bit registers
+ * HWMOD_EXT_OPT_MAIN_CLK: The only main functional clock source for
+ * this IP block comes from an off-chip source and is not always
+ * enabled.  This prevents the hwmod code from being able to
+ * enable and reset the IP block early.  XXX Eventually it should
+ * be possible to query the clock framework for this information.
  */
 #define HWMOD_SWSUP_SIDLE  (1  0)
 #define HWMOD_SWSUP_MSTANDBY   (1  1)
@@ -419,6 +424,7 @@ struct omap_hwmod_omap4_prcm {
 #define HWMOD_NO_IDLEST(1  6)
 #define HWMOD_CONTROL_OPT_CLKS_IN_RESET(1  7)
 #define HWMOD_16BIT_REG(1  8)
+#define HWMOD_EXT_OPT_MAIN_CLK (1  9)
 
 /*
  * omap_hwmod._int_flags definitions


--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 08/11] ARM: OMAP2+: CM: increase the module disable timeout

2012-06-07 Thread Paul Walmsley
Increase the timeout for disabling an IP block to five milliseconds.
This is to handle the usb_host_fs idle latency, which takes almost
four milliseconds after a host controller reset.

This is the second of two patches needed to resolve the following
boot warning:

omap_hwmod: usb_host_fs: _wait_target_disable failed

Signed-off-by: Paul Walmsley p...@pwsan.com
Cc: Tero Kristo t-kri...@ti.com
---
 arch/arm/mach-omap2/cm.h   |   11 +++
 arch/arm/mach-omap2/cminst44xx.c   |4 ++--
 arch/arm/mach-omap2/omap_hwmod_44xx_data.c |1 +
 3 files changed, 14 insertions(+), 2 deletions(-)

diff --git a/arch/arm/mach-omap2/cm.h b/arch/arm/mach-omap2/cm.h
index 99978c7..cf67617 100644
--- a/arch/arm/mach-omap2/cm.h
+++ b/arch/arm/mach-omap2/cm.h
@@ -28,4 +28,15 @@
  */
 #define MAX_MODULE_READY_TIME  2000
 
+/*
+ * MAX_MODULE_DISABLE_TIME: max duration in microseconds to wait for
+ * the PRCM to request that a module enter the inactive state in the
+ * case of OMAP2  3.  In the case of OMAP4 this is the max duration
+ * in microseconds for the module to reach the inactive state from
+ * a functional state.
+ * XXX FSUSB on OMAP4430 takes ~4ms to idle after reset during
+ * kernel init.
+ */
+#define MAX_MODULE_DISABLE_TIME5000
+
 #endif
diff --git a/arch/arm/mach-omap2/cminst44xx.c b/arch/arm/mach-omap2/cminst44xx.c
index 8c86d29..1a39945 100644
--- a/arch/arm/mach-omap2/cminst44xx.c
+++ b/arch/arm/mach-omap2/cminst44xx.c
@@ -313,9 +313,9 @@ int omap4_cminst_wait_module_idle(u8 part, u16 inst, s16 
cdoffs, u16 clkctrl_off
 
omap_test_timeout((_clkctrl_idlest(part, inst, cdoffs, clkctrl_offs) ==
   CLKCTRL_IDLEST_DISABLED),
- MAX_MODULE_READY_TIME, i);
+ MAX_MODULE_DISABLE_TIME, i);
 
-   return (i  MAX_MODULE_READY_TIME) ? 0 : -EBUSY;
+   return (i  MAX_MODULE_DISABLE_TIME) ? 0 : -EBUSY;
 }
 
 /**
diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c 
b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
index 02daacc..20e45a6 100644
--- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
@@ -30,6 +30,7 @@
 #include plat/mmc.h
 #include plat/dmtimer.h
 #include plat/common.h
+#include plat/usb.h
 
 #include omap_hwmod_common_data.h
 


--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 09/11] ARM: OMAP4: clock data: add clockdomains for clocks used as main clocks

2012-06-07 Thread Paul Walmsley
Until the OMAP4 code is converted to disable the use of the clock
framework-based clockdomain enable/disable sequence, any clock used as
a hwmod main_clk must have a clockdomain associated with it.  This
patch populates some clock structure clockdomain names to resolve the
following warnings during kernel init:

omap_hwmod: dpll_mpu_m2_ck: missing clockdomain for dpll_mpu_m2_ck.
omap_hwmod: trace_clk_div_ck: missing clockdomain for trace_clk_div_ck.
omap_hwmod: l3_div_ck: missing clockdomain for l3_div_ck.
omap_hwmod: ddrphy_ck: missing clockdomain for ddrphy_ck.

Signed-off-by: Paul Walmsley p...@pwsan.com
Cc: Rajendra Nayak rna...@ti.com
Cc: Benoît Cousson b-cous...@ti.com
---
 arch/arm/mach-omap2/clock44xx_data.c |5 +
 1 file changed, 5 insertions(+)

diff --git a/arch/arm/mach-omap2/clock44xx_data.c 
b/arch/arm/mach-omap2/clock44xx_data.c
index 2172f66..e2b701e 100644
--- a/arch/arm/mach-omap2/clock44xx_data.c
+++ b/arch/arm/mach-omap2/clock44xx_data.c
@@ -84,6 +84,7 @@ static struct clk slimbus_clk = {
 
 static struct clk sys_32k_ck = {
.name   = sys_32k_ck,
+   .clkdm_name = prm_clkdm,
.rate   = 32768,
.ops= clkops_null,
 };
@@ -512,6 +513,7 @@ static struct clk ddrphy_ck = {
.name   = ddrphy_ck,
.parent = dpll_core_m2_ck,
.ops= clkops_null,
+   .clkdm_name = l3_emif_clkdm,
.fixed_div  = 2,
.recalc = omap_fixed_divisor_recalc,
 };
@@ -769,6 +771,7 @@ static const struct clksel dpll_mpu_m2_div[] = {
 static struct clk dpll_mpu_m2_ck = {
.name   = dpll_mpu_m2_ck,
.parent = dpll_mpu_ck,
+   .clkdm_name = cm_clkdm,
.clksel = dpll_mpu_m2_div,
.clksel_reg = OMAP4430_CM_DIV_M2_DPLL_MPU,
.clksel_mask= OMAP4430_DPLL_CLKOUT_DIV_MASK,
@@ -1149,6 +1152,7 @@ static const struct clksel l3_div_div[] = {
 static struct clk l3_div_ck = {
.name   = l3_div_ck,
.parent = div_core_ck,
+   .clkdm_name = cm_clkdm,
.clksel = l3_div_div,
.clksel_reg = OMAP4430_CM_CLKSEL_CORE,
.clksel_mask= OMAP4430_CLKSEL_L3_MASK,
@@ -2824,6 +2828,7 @@ static const struct clksel trace_clk_div_div[] = {
 static struct clk trace_clk_div_ck = {
.name   = trace_clk_div_ck,
.parent = pmd_trace_clk_mux_ck,
+   .clkdm_name = emu_sys_clkdm,
.clksel = trace_clk_div_div,
.clksel_reg = OMAP4430_CM_EMU_DEBUGSS_CLKCTRL,
.clksel_mask= OMAP4430_CLKSEL_PMD_TRACE_CLK_MASK,


--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 07/11] ARM: OMAP: PM: Lock clocks list while generating summary

2012-06-07 Thread Paul Walmsley
From: Todd Poynor toddpoy...@google.com

Commit a53025724052b2b1edbc982a4a248784638f563d (OMAP: Add debugfs
node to show the summary of all clocks) introduced clock summary,
however, we are interested in seeing snapshot of the clock state, not
in dynamically changing clock configurations as the data provided by
clock summary will then be useless for debugging configuration
issues. So, hold the common lock when dumping the clock summary.

Cc: Paul Walmsley p...@pwsan.com
Cc: Tony Lindgren t...@atomide.com
Signed-off-by: Todd Poynor toddpoy...@google.com
[n...@ti.com: added commit message]
Signed-off-by: Nishanth Menon n...@ti.com
[p...@pwsan.com: minor edits to commit message]
Signed-off-by: Paul Walmsley p...@pwsan.com
---
 arch/arm/plat-omap/clock.c |2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm/plat-omap/clock.c b/arch/arm/plat-omap/clock.c
index 62ec5c4..706b7e2 100644
--- a/arch/arm/plat-omap/clock.c
+++ b/arch/arm/plat-omap/clock.c
@@ -461,6 +461,7 @@ static int clk_dbg_show_summary(struct seq_file *s, void 
*unused)
struct clk *c;
struct clk *pa;
 
+   mutex_lock(clocks_mutex);
seq_printf(s, %-30s %-30s %-10s %s\n,
clock-name, parent-name, rate, use-count);
 
@@ -469,6 +470,7 @@ static int clk_dbg_show_summary(struct seq_file *s, void 
*unused)
seq_printf(s, %-30s %-30s %-10lu %d\n,
c-name, pa ? pa-name : none, c-rate, c-usecount);
}
+   mutex_unlock(clocks_mutex);
 
return 0;
 }


--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 02/11] ARM: OMAP4+: AESS: enable internal auto-gating during initial setup

2012-06-07 Thread Paul Walmsley
Enable the AESS auto-gating control bit during AESS hwmod setup.  This
fixes the following boot warning on OMAP4:

omap_hwmod: aess: _wait_target_disable failed

Without this patch, the AESS IP block does not indicate to the PRCM
that it is idle after it is reset.  This prevents some types of SoC
power management until something sets the auto-gating control bit.

Signed-off-by: Paul Walmsley p...@pwsan.com
Cc: Benoît Cousson b-cous...@ti.com
Cc: Péter Ujfalusi peter.ujfal...@ti.com
---
 arch/arm/mach-omap2/Makefile   |2 +
 arch/arm/mach-omap2/aess.c |   55 
 arch/arm/mach-omap2/common.h   |2 +
 arch/arm/mach-omap2/omap_hwmod_44xx_data.c |2 +
 4 files changed, 60 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm/mach-omap2/aess.c

diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
index fa742f3..bc2ac4f 100644
--- a/arch/arm/mach-omap2/Makefile
+++ b/arch/arm/mach-omap2/Makefile
@@ -4,7 +4,7 @@
 
 # Common support
 obj-y := id.o io.o control.o mux.o devices.o serial.o gpmc.o timer.o pm.o \
-common.o gpio.o dma.o wd_timer.o display.o i2c.o hdq1w.o
+common.o gpio.o dma.o wd_timer.o display.o i2c.o hdq1w.o aess.o
 
 omap-2-3-common= irq.o sdrc.o
 hwmod-common   = omap_hwmod.o \
diff --git a/arch/arm/mach-omap2/aess.c b/arch/arm/mach-omap2/aess.c
new file mode 100644
index 000..d5ca3d2
--- /dev/null
+++ b/arch/arm/mach-omap2/aess.c
@@ -0,0 +1,55 @@
+/*
+ * AESS IP block integration
+ *
+ * Copyright (C) 2012 Texas Instruments, Inc.
+ * Paul Walmsley
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+
+#include linux/kernel.h
+
+#include plat/omap_hwmod.h
+
+#include common.h
+
+/*
+ * AESS_AUTO_GATING_ENABLE_OFFSET: offset in bytes of the AESS IP
+ * block's AESS_AUTO_GATING_ENABLE__1 register from the IP block's
+ * base address
+ */
+#define AESS_AUTO_GATING_ENABLE_OFFSET 0x07c
+
+/* Register bitfields in the AESS_AUTO_GATING_ENABLE__1 register */
+#define AESS_AUTO_GATING_ENABLE_SHIFT  0
+
+/**
+ * omap_aess_preprogram - enable AESS internal autogating
+ * @oh: struct omap_hwmod *
+ *
+ * Since the AESS will not IdleAck to the PRCM until its internal
+ * autogating is enabled, we must enable autogating during the initial
+ * AESS hwmod setup.  Returns 0.
+ */
+int omap_aess_preprogram(struct omap_hwmod *oh)
+{
+   u32 v;
+
+   /* Set AESS_AUTO_GATING_ENABLE__1.ENABLE to allow idle entry */
+   v = 1  AESS_AUTO_GATING_ENABLE_SHIFT;
+   omap_hwmod_write(v, oh, AESS_AUTO_GATING_ENABLE_OFFSET);
+
+   return 0;
+}
diff --git a/arch/arm/mach-omap2/common.h b/arch/arm/mach-omap2/common.h
index be9dfd1..d9b8b06 100644
--- a/arch/arm/mach-omap2/common.h
+++ b/arch/arm/mach-omap2/common.h
@@ -304,5 +304,7 @@ extern void omap_sdrc_init(struct omap_sdrc_params 
*sdrc_cs0,
 struct omap2_hsmmc_info;
 extern int omap4_twl6030_hsmmc_init(struct omap2_hsmmc_info *controllers);
 
+extern int omap_aess_preprogram(struct omap_hwmod *oh);
+
 #endif /* __ASSEMBLER__ */
 #endif /* __ARCH_ARM_MACH_OMAP2PLUS_COMMON_H */
diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c 
b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
index 950454a..4a2f2cc 100644
--- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
@@ -39,6 +39,7 @@
 #include prm44xx.h
 #include prm-regbits-44xx.h
 #include wd_timer.h
+#include common.h
 
 /* Base offset for all OMAP4 interrupts external to MPUSS */
 #define OMAP44XX_IRQ_GIC_START 32
@@ -313,6 +314,7 @@ static struct omap_hwmod_class_sysconfig omap44xx_aess_sysc 
= {
 static struct omap_hwmod_class omap44xx_aess_hwmod_class = {
.name   = aess,
.sysc   = omap44xx_aess_sysc,
+   .setup_preprogram = omap_aess_preprogram,
 };
 
 /* aess */


--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] ARM: omap: clock: Get rid of unwanted clkdm assocations within clks

2012-06-07 Thread Rajendra Nayak

Hi Paul,

On Thursday 17 May 2012 03:54 PM, Rajendra Nayak wrote:

clkdm assocations with clocks in the clock framework are useful
only for 'gate' clocks which have enable/disable ops populated.
Get rid of the clkdm_names populated in any other type of clocks.


Any comments on this one?

regards,
Rajendra


Signed-off-by: Rajendra Nayakrna...@ti.com
---
  arch/arm/mach-omap2/clock2420_data.c |   16 
  arch/arm/mach-omap2/clock2430_data.c |   15 ---
  arch/arm/mach-omap2/clock3xxx_data.c |   44 --
  3 files changed, 0 insertions(+), 75 deletions(-)

diff --git a/arch/arm/mach-omap2/clock2420_data.c 
b/arch/arm/mach-omap2/clock2420_data.c
index bace930..914d12a 100644
--- a/arch/arm/mach-omap2/clock2420_data.c
+++ b/arch/arm/mach-omap2/clock2420_data.c
@@ -56,14 +56,12 @@ static struct clk func_32k_ck = {
.name   = func_32k_ck,
.ops=clkops_null,
.rate   = 32768,
-   .clkdm_name = wkup_clkdm,
  };

  static struct clk secure_32k_ck = {
.name   = secure_32k_ck,
.ops=clkops_null,
.rate   = 32768,
-   .clkdm_name = wkup_clkdm,
  };

  /* Typical 12/13MHz in standalone mode, will be 26Mhz in chassis mode */
@@ -79,7 +77,6 @@ static struct clk sys_ck = {  /* (*12, *13, 19.2, 26, 
38.4)MHz */
.name   = sys_ck,   /* ~ ref_clk also */
.ops=clkops_null,
.parent =osc_ck,
-   .clkdm_name = wkup_clkdm,
.recalc =omap2xxx_sys_clk_recalc,
  };

@@ -87,7 +84,6 @@ static struct clk alt_ck = {  /* Typical 54M or 48M, 
may not exist */
.name   = alt_ck,
.ops=clkops_null,
.rate   = 5400,
-   .clkdm_name = wkup_clkdm,
  };

  /* Optional external clock input for McBSP CLKS */
@@ -180,7 +176,6 @@ static struct clk func_54m_ck = {
.name   = func_54m_ck,
.ops=clkops_null,
.parent =apll54_ck,/* can also be alt_clk */
-   .clkdm_name = wkup_clkdm,
.init   =omap2_init_clksel_parent,
.clksel_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL1),
.clksel_mask= OMAP24XX_54M_SOURCE_MASK,
@@ -192,7 +187,6 @@ static struct clk core_ck = {
.name   = core_ck,
.ops=clkops_null,
.parent =dpll_ck,  /* can also be 32k */
-   .clkdm_name = wkup_clkdm,
.recalc =followparent_recalc,
  };

@@ -200,7 +194,6 @@ static struct clk func_96m_ck = {
.name   = func_96m_ck,
.ops=clkops_null,
.parent =apll96_ck,
-   .clkdm_name = wkup_clkdm,
.recalc =followparent_recalc,
  };

@@ -226,7 +219,6 @@ static struct clk func_48m_ck = {
.name   = func_48m_ck,
.ops=clkops_null,
.parent =apll96_ck, /* 96M or Alt */
-   .clkdm_name = wkup_clkdm,
.init   =omap2_init_clksel_parent,
.clksel_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL1),
.clksel_mask= OMAP24XX_48M_SOURCE_MASK,
@@ -241,7 +233,6 @@ static struct clk func_12m_ck = {
.ops=clkops_null,
.parent =func_48m_ck,
.fixed_div  = 4,
-   .clkdm_name = wkup_clkdm,
.recalc =omap_fixed_divisor_recalc,
  };

@@ -323,7 +314,6 @@ static struct clk sys_clkout = {
.name   = sys_clkout,
.ops=clkops_null,
.parent =sys_clkout_src,
-   .clkdm_name = wkup_clkdm,
.clksel_reg = OMAP2420_PRCM_CLKOUT_CTRL,
.clksel_mask= OMAP24XX_CLKOUT_DIV_MASK,
.clksel = sys_clkout_clksel,
@@ -359,7 +349,6 @@ static struct clk sys_clkout2 = {
.name   = sys_clkout2,
.ops=clkops_null,
.parent =sys_clkout2_src,
-   .clkdm_name = wkup_clkdm,
.clksel_reg = OMAP2420_PRCM_CLKOUT_CTRL,
.clksel_mask= OMAP2420_CLKOUT2_DIV_MASK,
.clksel = sys_clkout2_clksel,
@@ -407,7 +396,6 @@ static struct clk mpu_ck = {/* Control cpu */
.name   = mpu_ck,
.ops=clkops_null,
.parent =core_ck,
-   .clkdm_name = mpu_clkdm,
.init   =omap2_init_clksel_parent,
.clksel_reg = OMAP_CM_REGADDR(MPU_MOD, CM_CLKSEL),
.clksel_mask= OMAP24XX_CLKSEL_MPU_MASK,
@@ -541,7 +529,6 @@ static struct clk core_l3_ck = {/* Used for ick and 
fck, interconnect */
.name   = core_l3_ck,
.ops=clkops_null,
.parent =core_ck,
-   .clkdm_name = core_l3_clkdm,
.clksel_reg = OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL1),
.clksel_mask= OMAP24XX_CLKSEL_L3_MASK,
.clksel  

Re: [PATCH 09/11] ARM: OMAP4: clock data: add clockdomains for clocks used as main clocks

2012-06-07 Thread Rajendra Nayak

On Thursday 07 June 2012 11:43 AM, Paul Walmsley wrote:

Until the OMAP4 code is converted to disable the use of the clock
framework-based clockdomain enable/disable sequence, any clock used as
a hwmod main_clk must have a clockdomain associated with it.  This
patch populates some clock structure clockdomain names to resolve the
following warnings during kernel init:


But these associations are useless if the clock is not a 'gate' clock,
except for getting rid of these warnings.
Maybe we should make hwmod understand that not all clocks need to have
a clockdomain associated with it and stop complaining.



omap_hwmod: dpll_mpu_m2_ck: missing clockdomain for dpll_mpu_m2_ck.
omap_hwmod: trace_clk_div_ck: missing clockdomain for trace_clk_div_ck.
omap_hwmod: l3_div_ck: missing clockdomain for l3_div_ck.
omap_hwmod: ddrphy_ck: missing clockdomain for ddrphy_ck.

Signed-off-by: Paul Walmsleyp...@pwsan.com
Cc: Rajendra Nayakrna...@ti.com
Cc: Benoît Coussonb-cous...@ti.com
---
  arch/arm/mach-omap2/clock44xx_data.c |5 +
  1 file changed, 5 insertions(+)

diff --git a/arch/arm/mach-omap2/clock44xx_data.c 
b/arch/arm/mach-omap2/clock44xx_data.c
index 2172f66..e2b701e 100644
--- a/arch/arm/mach-omap2/clock44xx_data.c
+++ b/arch/arm/mach-omap2/clock44xx_data.c
@@ -84,6 +84,7 @@ static struct clk slimbus_clk = {

  static struct clk sys_32k_ck = {
.name   = sys_32k_ck,
+   .clkdm_name = prm_clkdm,
.rate   = 32768,
.ops=clkops_null,
  };
@@ -512,6 +513,7 @@ static struct clk ddrphy_ck = {
.name   = ddrphy_ck,
.parent =dpll_core_m2_ck,
.ops=clkops_null,
+   .clkdm_name = l3_emif_clkdm,
.fixed_div  = 2,
.recalc =omap_fixed_divisor_recalc,
  };
@@ -769,6 +771,7 @@ static const struct clksel dpll_mpu_m2_div[] = {
  static struct clk dpll_mpu_m2_ck = {
.name   = dpll_mpu_m2_ck,
.parent =dpll_mpu_ck,
+   .clkdm_name = cm_clkdm,
.clksel = dpll_mpu_m2_div,
.clksel_reg = OMAP4430_CM_DIV_M2_DPLL_MPU,
.clksel_mask= OMAP4430_DPLL_CLKOUT_DIV_MASK,
@@ -1149,6 +1152,7 @@ static const struct clksel l3_div_div[] = {
  static struct clk l3_div_ck = {
.name   = l3_div_ck,
.parent =div_core_ck,
+   .clkdm_name = cm_clkdm,
.clksel = l3_div_div,
.clksel_reg = OMAP4430_CM_CLKSEL_CORE,
.clksel_mask= OMAP4430_CLKSEL_L3_MASK,
@@ -2824,6 +2828,7 @@ static const struct clksel trace_clk_div_div[] = {
  static struct clk trace_clk_div_ck = {
.name   = trace_clk_div_ck,
.parent =pmd_trace_clk_mux_ck,
+   .clkdm_name = emu_sys_clkdm,
.clksel = trace_clk_div_div,
.clksel_reg = OMAP4430_CM_EMU_DEBUGSS_CLKCTRL,
.clksel_mask= OMAP4430_CLKSEL_PMD_TRACE_CLK_MASK,




--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


RE: [PATCH 05/11] ARM: OMAP2+: hwmod code/data: fix 32K sync timer

2012-06-07 Thread Hiremath, Vaibhav
On Thu, Jun 07, 2012 at 11:43:10, Paul Walmsley wrote:
 Kevin discovered that commit c8d82ff68fb6873691536cf33021977efbf5593c
 (ARM: OMAP2/3: hwmod data: Add 32k-sync timer data to hwmod
 database) broke CORE idle on OMAP3.  This prevents device low power
 states.
 
 The root cause is that the 32K sync timer IP block does not support
 smart-idle mode[1], and so the hwmod code keeps the IP block in
 no-idle mode while it is active.  This in turn prevents the WKUP
 clockdomain from transitioning to idle.  There is a hardcoded sleep
 dependency that prevents the CORE_L3 and CORE_CM clockdomains from
 transitioning to idle when the WKUP clockdomain is active[2], so the
 chip cannot enter any device low power states.
 
 It turns out that there is no need to take the 32k sync timer out of
 idle.  The IP block itself probably does not have any native idle
 handling at all, due to its simplicity.  Furthermore, the PRCM will
 never request target idle for this IP block while the kernel is
 running, due to the sleep dependency that prevents the WKUP
 clockdomain from idling while the CORE_L3 clockdomain is active.  So
 we can safely leave the 32k sync timer in target-no-idle mode, even
 while we continue to access it.
 
 This workaround is implemented by programming the force-idle mode for
 any IP block that only supports the force-idle and no-idle modes.  If
 an IP block is ever released that doesn't support smart-idle and
 requires no-idle mode to be programmed while it's in use, we'll have
 to change this behavior.
 

Isn't this impact AM33xx devices, where we do not support smart idle mode???
Anyway, I will also test it on both OMAP3EVM and AM33xx platform now...

Thanks,
Vaibhav

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] ARM: omap: clock: Get rid of unwanted clkdm assocations within clks

2012-06-07 Thread Paul Walmsley
Hi

On Thu, 7 Jun 2012, Rajendra Nayak wrote:

 On Thursday 17 May 2012 03:54 PM, Rajendra Nayak wrote:
  clkdm assocations with clocks in the clock framework are useful
  only for 'gate' clocks which have enable/disable ops populated.
  Get rid of the clkdm_names populated in any other type of clocks.

I don't really see the point in changing this before the common clock 
conversion.  The design of most of the current low-level OMAP PM layers 
was predicated on each clock belonging to a clockdomain.  The testing 
overhead of changing this before the common clock conversion is something 
that I don't have time for, and almost no one else seems interested in 
doing.

Your common clock conversion moots this patch anyway, right?

- Paul

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


RE: [PATCH 05/11] ARM: OMAP2+: hwmod code/data: fix 32K sync timer

2012-06-07 Thread Paul Walmsley
Hi

On Thu, 7 Jun 2012, Hiremath, Vaibhav wrote:

 Isn't this impact AM33xx devices, where we do not support smart idle mode???
 Anyway, I will also test it on both OMAP3EVM and AM33xx platform now...

Thanks, please let me know how your tests go.  If it doesn't work, we'll 
go back to the flag-based approach in the patch I posted already.  


- Paul
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 02/11] ARM: OMAP4+: AESS: enable internal auto-gating during initial setup

2012-06-07 Thread Tony Lindgren
* Paul Walmsley p...@pwsan.com [120606 23:26]:
 Enable the AESS auto-gating control bit during AESS hwmod setup.  This
 fixes the following boot warning on OMAP4:
 
 omap_hwmod: aess: _wait_target_disable failed
 
 Without this patch, the AESS IP block does not indicate to the PRCM
 that it is idle after it is reset.  This prevents some types of SoC
 power management until something sets the auto-gating control bit.

I don't like the idea of having custom platform init code for every driver
to reset it, let's see if there's some better way to deal with stuff like
this.

It seems that most/many IP blocks need their custom reset hacks, and it's
not limited to just few instances?

Maybe we can distribute custom hacks like this to the drivers? If there is
no generic way to reset some IP block, then the driver should pass it's
whatever workaround bits/methdod/ to the bus level (hwmod) code during the
init rather than piling up all the possible hacks to the bus level code.

This way the driver init can still do the bus level reset during it's init,
and bail out after that if the module is not in use for the board in question.
That is already being flagged in device tree with status = disable flag,
and can also passed in platform data if necessary.

AFAIK there's no need to reset the IP blocks before the driver init, it's
really needed for PM. So it's not needed early on, and it's OK to require
running  the driver init for driver modules that are not in use to reset
them properly. After all, the hardware is on the device, even if it's not
being used.

Regards,

Tony
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 04/11] ARM: OMAP2+: usb_host_fs: add custom reset for usb_host_fs (fsusb)

2012-06-07 Thread Tony Lindgren
* Paul Walmsley p...@pwsan.com [120606 23:26]:
 From: Tero Kristo t-kri...@ti.com
 
 Add a custom reset function for the usb_host_fs/fsusb IP block, and
 connect it to the OMAP4 FSUSB block.
 
 This is the first of two fixes required to get rid of the boot
 warning:
 
 omap_hwmod: usb_host_fs: _wait_target_disable failed
 
 and to allow the module to idle.
 
 It may be necessary to use this reset method for OMAP2xxx SoCs as
 well; this is left for a future patch.

Here too I think driver like features like this should live in the
driver init for omap OHCI driver. In the likely case that FS OHCI is
not in use on the board, the OHCI glue can just reset it.
 
 +/* HCCOMMANDSTATUS: the register offset of the HCCOMMANDSTATUS register */
 +#define HCCOMMANDSTATUS  0x0008
 +
 +/* HCCOMMANDSTATUS_HCR: the bitmask of the host controller reset flag */
 +#define HCCOMMANDSTATUS_HCR_MASK (1  0)

I don't think the bus layer code should need to know anything about driver
specific registers.

 + omap_hwmod_write(HCCOMMANDSTATUS_HCR_MASK, oh, HCCOMMANDSTATUS);
 +
 + omap_test_timeout(!(omap_hwmod_read(oh, HCCOMMANDSTATUS)
 +  HCCOMMANDSTATUS_HCR_MASK),
 +   MAX_MODULE_SOFTRESET_WAIT, c);
 +

These should be accessed by the driver in a standard way after ioremapping
the device.

Tony
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 02/11] ARM: OMAP4+: AESS: enable internal auto-gating during initial setup

2012-06-07 Thread Paul Walmsley
On Thu, 7 Jun 2012, Tony Lindgren wrote:

 It seems that most/many IP blocks need their custom reset hacks, and 
 it's not limited to just few instances?

Only four out of the fifty-seven omap_hwmod_classes defined in 
mach-omap2/omap_hwmod_44xx_data.c after this series have custom reset 
functions used:

$ fgrep 'struct omap_hwmod_class ' arch/arm/mach-omap2/omap_hwmod_44xx_data.c | 
wc -l
57
$ fgrep '.reset' arch/arm/mach-omap2/omap_hwmod_44xx_data.c | wc -l
4

That's 7% of the classes.  In terms of the total number of IP block 
instances that use custom reset functions viewed against the total number 
of instances on the chip, the percentage is even smaller.

 AFAIK there's no need to reset the IP blocks before the driver init, 
 it's really needed for PM. So it's not needed early on, and it's OK to 
 require running the driver init for driver modules that are not in use 
 to reset them properly. After all, the hardware is on the device, even 
 if it's not being used.

I don't think I'm following you.  It's not just PM; the problem is also 
with kexec or buggy bootloaders.  If an IP block isn't reset when the 
kernel boots, and is doing DMA or anything else that could affect the 
reset of the system, it could easily cause unpredictable behavior or 
crashes in unrelated kernel code.

It's also worth mentioning that many IP blocks, such as AESS, don't have 
Linux drivers.


- Paul
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 04/11] ARM: OMAP2+: usb_host_fs: add custom reset for usb_host_fs (fsusb)

2012-06-07 Thread Felipe Balbi
Hi,

On Thu, Jun 07, 2012 at 12:31:13AM -0700, Tony Lindgren wrote:
 * Paul Walmsley p...@pwsan.com [120606 23:26]:
  From: Tero Kristo t-kri...@ti.com
  
  Add a custom reset function for the usb_host_fs/fsusb IP block, and
  connect it to the OMAP4 FSUSB block.
  
  This is the first of two fixes required to get rid of the boot
  warning:
  
  omap_hwmod: usb_host_fs: _wait_target_disable failed
  
  and to allow the module to idle.
  
  It may be necessary to use this reset method for OMAP2xxx SoCs as
  well; this is left for a future patch.
 
 Here too I think driver like features like this should live in the
 driver init for omap OHCI driver. In the likely case that FS OHCI is
 not in use on the board, the OHCI glue can just reset it.

this I don't agree. It means we will have to add some OHCI code even
when OHCI is disabled.

  +/* HCCOMMANDSTATUS: the register offset of the HCCOMMANDSTATUS register */
  +#define HCCOMMANDSTATUS0x0008
  +
  +/* HCCOMMANDSTATUS_HCR: the bitmask of the host controller reset flag */
  +#define HCCOMMANDSTATUS_HCR_MASK   (1  0)
 
 I don't think the bus layer code should need to know anything about driver
 specific registers.
 
  +   omap_hwmod_write(HCCOMMANDSTATUS_HCR_MASK, oh, HCCOMMANDSTATUS);
  +
  +   omap_test_timeout(!(omap_hwmod_read(oh, HCCOMMANDSTATUS)
  +HCCOMMANDSTATUS_HCR_MASK),
  + MAX_MODULE_SOFTRESET_WAIT, c);
  +
 
 These should be accessed by the driver in a standard way after ioremapping
 the device.

agree.

-- 
balbi


signature.asc
Description: Digital signature


Re: [PATCH 04/11] ARM: OMAP2+: usb_host_fs: add custom reset for usb_host_fs (fsusb)

2012-06-07 Thread Paul Walmsley
On Thu, 7 Jun 2012, Tony Lindgren wrote:

 Here too I think driver like features like this should live in the
 driver init for omap OHCI driver. In the likely case that FS OHCI is
 not in use on the board, the OHCI glue can just reset it.

What if the driver is not compiled into the kernel, but instead is built 
as a loadable module?


- Paul
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 02/11] ARM: OMAP4+: AESS: enable internal auto-gating during initial setup

2012-06-07 Thread Tony Lindgren
* Paul Walmsley p...@pwsan.com [120607 00:35]:
 On Thu, 7 Jun 2012, Tony Lindgren wrote:
 
  It seems that most/many IP blocks need their custom reset hacks, and 
  it's not limited to just few instances?
 
 Only four out of the fifty-seven omap_hwmod_classes defined in 
 mach-omap2/omap_hwmod_44xx_data.c after this series have custom reset 
 functions used:
 
 $ fgrep 'struct omap_hwmod_class ' arch/arm/mach-omap2/omap_hwmod_44xx_data.c 
 | wc -l
 57
 $ fgrep '.reset' arch/arm/mach-omap2/omap_hwmod_44xx_data.c | wc -l
 4
 
 That's 7% of the classes.  In terms of the total number of IP block 
 instances that use custom reset functions viewed against the total number 
 of instances on the chip, the percentage is even smaller.

OK so that's not too bad then. But there's also the omap2_wd_timer_disable
pre_shutdown too. And there's also the sysconfig autoidle bit for each driver
that we're tweaking in the bus level code?

If we can remove the ioremapping and accessing driver registers in the bus
level code things get much simpler for the bus level code.

  AFAIK there's no need to reset the IP blocks before the driver init, 
  it's really needed for PM. So it's not needed early on, and it's OK to 
  require running the driver init for driver modules that are not in use 
  to reset them properly. After all, the hardware is on the device, even 
  if it's not being used.
 
 I don't think I'm following you.  It's not just PM; the problem is also 
 with kexec or buggy bootloaders.  If an IP block isn't reset when the 
 kernel boots, and is doing DMA or anything else that could affect the 
 reset of the system, it could easily cause unpredictable behavior or 
 crashes in unrelated kernel code.

Still sounds like the responsibility of the bootloaders and drivers to
set things up properly, that's the standard behaviour.
 
 It's also worth mentioning that many IP blocks, such as AESS, don't have 
 Linux drivers.

Sounds like it should have a minimal driver then, just to reset it if
nothing else.

Regards,

Tony
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 04/11] ARM: OMAP2+: usb_host_fs: add custom reset for usb_host_fs (fsusb)

2012-06-07 Thread Tony Lindgren
* Paul Walmsley p...@pwsan.com [120607 00:44]:
 On Thu, 7 Jun 2012, Tony Lindgren wrote:
 
  Here too I think driver like features like this should live in the
  driver init for omap OHCI driver. In the likely case that FS OHCI is
  not in use on the board, the OHCI glue can just reset it.
 
 What if the driver is not compiled into the kernel, but instead is built 
 as a loadable module?

You can still have a core piece of the driver that's always built in, such
as omap-ohci-common. But it should live under drivers, not in the bus level
code. Or you can insmod/rmmod it to reset things properly.

Regards,

Tony
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 04/11] ARM: OMAP2+: usb_host_fs: add custom reset for usb_host_fs (fsusb)

2012-06-07 Thread Tony Lindgren
* Felipe Balbi ba...@ti.com [120607 00:39]:
 Hi,
 
 On Thu, Jun 07, 2012 at 12:31:13AM -0700, Tony Lindgren wrote:
  * Paul Walmsley p...@pwsan.com [120606 23:26]:
   From: Tero Kristo t-kri...@ti.com
   
   Add a custom reset function for the usb_host_fs/fsusb IP block, and
   connect it to the OMAP4 FSUSB block.
   
   This is the first of two fixes required to get rid of the boot
   warning:
   
   omap_hwmod: usb_host_fs: _wait_target_disable failed
   
   and to allow the module to idle.
   
   It may be necessary to use this reset method for OMAP2xxx SoCs as
   well; this is left for a future patch.
  
  Here too I think driver like features like this should live in the
  driver init for omap OHCI driver. In the likely case that FS OHCI is
  not in use on the board, the OHCI glue can just reset it.
 
 this I don't agree. It means we will have to add some OHCI code even
 when OHCI is disabled.

That's because the bus level code alone is not enough for the reset and
driver features are needed to reset it. Nothing wrong with the code itself,
it should be just something that's part of the driver rather than the bus
level code. It could be always built in for sure even if it lives under
drivers.

Tony 
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 04/11] ARM: OMAP2+: usb_host_fs: add custom reset for usb_host_fs (fsusb)

2012-06-07 Thread Cousson, Benoit

On 6/7/2012 9:55 AM, Felipe Balbi wrote:

On Thu, Jun 07, 2012 at 12:51:58AM -0700, Tony Lindgren wrote:

* Paul Walmsleyp...@pwsan.com  [120607 00:44]:

On Thu, 7 Jun 2012, Tony Lindgren wrote:


Here too I think driver like features like this should live in the
driver init for omap OHCI driver. In the likely case that FS OHCI is
not in use on the board, the OHCI glue can just reset it.


What if the driver is not compiled into the kernel, but instead is built
as a loadable module?


You can still have a core piece of the driver that's always built in, such
as omap-ohci-common. But it should live under drivers, not in the bus level
code. Or you can insmod/rmmod it to reset things properly.


that's such a hack... both solutions are quite hacky. The only problem
here is because some bootloaders are leaving controller in an unknown
state and I guess to be completely safe, resets should be done before
any driver kicks in.

But, driver will probably reset again the IP block during probe...


Ideally it should be done only in the probe if needed. In the case of 
the DSS, the bootloader can init it with a splash screen and we do not 
want to blindly reset it and thus produce some ugly artifact on the screen.


In fact we should delay the reset to the very last moment and 
potentially reset the IPs not under driver control later after a couple 
of second for example.

It will avoid reseting every IP that will be handled properly by drivers.

Regards,
Benoit
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 04/11] ARM: OMAP2+: usb_host_fs: add custom reset for usb_host_fs (fsusb)

2012-06-07 Thread Tony Lindgren
* Cousson, Benoit b-cous...@ti.com [120607 01:07]:
 On 6/7/2012 9:55 AM, Felipe Balbi wrote:
 On Thu, Jun 07, 2012 at 12:51:58AM -0700, Tony Lindgren wrote:
 * Paul Walmsleyp...@pwsan.com  [120607 00:44]:
 On Thu, 7 Jun 2012, Tony Lindgren wrote:
 
 Here too I think driver like features like this should live in the
 driver init for omap OHCI driver. In the likely case that FS OHCI is
 not in use on the board, the OHCI glue can just reset it.
 
 What if the driver is not compiled into the kernel, but instead is built
 as a loadable module?
 
 You can still have a core piece of the driver that's always built in, such
 as omap-ohci-common. But it should live under drivers, not in the bus level
 code. Or you can insmod/rmmod it to reset things properly.
 
 that's such a hack... both solutions are quite hacky. The only problem
 here is because some bootloaders are leaving controller in an unknown
 state and I guess to be completely safe, resets should be done before
 any driver kicks in.
 
 But, driver will probably reset again the IP block during probe...

Well I see two advantages moving the reset and idle responsibility to
the drivers:

1. We can avoid ioremapping the devices in the bus level code and
   simplify things

2. We don't need to duplicate driver code into the bus level code
 
 Ideally it should be done only in the probe if needed. In the case
 of the DSS, the bootloader can init it with a splash screen and we
 do not want to blindly reset it and thus produce some ugly artifact
 on the screen.
 
 In fact we should delay the reset to the very last moment and
 potentially reset the IPs not under driver control later after a
 couple of second for example.
 It will avoid reseting every IP that will be handled properly by drivers.

Good point.

Regards,

Tony
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 04/11] ARM: OMAP2+: usb_host_fs: add custom reset for usb_host_fs (fsusb)

2012-06-07 Thread Felipe Balbi
On Thu, Jun 07, 2012 at 10:02:51AM +0200, Cousson, Benoit wrote:
 On 6/7/2012 9:55 AM, Felipe Balbi wrote:
 On Thu, Jun 07, 2012 at 12:51:58AM -0700, Tony Lindgren wrote:
 * Paul Walmsleyp...@pwsan.com  [120607 00:44]:
 On Thu, 7 Jun 2012, Tony Lindgren wrote:
 
 Here too I think driver like features like this should live in the
 driver init for omap OHCI driver. In the likely case that FS OHCI is
 not in use on the board, the OHCI glue can just reset it.
 
 What if the driver is not compiled into the kernel, but instead is built
 as a loadable module?
 
 You can still have a core piece of the driver that's always built in, such
 as omap-ohci-common. But it should live under drivers, not in the bus level
 code. Or you can insmod/rmmod it to reset things properly.
 
 that's such a hack... both solutions are quite hacky. The only problem
 here is because some bootloaders are leaving controller in an unknown
 state and I guess to be completely safe, resets should be done before
 any driver kicks in.
 
 But, driver will probably reset again the IP block during probe...
 
 Ideally it should be done only in the probe if needed. In the case of
 the DSS, the bootloader can init it with a splash screen and we do
 not want to blindly reset it and thus produce some ugly artifact on
 the screen.
 
 In fact we should delay the reset to the very last moment and
 potentially reset the IPs not under driver control later after a
 couple of second for example.
 It will avoid reseting every IP that will be handled properly by drivers.

you could have a late_initcall() that will iterate over hwmods and reset
the ones which aren't used. That would mean adding some extra code to
omap_device_build_ss() which would set a flag on each hwmod, or
something similar.

-- 
balbi


signature.asc
Description: Digital signature


RE: Please help! AM35xx mm/slab.c BUG

2012-06-07 Thread Mohammed, Afzal
Hi ,

On Wed, Jun 06, 2012 at 13:21:23, CF Adad wrote:

 Thanks again.  I'm really starting to think the GPMC almost has to be 
 contributing.

Does adding cycle2cycle delay / bus turnaround prevent the issue ?,

SMSC datasheet mentions about special restrictions on back to back read
and write-read, reading BYTE_TEST should take care of it, not sure whether
driver takes care of all scenarios as per datasheet.

Perhaps cycle2cycledelay would help us achieve it if driver doesn't
take care of it.

Regards
Afzal
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 04/11] ARM: OMAP2+: usb_host_fs: add custom reset for usb_host_fs (fsusb)

2012-06-07 Thread Paul Walmsley
On Thu, 7 Jun 2012, Tony Lindgren wrote:

 * Paul Walmsley p...@pwsan.com [120607 00:44]:
  On Thu, 7 Jun 2012, Tony Lindgren wrote:
  
   Here too I think driver like features like this should live in the
   driver init for omap OHCI driver. In the likely case that FS OHCI is
   not in use on the board, the OHCI glue can just reset it.
  
  What if the driver is not compiled into the kernel, but instead is built 
  as a loadable module?
 
 You can still have a core piece of the driver that's always built in, such
 as omap-ohci-common. But it should live under drivers, not in the bus level
 code. Or you can insmod/rmmod it to reset things properly.

Do you know of any device drivers that do this now, with a core built-in 
piece separate from a dynamically loadable part?

Seems like it would be tricky to avoid linking in the entire driver, due 
to the symbol dependencies.  Either that, or an extra, largely useless, 
layer of indirection would be needed in the shim layer.


- Paul
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[CFT] DMA engine patches

2012-06-07 Thread Russell King - ARM Linux
I am intending to post the _entire_ set of DMA patches I have so far.
I'm going to be doing this in a slightly different way to normal,
because of the way the branches are structured.

What will come first is a set of three common patches to all the
branches.  Following on from that will be the individual sets for
sa11x0, pl08x and OMAP.

These are for testing, and are based on v3.5-rc1.

 drivers/dma/Kconfig  |4 +
 drivers/dma/Makefile |1 +
 drivers/dma/sa11x0-dma.c |  249 ++---
 drivers/dma/virt-dma.c   |  123 +++
 drivers/dma/virt-dma.h   |  152 
 5 files changed, 358 insertions(+), 171 deletions(-)

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[CFT 2/3] dmaengine: virt-dma: vchan_find_desc()

2012-06-07 Thread Russell King
Add a function to find a descriptor within the depths of the
virtualized DMA channel support.  Needed for tx_status functionality.

Signed-off-by: Russell King rmk+ker...@arm.linux.org.uk
---
 drivers/dma/virt-dma.c |   13 +
 drivers/dma/virt-dma.h |2 +-
 2 files changed, 14 insertions(+), 1 deletions(-)

diff --git a/drivers/dma/virt-dma.c b/drivers/dma/virt-dma.c
index bd85b05..a8054fc 100644
--- a/drivers/dma/virt-dma.c
+++ b/drivers/dma/virt-dma.c
@@ -39,6 +39,19 @@ dma_cookie_t vchan_tx_submit(struct dma_async_tx_descriptor 
*tx)
 }
 EXPORT_SYMBOL_GPL(vchan_tx_submit);
 
+struct virt_dma_desc *vchan_find_desc(struct virt_dma_chan *vc,
+   dma_cookie_t cookie)
+{
+   struct virt_dma_desc *vd;
+
+   list_for_each_entry(vd, vc-desc_issued, node)
+   if (vd-tx.cookie == cookie)
+   return vd;
+
+   return NULL;
+}
+EXPORT_SYMBOL_GPL(vchan_find_desc);
+
 /*
  * This tasklet handles the completion of a DMA descriptor by
  * calling its callback and freeing it.
diff --git a/drivers/dma/virt-dma.h b/drivers/dma/virt-dma.h
index 825bb96..44ec57e 100644
--- a/drivers/dma/virt-dma.h
+++ b/drivers/dma/virt-dma.h
@@ -40,8 +40,8 @@ static inline struct virt_dma_chan *to_virt_chan(struct 
dma_chan *chan)
 }
 
 void vchan_dma_desc_free_list(struct virt_dma_chan *vc, struct list_head 
*head);
-
 void vchan_init(struct virt_dma_chan *vc, struct dma_device *dmadev);
+struct virt_dma_desc *vchan_find_desc(struct virt_dma_chan *, dma_cookie_t);
 
 /**
  * vchan_tx_prep - prepare a descriptor
-- 
1.7.4.4

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[CFT 3/3] dmaengine: virt-dma: add support for cyclic DMA periodic callbacks

2012-06-07 Thread Russell King
Add support for cyclic DMA's periodic callbacks.  Drivers are expected
to call vchan_cyclic_callback() when a period has completed, which will
schedule the tasklet to make the callback into the driver.

As callbacks are made from tasklet context, it is important to realise
that we don't guarantee a callback for each completed period, but for
N completed periods where N may be greater than one.

Signed-off-by: Russell King rmk+ker...@arm.linux.org.uk
---
 drivers/dma/virt-dma.c |   19 +++
 drivers/dma/virt-dma.h |   14 ++
 2 files changed, 29 insertions(+), 4 deletions(-)

diff --git a/drivers/dma/virt-dma.c b/drivers/dma/virt-dma.c
index a8054fc..6f80432 100644
--- a/drivers/dma/virt-dma.c
+++ b/drivers/dma/virt-dma.c
@@ -59,17 +59,28 @@ EXPORT_SYMBOL_GPL(vchan_find_desc);
 static void vchan_complete(unsigned long arg)
 {
struct virt_dma_chan *vc = (struct virt_dma_chan *)arg;
+   struct virt_dma_desc *vd;
+   dma_async_tx_callback cb = NULL;
+   void *cb_data = NULL;
LIST_HEAD(head);
 
spin_lock_irq(vc-lock);
list_splice_tail_init(vc-desc_completed, head);
+   vd = vc-cyclic;
+   if (vd) {
+   vc-cyclic = NULL;
+   cb = vd-tx.callback;
+   cb_data = vd-tx.callback_param;
+   }
spin_unlock_irq(vc-lock);
 
+   if (cb)
+   cb(cb_data);
+
while (!list_empty(head)) {
-   struct virt_dma_desc *vd = list_first_entry(head,
-   struct virt_dma_desc, node);
-   dma_async_tx_callback cb = vd-tx.callback;
-   void *cb_data = vd-tx.callback_param;
+   vd = list_first_entry(head, struct virt_dma_desc, node);
+   cb = vd-tx.callback;
+   cb_data = vd-tx.callback_param;
 
list_del(vd-node);
 
diff --git a/drivers/dma/virt-dma.h b/drivers/dma/virt-dma.h
index 44ec57e..85c19d6 100644
--- a/drivers/dma/virt-dma.h
+++ b/drivers/dma/virt-dma.h
@@ -32,6 +32,8 @@ struct virt_dma_chan {
struct list_head desc_submitted;
struct list_head desc_issued;
struct list_head desc_completed;
+
+   struct virt_dma_desc *cyclic;
 };
 
 static inline struct virt_dma_chan *to_virt_chan(struct dma_chan *chan)
@@ -92,6 +94,18 @@ static inline void vchan_cookie_complete(struct 
virt_dma_desc *vd)
 }
 
 /**
+ * vchan_cyclic_callback - report the completion of a period
+ * vd: virtual descriptor
+ */
+static inline void vchan_cyclic_callback(struct virt_dma_desc *vd)
+{
+   struct virt_dma_chan *vc = to_virt_chan(vd-tx.chan);
+
+   vc-cyclic = vd;
+   tasklet_schedule(vc-task);
+}
+
+/**
  * vchan_next_desc - peek at the next descriptor to be processed
  * vc: virtual channel to obtain descriptor from
  *
-- 
1.7.4.4

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[CFT] SA11x0 patches

2012-06-07 Thread Russell King - ARM Linux
Updates to the SA11x0 DMA engine driver.  This fixes the residue
calculation, and implements cyclic transfers.

 drivers/dma/sa11x0-dma.c |  153 --
 1 files changed, 121 insertions(+), 32 deletions(-)

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[CFT 1/2] dmaengine: sa11x0-dma: fix DMA residue support

2012-06-07 Thread Russell King
The semantics now implemented are:

- If the cookie has completed successfully, the residue will be zero.
- If the cookie is in progress or the channel is paused, it will be the
  number of bytes yet to be transferred. [*]
- If the cookie is queued, it will be the number of bytes in the
  descriptor.

* - where this is the number of bytes yet to be transferred to/from
  RAM.

Signed-off-by: Russell King rmk+ker...@arm.linux.org.uk
---
 drivers/dma/sa11x0-dma.c |   45 +
 1 files changed, 29 insertions(+), 16 deletions(-)

diff --git a/drivers/dma/sa11x0-dma.c b/drivers/dma/sa11x0-dma.c
index 5f1d2e6..db4fcbd 100644
--- a/drivers/dma/sa11x0-dma.c
+++ b/drivers/dma/sa11x0-dma.c
@@ -416,27 +416,47 @@ static enum dma_status sa11x0_dma_tx_status(struct 
dma_chan *chan,
struct sa11x0_dma_chan *c = to_sa11x0_dma_chan(chan);
struct sa11x0_dma_dev *d = to_sa11x0_dma(chan-device);
struct sa11x0_dma_phy *p;
-   struct sa11x0_dma_desc *txd;
+   struct virt_dma_desc *vd;
unsigned long flags;
enum dma_status ret;
-   size_t bytes = 0;
 
ret = dma_cookie_status(c-vc.chan, cookie, state);
if (ret == DMA_SUCCESS)
return ret;
 
+   if (!state)
+   return c-status;
+
spin_lock_irqsave(c-vc.lock, flags);
p = c-phy;
-   ret = c-status;
-   if (p) {
-   dma_addr_t addr = sa11x0_dma_pos(p);
 
-   dev_vdbg(d-slave.dev, tx_status: addr:%x\n, addr);
+   /*
+* If the cookie is on our issue queue, then the residue is
+* its total size.
+*/
+   vd = vchan_find_desc(c-vc, cookie);
+   if (vd) {
+   state-residue = container_of(vd, struct sa11x0_dma_desc, 
vd)-size;
+   } else if (!p) {
+   state-residue = 0;
+   } else {
+   struct sa11x0_dma_desc *txd;
+   size_t bytes = 0;
+
+   if (p-txd_done  p-txd_done-vd.tx.cookie == cookie)
+   txd = p-txd_done;
+   else if (p-txd_load  p-txd_load-vd.tx.cookie == cookie)
+   txd = p-txd_load;
+   else
+   txd = NULL;
 
-   txd = p-txd_done;
+   ret = c-status;
if (txd) {
+   dma_addr_t addr = sa11x0_dma_pos(p);
unsigned i;
 
+   dev_vdbg(d-slave.dev, tx_status: addr:%x\n, addr);
+
for (i = 0; i  txd-sglen; i++) {
dev_vdbg(d-slave.dev, tx_status: [%u] 
%x+%x\n,
i, txd-sg[i].addr, txd-sg[i].len);
@@ -459,18 +479,11 @@ static enum dma_status sa11x0_dma_tx_status(struct 
dma_chan *chan,
bytes += txd-sg[i].len;
}
}
-   if (txd != p-txd_load  p-txd_load)
-   bytes += p-txd_load-size;
-   }
-   list_for_each_entry(txd, c-vc.desc_issued, vd.node) {
-   bytes += txd-size;
+   state-residue = bytes;
}
spin_unlock_irqrestore(c-vc.lock, flags);
 
-   if (state)
-   state-residue = bytes;
-
-   dev_vdbg(d-slave.dev, tx_status: bytes 0x%zx\n, bytes);
+   dev_vdbg(d-slave.dev, tx_status: bytes 0x%zx\n, state-residue);
 
return ret;
 }
-- 
1.7.4.4

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[CFT 2/2] dmaengine: sa11x0-dma: add cyclic DMA support

2012-06-07 Thread Russell King
Add support for cyclic DMA on sa11x0 platforms.  This follows the
discussed behaviour that the callback will be called at some point
after period expires, and may coalesce multiple period expiries into
one callback (due to the tasklet behaviour.)

Signed-off-by: Russell King rmk+ker...@arm.linux.org.uk
---
 drivers/dma/sa11x0-dma.c |  108 +++---
 1 files changed, 92 insertions(+), 16 deletions(-)

diff --git a/drivers/dma/sa11x0-dma.c b/drivers/dma/sa11x0-dma.c
index db4fcbd..f5a7360 100644
--- a/drivers/dma/sa11x0-dma.c
+++ b/drivers/dma/sa11x0-dma.c
@@ -78,6 +78,8 @@ struct sa11x0_dma_desc {
 
u32 ddar;
size_t  size;
+   unsignedperiod;
+   boolcyclic;
 
unsignedsglen;
struct sa11x0_dma_sgsg[0];
@@ -178,19 +180,24 @@ static void noinline sa11x0_dma_start_sg(struct 
sa11x0_dma_phy *p,
return;
 
if (p-sg_load == txd-sglen) {
-   struct sa11x0_dma_desc *txn = sa11x0_dma_next_desc(c);
+   if (!txd-cyclic) {
+   struct sa11x0_dma_desc *txn = sa11x0_dma_next_desc(c);
 
-   /*
-* We have reached the end of the current descriptor.
-* Peek at the next descriptor, and if compatible with
-* the current, start processing it.
-*/
-   if (txn  txn-ddar == txd-ddar) {
-   txd = txn;
-   sa11x0_dma_start_desc(p, txn);
+   /*
+* We have reached the end of the current descriptor.
+* Peek at the next descriptor, and if compatible with
+* the current, start processing it.
+*/
+   if (txn  txn-ddar == txd-ddar) {
+   txd = txn;
+   sa11x0_dma_start_desc(p, txn);
+   } else {
+   p-txd_load = NULL;
+   return;
+   }
} else {
-   p-txd_load = NULL;
-   return;
+   /* Cyclic: reset back to beginning */
+   p-sg_load = 0;
}
}
 
@@ -224,13 +231,21 @@ static void noinline sa11x0_dma_complete(struct 
sa11x0_dma_phy *p,
struct sa11x0_dma_desc *txd = p-txd_done;
 
if (++p-sg_done == txd-sglen) {
-   vchan_cookie_complete(txd-vd);
+   if (!txd-cyclic) {
+   vchan_cookie_complete(txd-vd);
 
-   p-sg_done = 0;
-   p-txd_done = p-txd_load;
+   p-sg_done = 0;
+   p-txd_done = p-txd_load;
+
+   if (!p-txd_done)
+   tasklet_schedule(p-dev-task);
+   } else {
+   if ((p-sg_done % txd-period) == 0)
+   vchan_cyclic_callback(txd-vd);
 
-   if (!p-txd_done)
-   tasklet_schedule(p-dev-task);
+   /* Cyclic: reset back to beginning */
+   p-sg_done = 0;
+   }
}
 
sa11x0_dma_start_sg(p, c);
@@ -597,6 +612,65 @@ static struct dma_async_tx_descriptor 
*sa11x0_dma_prep_slave_sg(
return vchan_tx_prep(c-vc, txd-vd, flags);
 }
 
+static struct dma_async_tx_descriptor *sa11x0_dma_prep_dma_cyclic(
+   struct dma_chan *chan, dma_addr_t addr, size_t size, size_t period,
+   enum dma_transfer_direction dir, void *context)
+{
+   struct sa11x0_dma_chan *c = to_sa11x0_dma_chan(chan);
+   struct sa11x0_dma_desc *txd;
+   unsigned i, j, k, sglen, sgperiod;
+
+   /* SA11x0 channels can only operate in their native direction */
+   if (dir != (c-ddar  DDAR_RW ? DMA_DEV_TO_MEM : DMA_MEM_TO_DEV)) {
+   dev_err(chan-device-dev, vchan %p: bad DMA direction: 
DDAR:%08x dir:%u\n,
+   c-vc, c-ddar, dir);
+   return NULL;
+   }
+
+   sgperiod = DIV_ROUND_UP(period, DMA_MAX_SIZE  ~DMA_ALIGN);
+   sglen = size * sgperiod / period;
+
+   /* Do not allow zero-sized txds */
+   if (sglen == 0)
+   return NULL;
+
+   txd = kzalloc(sizeof(*txd) + sglen * sizeof(txd-sg[0]), GFP_ATOMIC);
+   if (!txd) {
+   dev_dbg(chan-device-dev, vchan %p: kzalloc failed\n, 
c-vc);
+   return NULL;
+   }
+
+   for (i = k = 0; i  size / period; i++) {
+   size_t tlen, len = period;
+
+   for (j = 0; j  sgperiod; j++, k++) {
+   tlen = len;
+
+   if (tlen  DMA_MAX_SIZE) {
+   unsigned mult = DIV_ROUND_UP(tlen, DMA_MAX_SIZE 
 ~DMA_ALIGN);
+   

Re: [PATCH 02/11] ARM: OMAP4+: AESS: enable internal auto-gating during initial setup

2012-06-07 Thread Paul Walmsley
On Thu, 7 Jun 2012, Tony Lindgren wrote:

 OK so that's not too bad then. But there's also the 
 omap2_wd_timer_disable pre_shutdown too. And there's also the sysconfig 
 autoidle bit for each driver that we're tweaking in the bus level code?

I think I lost your point here.  The ioremap() issue is separate from the 
reset functions, etc., in my view.  Moving the reset functions out to 
drivers/ seems potentially more reasonable than dropping the ioremap().

 If we can remove the ioremapping and accessing driver registers in the 
 bus level code things get much simpler for the bus level code.

That's like saying if PCI Configuration Header handling were to be moved 
into the driver code, then the PCI bus-level code would be much simpler 
:-)

The hwmod code ioremaps the device registers to handle the 
integration-level registers at the beginning of the device's address 
space.  These registers can be thought of as part of the PRCM, not part of 
the IP block.  It would have been better if TI had put these integration 
registers in a separate address space like PCI does.  But we are stuck 
with the existing hardware design.  The integration registers also differ 
from chip to chip even with the same underlying IP block, see for example 
the 32k sync timer.

The main reasons why these integration registers are handled now in common 
code are:

1. to avoid duplicating integration code between lots of different drivers 
   that is unrelated to the driver itself, such as bus-level reset

2. to ensure consistency of the OCP registers with the rest of the PM
   state

3. to avoid callbacks into drivers that might otherwise be needed for 
   bitfields like CLOCKACTIVITY 

4. to make it easier to debug integration problems with drivers

If we don't handle those registers in common code, the number of SoC 
integration workarounds that need to be placed into the drivers will 
increase.  For example, when OMAP4 added the smart-idle-with-wakeup and 
smart-standby-with-wakeup OCP idle modes, only a couple of files needed to 
be changed.  If those integration-level details were still in the drivers, 
a large number of files would need to be changed.  And $DEITY help us if 
the code sequence for dealing with those bits were to ever change in the 
future - we'd need to change a bunch of drivers, rather than just one or 
two files.  Also some people are going to need to audit the driver code 
from an integration level pretty carefully for PM to work consistently.

I suppose one option, if we were to have a real omap_device, would be to 
define callbacks for each driver to implement that would read and write 
the OCP header registers.  Then the omap_bus code could call those 
callbacks to handle the OCP register accesses, when called from the 
driver's PM runtime calls.  Adds another layer of indirection, but would 
localize IP block register accesses to the IP block's driver.

...

As far as the reset and preconfiguration aspects of the hwmod code go, 
they just happen to be possible since we're doing the ioremap anyway.  It 
can be ensured that no matter what drivers are present, or what the 
bootloader or previous OS did or didn't do, a minimal kernel should behave 
predictably.

It seems like it might be reasonable to move these to some built-in driver 
shim layer as you suggest in your other E-mail.  But that is assuming that 
it can be made to work without needless layers of indirection.  I don't 
know of any driver that does this now.  Maybe you know of one?


- Paul
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [CFT] PL08x patches

2012-06-07 Thread Russell King - ARM Linux
Here's the PL08x patches.

 drivers/dma/Kconfig|1 +
 drivers/dma/amba-pl08x.c   |  941 ++--
 include/linux/amba/pl08x.h |  156 +---
 3 files changed, 482 insertions(+), 616 deletions(-)

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[CFT 01/31] dmaengine: PL08x: remove runtime PM support

2012-06-07 Thread Russell King
The runtime PM support conflicts with the generic AMBA bus PM, and also
causes a potential deadlock with the PL011 driver as it results in
interrupts being enabled beneath a spinlock.

I don't presently see any solution to this other than by removing the
runtime PM support entirely from the DMA engine driver.  Alternative
suggestions welcome.

Acked-by: Linus Walleij linus.wall...@linaro.org
Signed-off-by: Russell King rmk+ker...@arm.linux.org.uk
---
 drivers/dma/amba-pl08x.c |   10 --
 1 files changed, 0 insertions(+), 10 deletions(-)

diff --git a/drivers/dma/amba-pl08x.c b/drivers/dma/amba-pl08x.c
index 49ecbbb..5586d9a 100644
--- a/drivers/dma/amba-pl08x.c
+++ b/drivers/dma/amba-pl08x.c
@@ -404,7 +404,6 @@ pl08x_get_phy_channel(struct pl08x_driver_data *pl08x,
return NULL;
}
 
-   pm_runtime_get_sync(pl08x-adev-dev);
return ch;
 }
 
@@ -418,8 +417,6 @@ static inline void pl08x_put_phy_channel(struct 
pl08x_driver_data *pl08x,
/* Stop the channel and clear its interrupts */
pl08x_terminate_phy_chan(pl08x, ch);
 
-   pm_runtime_put(pl08x-adev-dev);
-
/* Mark it as free */
ch-serving = NULL;
spin_unlock_irqrestore(ch-lock, flags);
@@ -1851,9 +1848,6 @@ static int pl08x_probe(struct amba_device *adev, const 
struct amba_id *id)
goto out_no_pl08x;
}
 
-   pm_runtime_set_active(adev-dev);
-   pm_runtime_enable(adev-dev);
-
/* Initialize memcpy engine */
dma_cap_set(DMA_MEMCPY, pl08x-memcpy.cap_mask);
pl08x-memcpy.dev = adev-dev;
@@ -2007,7 +2001,6 @@ static int pl08x_probe(struct amba_device *adev, const 
struct amba_id *id)
 amba_part(adev), amba_rev(adev),
 (unsigned long long)adev-res.start, adev-irq[0]);
 
-   pm_runtime_put(adev-dev);
return 0;
 
 out_no_slave_reg:
@@ -2026,9 +2019,6 @@ static int pl08x_probe(struct amba_device *adev, const 
struct amba_id *id)
dma_pool_destroy(pl08x-pool);
 out_no_lli_pool:
 out_no_platdata:
-   pm_runtime_put(adev-dev);
-   pm_runtime_disable(adev-dev);
-
kfree(pl08x);
 out_no_pl08x:
amba_release_regions(adev);
-- 
1.7.4.4

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[CFT 02/31] dmaengine: PL08x: fix missed dma_transfer_direction fixup

2012-06-07 Thread Russell King
db8196df4 (dmaengine: move drivers to dma_transfer_direction) missed
fixing up the DMA_NONE case.

Acked-by: Linus Walleij linus.wall...@linaro.org
Signed-off-by: Russell King rmk+ker...@arm.linux.org.uk
---
 drivers/dma/amba-pl08x.c |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/dma/amba-pl08x.c b/drivers/dma/amba-pl08x.c
index 5586d9a..f3ab004 100644
--- a/drivers/dma/amba-pl08x.c
+++ b/drivers/dma/amba-pl08x.c
@@ -1287,7 +1287,7 @@ static struct dma_async_tx_descriptor 
*pl08x_prep_dma_memcpy(
}
list_add_tail(dsg-node, txd-dsg_list);
 
-   txd-direction = DMA_NONE;
+   txd-direction = DMA_MEM_TO_MEM;
dsg-src_addr = src;
dsg-dst_addr = dest;
dsg-len = len;
-- 
1.7.4.4

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[CFT 03/31] dmaengine: PL08x: remove redundant spinlock

2012-06-07 Thread Russell King
The pl08x_driver_data spinlock is only ever initialized.  Nothing else
uses it.  Let's get rid of it.

Acked-by: Linus Walleij linus.wall...@linaro.org
Signed-off-by: Russell King rmk+ker...@arm.linux.org.uk
---
 drivers/dma/amba-pl08x.c |3 ---
 1 files changed, 0 insertions(+), 3 deletions(-)

diff --git a/drivers/dma/amba-pl08x.c b/drivers/dma/amba-pl08x.c
index f3ab004..9c5bae6 100644
--- a/drivers/dma/amba-pl08x.c
+++ b/drivers/dma/amba-pl08x.c
@@ -146,7 +146,6 @@ struct pl08x_driver_data {
int pool_ctr;
u8 lli_buses;
u8 mem_buses;
-   spinlock_t lock;
 };
 
 /*
@@ -1897,8 +1896,6 @@ static int pl08x_probe(struct amba_device *adev, const 
struct amba_id *id)
goto out_no_lli_pool;
}
 
-   spin_lock_init(pl08x-lock);
-
pl08x-base = ioremap(adev-res.start, resource_size(adev-res));
if (!pl08x-base) {
ret = -ENOMEM;
-- 
1.7.4.4

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[CFT 04/31] dmaengine: PL08x: remove circular_buffer boolean from channel data

2012-06-07 Thread Russell King
Circular buffers are not handled in this way; we have a separate API
call now to setup circular buffers.  So lets not mislead people with
this bool.

Acked-by: Linus Walleij linus.wall...@linaro.org
Signed-off-by: Russell King rmk+ker...@arm.linux.org.uk
---
 drivers/dma/amba-pl08x.c   |7 ---
 include/linux/amba/pl08x.h |4 
 2 files changed, 0 insertions(+), 11 deletions(-)

diff --git a/drivers/dma/amba-pl08x.c b/drivers/dma/amba-pl08x.c
index 9c5bae6..5821125 100644
--- a/drivers/dma/amba-pl08x.c
+++ b/drivers/dma/amba-pl08x.c
@@ -1701,13 +1701,6 @@ static int pl08x_dma_init_virtual_channels(struct 
pl08x_driver_data *pl08x,
return -ENOMEM;
}
}
-   if (chan-cd-circular_buffer) {
-   dev_err(pl08x-adev-dev,
-   channel %s: circular buffers not supported\n,
-   chan-name);
-   kfree(chan);
-   continue;
-   }
dev_dbg(pl08x-adev-dev,
 initialize virtual channel \%s\\n,
 chan-name);
diff --git a/include/linux/amba/pl08x.h b/include/linux/amba/pl08x.h
index 0254901..0f5b34d 100644
--- a/include/linux/amba/pl08x.h
+++ b/include/linux/amba/pl08x.h
@@ -51,9 +51,6 @@ enum {
  * can be the address of a FIFO register for burst requests for example.
  * This can be left undefined if the PrimeCell API is used for configuring
  * this.
- * @circular_buffer: whether the buffer passed in is circular and
- * shall simply be looped round round (like a record baby round
- * round round round)
  * @single: the device connected to this channel will request single DMA
  * transfers, not bursts. (Bursts are default.)
  * @periph_buses: the device connected to this channel is accessible via
@@ -66,7 +63,6 @@ struct pl08x_channel_data {
u32 muxval;
u32 cctl;
dma_addr_t addr;
-   bool circular_buffer;
bool single;
u8 periph_buses;
 };
-- 
1.7.4.4

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[CFT 05/31] dmaengine: PL08x: clean up get_signal/put_signal

2012-06-07 Thread Russell King
Try to avoid dereferencing the DMA engine's channel struct in these
platform helpers; instead, pass a pointer to the channel data into
get_signal(), and the returned signal number to put_signal().

Signed-off-by: Russell King rmk+ker...@arm.linux.org.uk
---
 drivers/dma/amba-pl08x.c   |4 ++--
 include/linux/amba/pl08x.h |4 ++--
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/dma/amba-pl08x.c b/drivers/dma/amba-pl08x.c
index 5821125..cc08c8c 100644
--- a/drivers/dma/amba-pl08x.c
+++ b/drivers/dma/amba-pl08x.c
@@ -874,7 +874,7 @@ static int prep_phy_channel(struct pl08x_dma_chan *plchan,
 * Can the platform allow us to use this channel?
 */
if (plchan-slave  pl08x-pd-get_signal) {
-   ret = pl08x-pd-get_signal(plchan);
+   ret = pl08x-pd-get_signal(plchan-cd);
if (ret  0) {
dev_dbg(pl08x-adev-dev,
unable to use physical channel %d for transfer 
on %s due to platform restrictions\n,
@@ -909,7 +909,7 @@ static void release_phy_channel(struct pl08x_dma_chan 
*plchan)
struct pl08x_driver_data *pl08x = plchan-host;
 
if ((plchan-phychan-signal = 0)  pl08x-pd-put_signal) {
-   pl08x-pd-put_signal(plchan);
+   pl08x-pd-put_signal(plchan-cd, plchan-phychan-signal);
plchan-phychan-signal = -1;
}
pl08x_put_phy_channel(pl08x, plchan-phychan);
diff --git a/include/linux/amba/pl08x.h b/include/linux/amba/pl08x.h
index 0f5b34d..88765a6 100644
--- a/include/linux/amba/pl08x.h
+++ b/include/linux/amba/pl08x.h
@@ -225,8 +225,8 @@ struct pl08x_platform_data {
const struct pl08x_channel_data *slave_channels;
unsigned int num_slave_channels;
struct pl08x_channel_data memcpy_channel;
-   int (*get_signal)(struct pl08x_dma_chan *);
-   void (*put_signal)(struct pl08x_dma_chan *);
+   int (*get_signal)(const struct pl08x_channel_data *);
+   void (*put_signal)(const struct pl08x_channel_data *, int);
u8 lli_buses;
u8 mem_buses;
 };
-- 
1.7.4.4

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[CFT 06/31] dmaengine: PL08x: move private data structures into amba-pl08x.c

2012-06-07 Thread Russell King
Move the driver private data structures into the driver itself, rather
than having them exposed to everyone in a header file.

Acked-by: Linus Walleij linus.wall...@linaro.org
Signed-off-by: Russell King rmk+ker...@arm.linux.org.uk
---
 drivers/dma/amba-pl08x.c   |  136 ++
 include/linux/amba/pl08x.h |  141 +---
 2 files changed, 138 insertions(+), 139 deletions(-)

diff --git a/drivers/dma/amba-pl08x.c b/drivers/dma/amba-pl08x.c
index cc08c8c..9494990 100644
--- a/drivers/dma/amba-pl08x.c
+++ b/drivers/dma/amba-pl08x.c
@@ -90,6 +90,7 @@
 #define DRIVER_NAMEpl08xdmac
 
 static struct amba_driver pl08x_amba_driver;
+struct pl08x_driver_data;
 
 /**
  * struct vendor_data - vendor-specific config parameters for PL08x derivatives
@@ -119,6 +120,141 @@ struct pl08x_lli {
 };
 
 /**
+ * struct pl08x_bus_data - information of source or destination
+ * busses for a transfer
+ * @addr: current address
+ * @maxwidth: the maximum width of a transfer on this bus
+ * @buswidth: the width of this bus in bytes: 1, 2 or 4
+ */
+struct pl08x_bus_data {
+   dma_addr_t addr;
+   u8 maxwidth;
+   u8 buswidth;
+};
+
+/**
+ * struct pl08x_phy_chan - holder for the physical channels
+ * @id: physical index to this channel
+ * @lock: a lock to use when altering an instance of this struct
+ * @signal: the physical signal (aka channel) serving this physical channel
+ * right now
+ * @serving: the virtual channel currently being served by this physical
+ * channel
+ */
+struct pl08x_phy_chan {
+   unsigned int id;
+   void __iomem *base;
+   spinlock_t lock;
+   int signal;
+   struct pl08x_dma_chan *serving;
+};
+
+/**
+ * struct pl08x_sg - structure containing data per sg
+ * @src_addr: src address of sg
+ * @dst_addr: dst address of sg
+ * @len: transfer len in bytes
+ * @node: node for txd's dsg_list
+ */
+struct pl08x_sg {
+   dma_addr_t src_addr;
+   dma_addr_t dst_addr;
+   size_t len;
+   struct list_head node;
+};
+
+/**
+ * struct pl08x_txd - wrapper for struct dma_async_tx_descriptor
+ * @tx: async tx descriptor
+ * @node: node for txd list for channels
+ * @dsg_list: list of children sg's
+ * @direction: direction of transfer
+ * @llis_bus: DMA memory address (physical) start for the LLIs
+ * @llis_va: virtual memory address start for the LLIs
+ * @cctl: control reg values for current txd
+ * @ccfg: config reg values for current txd
+ */
+struct pl08x_txd {
+   struct dma_async_tx_descriptor tx;
+   struct list_head node;
+   struct list_head dsg_list;
+   enum dma_transfer_direction direction;
+   dma_addr_t llis_bus;
+   struct pl08x_lli *llis_va;
+   /* Default cctl value for LLIs */
+   u32 cctl;
+   /*
+* Settings to be put into the physical channel when we
+* trigger this txd.  Other registers are in llis_va[0].
+*/
+   u32 ccfg;
+};
+
+/**
+ * struct pl08x_dma_chan_state - holds the PL08x specific virtual channel
+ * states
+ * @PL08X_CHAN_IDLE: the channel is idle
+ * @PL08X_CHAN_RUNNING: the channel has allocated a physical transport
+ * channel and is running a transfer on it
+ * @PL08X_CHAN_PAUSED: the channel has allocated a physical transport
+ * channel, but the transfer is currently paused
+ * @PL08X_CHAN_WAITING: the channel is waiting for a physical transport
+ * channel to become available (only pertains to memcpy channels)
+ */
+enum pl08x_dma_chan_state {
+   PL08X_CHAN_IDLE,
+   PL08X_CHAN_RUNNING,
+   PL08X_CHAN_PAUSED,
+   PL08X_CHAN_WAITING,
+};
+
+/**
+ * struct pl08x_dma_chan - this structure wraps a DMA ENGINE channel
+ * @chan: wrappped abstract channel
+ * @phychan: the physical channel utilized by this channel, if there is one
+ * @phychan_hold: if non-zero, hold on to the physical channel even if we
+ * have no pending entries
+ * @tasklet: tasklet scheduled by the IRQ to handle actual work etc
+ * @name: name of channel
+ * @cd: channel platform data
+ * @runtime_addr: address for RX/TX according to the runtime config
+ * @runtime_direction: current direction of this channel according to
+ * runtime config
+ * @pend_list: queued transactions pending on this channel
+ * @at: active transaction on this channel
+ * @lock: a lock for this channel data
+ * @host: a pointer to the host (internal use)
+ * @state: whether the channel is idle, paused, running etc
+ * @slave: whether this channel is a device (slave) or for memcpy
+ * @device_fc: Flow Controller Settings for ccfg register. Only valid for slave
+ * channels. Fill with 'true' if peripheral should be flow controller. 
Direction
+ * will be selected at Runtime.
+ * @waiting: a TX descriptor on this channel which is waiting for a physical
+ * channel to become available
+ */
+struct pl08x_dma_chan {
+   struct dma_chan chan;
+   struct pl08x_phy_chan *phychan;
+   int phychan_hold;
+   struct tasklet_struct 

[CFT 07/31] dmaengine: PL08x: constify channel names and bus_id strings

2012-06-07 Thread Russell King
Acked-by: Linus Walleij linus.wall...@linaro.org
Signed-off-by: Russell King rmk+ker...@arm.linux.org.uk
---
 drivers/dma/amba-pl08x.c   |2 +-
 include/linux/amba/pl08x.h |2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/dma/amba-pl08x.c b/drivers/dma/amba-pl08x.c
index 9494990..775efef 100644
--- a/drivers/dma/amba-pl08x.c
+++ b/drivers/dma/amba-pl08x.c
@@ -237,7 +237,7 @@ struct pl08x_dma_chan {
struct pl08x_phy_chan *phychan;
int phychan_hold;
struct tasklet_struct tasklet;
-   char *name;
+   const char *name;
const struct pl08x_channel_data *cd;
dma_addr_t src_addr;
dma_addr_t dst_addr;
diff --git a/include/linux/amba/pl08x.h b/include/linux/amba/pl08x.h
index 48d02bf..158ce26 100644
--- a/include/linux/amba/pl08x.h
+++ b/include/linux/amba/pl08x.h
@@ -58,7 +58,7 @@ enum {
  * these buses (use PL08X_AHB1 | PL08X_AHB2).
  */
 struct pl08x_channel_data {
-   char *bus_id;
+   const char *bus_id;
int min_signal;
int max_signal;
u32 muxval;
-- 
1.7.4.4

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[CFT 08/31] dmaengine: PL08x: get src/dst addr direct from dma_slave_config struct

2012-06-07 Thread Russell King
Add a dma_slave_config struct to struct pl08x_dma_chan, and move the
src_addr/dst_addr arguments into this struct.  This is a step away
from using the dma_slave_config's direction member.

Acked-by: Linus Walleij linus.wall...@linaro.org
Signed-off-by: Russell King rmk+ker...@arm.linux.org.uk
---
 drivers/dma/amba-pl08x.c |   15 +++
 1 files changed, 7 insertions(+), 8 deletions(-)

diff --git a/drivers/dma/amba-pl08x.c b/drivers/dma/amba-pl08x.c
index 775efef..31447db 100644
--- a/drivers/dma/amba-pl08x.c
+++ b/drivers/dma/amba-pl08x.c
@@ -239,8 +239,7 @@ struct pl08x_dma_chan {
struct tasklet_struct tasklet;
const char *name;
const struct pl08x_channel_data *cd;
-   dma_addr_t src_addr;
-   dma_addr_t dst_addr;
+   struct dma_slave_config cfg;
u32 src_cctl;
u32 dst_cctl;
enum dma_transfer_direction runtime_direction;
@@ -1245,6 +1244,8 @@ static int dma_set_runtime_config(struct dma_chan *chan,
return -EINVAL;
}
 
+   plchan-cfg = *config;
+
cctl |= width  PL080_CONTROL_SWIDTH_SHIFT;
cctl |= width  PL080_CONTROL_DWIDTH_SHIFT;
 
@@ -1263,12 +1264,10 @@ static int dma_set_runtime_config(struct dma_chan *chan,
plchan-device_fc = config-device_fc;
 
if (plchan-runtime_direction == DMA_DEV_TO_MEM) {
-   plchan-src_addr = config-src_addr;
plchan-src_cctl = pl08x_cctl(cctl) | PL080_CONTROL_DST_INCR |
pl08x_select_bus(plchan-cd-periph_buses,
 pl08x-mem_buses);
} else {
-   plchan-dst_addr = config-dst_addr;
plchan-dst_cctl = pl08x_cctl(cctl) | PL080_CONTROL_SRC_INCR |
pl08x_select_bus(pl08x-mem_buses,
 plchan-cd-periph_buses);
@@ -1482,10 +1481,10 @@ static struct dma_async_tx_descriptor 
*pl08x_prep_slave_sg(
 
if (direction == DMA_MEM_TO_DEV) {
txd-cctl = plchan-dst_cctl;
-   slave_addr = plchan-dst_addr;
+   slave_addr = plchan-cfg.dst_addr;
} else if (direction == DMA_DEV_TO_MEM) {
txd-cctl = plchan-src_cctl;
-   slave_addr = plchan-src_addr;
+   slave_addr = plchan-cfg.src_addr;
} else {
pl08x_free_txd(pl08x, txd);
dev_err(pl08x-adev-dev,
@@ -1790,8 +1789,8 @@ static void pl08x_dma_slave_init(struct pl08x_dma_chan 
*chan)
 
chan-slave = true;
chan-name = chan-cd-bus_id;
-   chan-src_addr = chan-cd-addr;
-   chan-dst_addr = chan-cd-addr;
+   chan-cfg.src_addr = chan-cd-addr;
+   chan-cfg.dst_addr = chan-cd-addr;
chan-src_cctl = cctl | PL080_CONTROL_DST_INCR |
pl08x_select_bus(chan-cd-periph_buses, chan-host-mem_buses);
chan-dst_cctl = cctl | PL080_CONTROL_SRC_INCR |
-- 
1.7.4.4

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[CFT 09/31] dmaengine: PL08x: get rid of device_fc in struct pl08x_dma_chan

2012-06-07 Thread Russell King
As we now store the dma_slave_config in pl08x_dma_chan, we don't need
to store this separately.  Use the one in dma_slave_config directly.

Acked-by: Linus Walleij linus.wall...@linaro.org
Signed-off-by: Russell King rmk+ker...@arm.linux.org.uk
---
 drivers/dma/amba-pl08x.c |8 +---
 1 files changed, 1 insertions(+), 7 deletions(-)

diff --git a/drivers/dma/amba-pl08x.c b/drivers/dma/amba-pl08x.c
index 31447db..7eb0e8e 100644
--- a/drivers/dma/amba-pl08x.c
+++ b/drivers/dma/amba-pl08x.c
@@ -226,9 +226,6 @@ enum pl08x_dma_chan_state {
  * @host: a pointer to the host (internal use)
  * @state: whether the channel is idle, paused, running etc
  * @slave: whether this channel is a device (slave) or for memcpy
- * @device_fc: Flow Controller Settings for ccfg register. Only valid for slave
- * channels. Fill with 'true' if peripheral should be flow controller. 
Direction
- * will be selected at Runtime.
  * @waiting: a TX descriptor on this channel which is waiting for a physical
  * channel to become available
  */
@@ -249,7 +246,6 @@ struct pl08x_dma_chan {
struct pl08x_driver_data *host;
enum pl08x_dma_chan_state state;
bool slave;
-   bool device_fc;
struct pl08x_txd *waiting;
 };
 
@@ -1261,8 +1257,6 @@ static int dma_set_runtime_config(struct dma_chan *chan,
cctl |= burst  PL080_CONTROL_SB_SIZE_SHIFT;
cctl |= burst  PL080_CONTROL_DB_SIZE_SHIFT;
 
-   plchan-device_fc = config-device_fc;
-
if (plchan-runtime_direction == DMA_DEV_TO_MEM) {
plchan-src_cctl = pl08x_cctl(cctl) | PL080_CONTROL_DST_INCR |
pl08x_select_bus(plchan-cd-periph_buses,
@@ -1492,7 +1486,7 @@ static struct dma_async_tx_descriptor 
*pl08x_prep_slave_sg(
return NULL;
}
 
-   if (plchan-device_fc)
+   if (plchan-cfg.device_fc)
tmp = (direction == DMA_MEM_TO_DEV) ? PL080_FLOW_MEM2PER_PER :
PL080_FLOW_PER2MEM_PER;
else
-- 
1.7.4.4

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[CFT 10/31] dmaengine: PL08x: move the bus and increment selection to dma prepare function

2012-06-07 Thread Russell King
Move the bus and transfer increment selection to the DMA prepare
function rather than the slave configuration function.

Acked-by: Linus Walleij linus.wall...@linaro.org
Signed-off-by: Russell King rmk+ker...@arm.linux.org.uk
---
 drivers/dma/amba-pl08x.c |   26 ++
 1 files changed, 14 insertions(+), 12 deletions(-)

diff --git a/drivers/dma/amba-pl08x.c b/drivers/dma/amba-pl08x.c
index 7eb0e8e..bd51a44 100644
--- a/drivers/dma/amba-pl08x.c
+++ b/drivers/dma/amba-pl08x.c
@@ -1258,13 +1258,9 @@ static int dma_set_runtime_config(struct dma_chan *chan,
cctl |= burst  PL080_CONTROL_DB_SIZE_SHIFT;
 
if (plchan-runtime_direction == DMA_DEV_TO_MEM) {
-   plchan-src_cctl = pl08x_cctl(cctl) | PL080_CONTROL_DST_INCR |
-   pl08x_select_bus(plchan-cd-periph_buses,
-pl08x-mem_buses);
+   plchan-src_cctl = pl08x_cctl(cctl);
} else {
-   plchan-dst_cctl = pl08x_cctl(cctl) | PL080_CONTROL_SRC_INCR |
-   pl08x_select_bus(pl08x-mem_buses,
-plchan-cd-periph_buses);
+   plchan-dst_cctl = pl08x_cctl(cctl);
}
 
dev_dbg(pl08x-adev-dev,
@@ -1451,6 +1447,8 @@ static struct dma_async_tx_descriptor 
*pl08x_prep_slave_sg(
struct scatterlist *sg;
dma_addr_t slave_addr;
int ret, tmp;
+   u8 src_buses, dst_buses;
+   u32 cctl;
 
dev_dbg(pl08x-adev-dev, %s prepare transaction of %d bytes from 
%s\n,
__func__, sg_dma_len(sgl), plchan-name);
@@ -1474,11 +1472,15 @@ static struct dma_async_tx_descriptor 
*pl08x_prep_slave_sg(
txd-direction = direction;
 
if (direction == DMA_MEM_TO_DEV) {
-   txd-cctl = plchan-dst_cctl;
+   cctl = plchan-dst_cctl | PL080_CONTROL_SRC_INCR;
slave_addr = plchan-cfg.dst_addr;
+   src_buses = pl08x-mem_buses;
+   dst_buses = plchan-cd-periph_buses;
} else if (direction == DMA_DEV_TO_MEM) {
-   txd-cctl = plchan-src_cctl;
+   cctl = plchan-src_cctl | PL080_CONTROL_DST_INCR;
slave_addr = plchan-cfg.src_addr;
+   src_buses = plchan-cd-periph_buses;
+   dst_buses = pl08x-mem_buses;
} else {
pl08x_free_txd(pl08x, txd);
dev_err(pl08x-adev-dev,
@@ -1486,6 +1488,8 @@ static struct dma_async_tx_descriptor 
*pl08x_prep_slave_sg(
return NULL;
}
 
+   txd-cctl = cctl | pl08x_select_bus(src_buses, dst_buses);
+
if (plchan-cfg.device_fc)
tmp = (direction == DMA_MEM_TO_DEV) ? PL080_FLOW_MEM2PER_PER :
PL080_FLOW_PER2MEM_PER;
@@ -1785,10 +1789,8 @@ static void pl08x_dma_slave_init(struct pl08x_dma_chan 
*chan)
chan-name = chan-cd-bus_id;
chan-cfg.src_addr = chan-cd-addr;
chan-cfg.dst_addr = chan-cd-addr;
-   chan-src_cctl = cctl | PL080_CONTROL_DST_INCR |
-   pl08x_select_bus(chan-cd-periph_buses, chan-host-mem_buses);
-   chan-dst_cctl = cctl | PL080_CONTROL_SRC_INCR |
-   pl08x_select_bus(chan-host-mem_buses, chan-cd-periph_buses);
+   chan-src_cctl = cctl;
+   chan-dst_cctl = cctl;
 }
 
 /*
-- 
1.7.4.4

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[CFT 11/31] dmaengine: PL08x: extract function to to generate cctl values

2012-06-07 Thread Russell King
Extract the functionality from dma_slave_config to generate the cctl
values for a given bus width and burst size.  This allows us to use
this elsewhere in the driver, namely the prepare functions.

Acked-by: Linus Walleij linus.wall...@linaro.org
Signed-off-by: Russell King rmk+ker...@arm.linux.org.uk
---
 drivers/dma/amba-pl08x.c |   53 +++--
 1 files changed, 32 insertions(+), 21 deletions(-)

diff --git a/drivers/dma/amba-pl08x.c b/drivers/dma/amba-pl08x.c
index bd51a44..fde801f 100644
--- a/drivers/dma/amba-pl08x.c
+++ b/drivers/dma/amba-pl08x.c
@@ -1207,14 +1207,40 @@ static u32 pl08x_burst(u32 maxburst)
return burst_sizes[i].reg;
 }
 
+static u32 pl08x_get_cctl(struct pl08x_dma_chan *plchan,
+   enum dma_slave_buswidth addr_width, u32 maxburst)
+{
+   u32 width, burst, cctl = 0;
+
+   width = pl08x_width(addr_width);
+   if (width == ~0)
+   return ~0;
+
+   cctl |= width  PL080_CONTROL_SWIDTH_SHIFT;
+   cctl |= width  PL080_CONTROL_DWIDTH_SHIFT;
+
+   /*
+* If this channel will only request single transfers, set this
+* down to ONE element.  Also select one element if no maxburst
+* is specified.
+*/
+   if (plchan-cd-single)
+   maxburst = 1;
+
+   burst = pl08x_burst(maxburst);
+   cctl |= burst  PL080_CONTROL_SB_SIZE_SHIFT;
+   cctl |= burst  PL080_CONTROL_DB_SIZE_SHIFT;
+
+   return pl08x_cctl(cctl);
+}
+
 static int dma_set_runtime_config(struct dma_chan *chan,
  struct dma_slave_config *config)
 {
struct pl08x_dma_chan *plchan = to_pl08x_chan(chan);
struct pl08x_driver_data *pl08x = plchan-host;
enum dma_slave_buswidth addr_width;
-   u32 width, burst, maxburst;
-   u32 cctl = 0;
+   u32 maxburst, cctl = 0;
 
if (!plchan-slave)
return -EINVAL;
@@ -1233,8 +1259,8 @@ static int dma_set_runtime_config(struct dma_chan *chan,
return -EINVAL;
}
 
-   width = pl08x_width(addr_width);
-   if (width == ~0) {
+   cctl = pl08x_get_cctl(plchan, addr_width, maxburst);
+   if (cctl == ~0) {
dev_err(pl08x-adev-dev,
bad runtime_config: alien address width\n);
return -EINVAL;
@@ -1242,25 +1268,10 @@ static int dma_set_runtime_config(struct dma_chan *chan,
 
plchan-cfg = *config;
 
-   cctl |= width  PL080_CONTROL_SWIDTH_SHIFT;
-   cctl |= width  PL080_CONTROL_DWIDTH_SHIFT;
-
-   /*
-* If this channel will only request single transfers, set this
-* down to ONE element.  Also select one element if no maxburst
-* is specified.
-*/
-   if (plchan-cd-single)
-   maxburst = 1;
-
-   burst = pl08x_burst(maxburst);
-   cctl |= burst  PL080_CONTROL_SB_SIZE_SHIFT;
-   cctl |= burst  PL080_CONTROL_DB_SIZE_SHIFT;
-
if (plchan-runtime_direction == DMA_DEV_TO_MEM) {
-   plchan-src_cctl = pl08x_cctl(cctl);
+   plchan-src_cctl = cctl;
} else {
-   plchan-dst_cctl = pl08x_cctl(cctl);
+   plchan-dst_cctl = cctl;
}
 
dev_dbg(pl08x-adev-dev,
-- 
1.7.4.4

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[CFT 12/31] dmaengine: PL08x: ignore 'direction' argument in dma_slave_config

2012-06-07 Thread Russell King
Ignore the direction argument in dma_slave_config, and configure both
directions independently.  We still check that the configuration for
the intended direction is valid; this check will eventually be dropped.
This check is just for debugging at present.

Acked-by: Linus Walleij linus.wall...@linaro.org
Signed-off-by: Russell King rmk+ker...@arm.linux.org.uk
---
 drivers/dma/amba-pl08x.c |   56 ++---
 1 files changed, 18 insertions(+), 38 deletions(-)

diff --git a/drivers/dma/amba-pl08x.c b/drivers/dma/amba-pl08x.c
index fde801f..50b9a83 100644
--- a/drivers/dma/amba-pl08x.c
+++ b/drivers/dma/amba-pl08x.c
@@ -218,8 +218,6 @@ enum pl08x_dma_chan_state {
  * @name: name of channel
  * @cd: channel platform data
  * @runtime_addr: address for RX/TX according to the runtime config
- * @runtime_direction: current direction of this channel according to
- * runtime config
  * @pend_list: queued transactions pending on this channel
  * @at: active transaction on this channel
  * @lock: a lock for this channel data
@@ -239,7 +237,6 @@ struct pl08x_dma_chan {
struct dma_slave_config cfg;
u32 src_cctl;
u32 dst_cctl;
-   enum dma_transfer_direction runtime_direction;
struct list_head pend_list;
struct pl08x_txd *at;
spinlock_t lock;
@@ -1239,50 +1236,31 @@ static int dma_set_runtime_config(struct dma_chan *chan,
 {
struct pl08x_dma_chan *plchan = to_pl08x_chan(chan);
struct pl08x_driver_data *pl08x = plchan-host;
-   enum dma_slave_buswidth addr_width;
-   u32 maxburst, cctl = 0;
+   u32 src_cctl, dst_cctl;
 
if (!plchan-slave)
return -EINVAL;
 
-   /* Transfer direction */
-   plchan-runtime_direction = config-direction;
-   if (config-direction == DMA_MEM_TO_DEV) {
-   addr_width = config-dst_addr_width;
-   maxburst = config-dst_maxburst;
-   } else if (config-direction == DMA_DEV_TO_MEM) {
-   addr_width = config-src_addr_width;
-   maxburst = config-src_maxburst;
-   } else {
+   dst_cctl = pl08x_get_cctl(plchan, config-dst_addr_width,
+ config-dst_maxburst);
+   if (dst_cctl == ~0  config-direction == DMA_MEM_TO_DEV) {
dev_err(pl08x-adev-dev,
-   bad runtime_config: alien transfer direction\n);
+   bad runtime_config: alien address width (M2D)\n);
return -EINVAL;
}
 
-   cctl = pl08x_get_cctl(plchan, addr_width, maxburst);
-   if (cctl == ~0) {
+   src_cctl = pl08x_get_cctl(plchan, config-src_addr_width,
+ config-src_maxburst);
+   if (src_cctl == ~0  config-direction == DMA_DEV_TO_MEM) {
dev_err(pl08x-adev-dev,
-   bad runtime_config: alien address width\n);
+   bad runtime_config: alien address width (D2M)\n);
return -EINVAL;
}
 
+   plchan-dst_cctl = dst_cctl;
+   plchan-src_cctl = src_cctl;
plchan-cfg = *config;
 
-   if (plchan-runtime_direction == DMA_DEV_TO_MEM) {
-   plchan-src_cctl = cctl;
-   } else {
-   plchan-dst_cctl = cctl;
-   }
-
-   dev_dbg(pl08x-adev-dev,
-   configured channel %s (%s) for %s, data width %d, 
-   maxburst %d words, LE, CCTL=0x%08x\n,
-   dma_chan_name(chan), plchan-name,
-   (config-direction == DMA_DEV_TO_MEM) ? RX : TX,
-   addr_width,
-   maxburst,
-   cctl);
-
return 0;
 }
 
@@ -1470,11 +1448,6 @@ static struct dma_async_tx_descriptor 
*pl08x_prep_slave_sg(
return NULL;
}
 
-   if (direction != plchan-runtime_direction)
-   dev_err(pl08x-adev-dev, %s DMA setup does not match 
-   the direction configured for the PrimeCell\n,
-   __func__);
-
/*
 * Set up addresses, the PrimeCell configured address
 * will take precedence since this may configure the
@@ -1499,6 +1472,13 @@ static struct dma_async_tx_descriptor 
*pl08x_prep_slave_sg(
return NULL;
}
 
+   if (cctl == ~0) {
+   pl08x_free_txd(pl08x, txd);
+   dev_err(pl08x-adev-dev,
+   DMA slave configuration botched?\n);
+   return NULL;
+   }
+
txd-cctl = cctl | pl08x_select_bus(src_buses, dst_buses);
 
if (plchan-cfg.device_fc)
-- 
1.7.4.4

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[CFT 13/31] dmaengine: PL08x: get rid of unnecessary checks in dma_slave_config

2012-06-07 Thread Russell King
Get rid of the unnecessary checks in dma_slave_config utilizing
the DMA direction.  This allows us to move the computation of
cctl to the prepare function.

Acked-by: Linus Walleij linus.wall...@linaro.org
Signed-off-by: Russell King rmk+ker...@arm.linux.org.uk
---
 drivers/dma/amba-pl08x.c   |   41 +
 include/linux/amba/pl08x.h |5 +++--
 2 files changed, 16 insertions(+), 30 deletions(-)

diff --git a/drivers/dma/amba-pl08x.c b/drivers/dma/amba-pl08x.c
index 50b9a83..f739778 100644
--- a/drivers/dma/amba-pl08x.c
+++ b/drivers/dma/amba-pl08x.c
@@ -235,8 +235,6 @@ struct pl08x_dma_chan {
const char *name;
const struct pl08x_channel_data *cd;
struct dma_slave_config cfg;
-   u32 src_cctl;
-   u32 dst_cctl;
struct list_head pend_list;
struct pl08x_txd *at;
spinlock_t lock;
@@ -1235,30 +1233,15 @@ static int dma_set_runtime_config(struct dma_chan *chan,
  struct dma_slave_config *config)
 {
struct pl08x_dma_chan *plchan = to_pl08x_chan(chan);
-   struct pl08x_driver_data *pl08x = plchan-host;
-   u32 src_cctl, dst_cctl;
 
if (!plchan-slave)
return -EINVAL;
 
-   dst_cctl = pl08x_get_cctl(plchan, config-dst_addr_width,
- config-dst_maxburst);
-   if (dst_cctl == ~0  config-direction == DMA_MEM_TO_DEV) {
-   dev_err(pl08x-adev-dev,
-   bad runtime_config: alien address width (M2D)\n);
+   /* Reject definitely invalid configurations */
+   if (config-src_addr_width == DMA_SLAVE_BUSWIDTH_8_BYTES ||
+   config-dst_addr_width == DMA_SLAVE_BUSWIDTH_8_BYTES)
return -EINVAL;
-   }
 
-   src_cctl = pl08x_get_cctl(plchan, config-src_addr_width,
- config-src_maxburst);
-   if (src_cctl == ~0  config-direction == DMA_DEV_TO_MEM) {
-   dev_err(pl08x-adev-dev,
-   bad runtime_config: alien address width (D2M)\n);
-   return -EINVAL;
-   }
-
-   plchan-dst_cctl = dst_cctl;
-   plchan-src_cctl = src_cctl;
plchan-cfg = *config;
 
return 0;
@@ -1407,7 +1390,7 @@ static struct dma_async_tx_descriptor 
*pl08x_prep_dma_memcpy(
 
/* Set platform data for m2m */
txd-ccfg |= PL080_FLOW_MEM2MEM  PL080_CONFIG_FLOW_CONTROL_SHIFT;
-   txd-cctl = pl08x-pd-memcpy_channel.cctl 
+   txd-cctl = pl08x-pd-memcpy_channel.cctl_memcpy 
~(PL080_CONTROL_DST_AHB2 | PL080_CONTROL_SRC_AHB2);
 
/* Both to be incremented or the code will break */
@@ -1434,10 +1417,11 @@ static struct dma_async_tx_descriptor 
*pl08x_prep_slave_sg(
struct pl08x_txd *txd;
struct pl08x_sg *dsg;
struct scatterlist *sg;
+   enum dma_slave_buswidth addr_width;
dma_addr_t slave_addr;
int ret, tmp;
u8 src_buses, dst_buses;
-   u32 cctl;
+   u32 maxburst, cctl;
 
dev_dbg(pl08x-adev-dev, %s prepare transaction of %d bytes from 
%s\n,
__func__, sg_dma_len(sgl), plchan-name);
@@ -1456,13 +1440,17 @@ static struct dma_async_tx_descriptor 
*pl08x_prep_slave_sg(
txd-direction = direction;
 
if (direction == DMA_MEM_TO_DEV) {
-   cctl = plchan-dst_cctl | PL080_CONTROL_SRC_INCR;
+   cctl = PL080_CONTROL_SRC_INCR;
slave_addr = plchan-cfg.dst_addr;
+   addr_width = plchan-cfg.dst_addr_width;
+   maxburst = plchan-cfg.dst_maxburst;
src_buses = pl08x-mem_buses;
dst_buses = plchan-cd-periph_buses;
} else if (direction == DMA_DEV_TO_MEM) {
-   cctl = plchan-src_cctl | PL080_CONTROL_DST_INCR;
+   cctl = PL080_CONTROL_DST_INCR;
slave_addr = plchan-cfg.src_addr;
+   addr_width = plchan-cfg.src_addr_width;
+   maxburst = plchan-cfg.src_maxburst;
src_buses = plchan-cd-periph_buses;
dst_buses = pl08x-mem_buses;
} else {
@@ -1472,6 +1460,7 @@ static struct dma_async_tx_descriptor 
*pl08x_prep_slave_sg(
return NULL;
}
 
+   cctl |= pl08x_get_cctl(plchan, addr_width, maxburst);
if (cctl == ~0) {
pl08x_free_txd(pl08x, txd);
dev_err(pl08x-adev-dev,
@@ -1774,14 +1763,10 @@ static irqreturn_t pl08x_irq(int irq, void *dev)
 
 static void pl08x_dma_slave_init(struct pl08x_dma_chan *chan)
 {
-   u32 cctl = pl08x_cctl(chan-cd-cctl);
-
chan-slave = true;
chan-name = chan-cd-bus_id;
chan-cfg.src_addr = chan-cd-addr;
chan-cfg.dst_addr = chan-cd-addr;
-   chan-src_cctl = cctl;
-   chan-dst_cctl = cctl;
 }
 
 /*
diff --git a/include/linux/amba/pl08x.h b/include/linux/amba/pl08x.h
index 158ce26..2a5f64a 100644
--- a/include/linux/amba/pl08x.h
+++ 

[CFT 14/31] dmaengine: PL08x: split DMA signal muxing from channel alloc

2012-06-07 Thread Russell King
Split the DMA request mux signal handling from the physical channel
allocation code.  The physical channel has very little to do with the
DMA request input which will be used, so these should be two separate
operations.

Acked-by: Linus Walleij linus.wall...@linaro.org
Signed-off-by: Russell King rmk+ker...@arm.linux.org.uk
---
 drivers/dma/amba-pl08x.c |   43 ---
 1 files changed, 36 insertions(+), 7 deletions(-)

diff --git a/drivers/dma/amba-pl08x.c b/drivers/dma/amba-pl08x.c
index f739778..b579bac 100644
--- a/drivers/dma/amba-pl08x.c
+++ b/drivers/dma/amba-pl08x.c
@@ -296,6 +296,39 @@ static inline struct pl08x_txd *to_pl08x_txd(struct 
dma_async_tx_descriptor *tx)
 }
 
 /*
+ * Mux handling.
+ *
+ * This gives us the DMA request input to the PL08x primecell which the
+ * peripheral described by the channel data will be routed to, possibly
+ * via a board/SoC specific external MUX.  One important point to note
+ * here is that this does not depend on the physical channel.
+ */
+static int pl08x_request_mux(struct pl08x_dma_chan *plchan, struct 
pl08x_phy_chan *ch)
+{
+   const struct pl08x_platform_data *pd = plchan-host-pd;
+   int ret;
+
+   if (pd-get_signal) {
+   ret = pd-get_signal(plchan-cd);
+   if (ret  0)
+   return ret;
+
+   ch-signal = ret;
+   }
+   return 0;
+}
+
+static void pl08x_release_mux(struct pl08x_dma_chan *plchan)
+{
+   const struct pl08x_platform_data *pd = plchan-host-pd;
+
+   if (plchan-phychan-signal = 0  pd-put_signal) {
+   pd-put_signal(plchan-cd, plchan-phychan-signal);
+   plchan-phychan-signal = -1;
+   }
+}
+
+/*
  * Physical channel handling
  */
 
@@ -999,8 +1032,8 @@ static int prep_phy_channel(struct pl08x_dma_chan *plchan,
 * need, but for slaves the physical signals may be muxed!
 * Can the platform allow us to use this channel?
 */
-   if (plchan-slave  pl08x-pd-get_signal) {
-   ret = pl08x-pd-get_signal(plchan-cd);
+   if (plchan-slave) {
+   ret = pl08x_request_mux(plchan, ch);
if (ret  0) {
dev_dbg(pl08x-adev-dev,
unable to use physical channel %d for transfer 
on %s due to platform restrictions\n,
@@ -1009,7 +1042,6 @@ static int prep_phy_channel(struct pl08x_dma_chan *plchan,
pl08x_put_phy_channel(pl08x, ch);
return -EBUSY;
}
-   ch-signal = ret;
}
 
plchan-phychan = ch;
@@ -1034,10 +1066,7 @@ static void release_phy_channel(struct pl08x_dma_chan 
*plchan)
 {
struct pl08x_driver_data *pl08x = plchan-host;
 
-   if ((plchan-phychan-signal = 0)  pl08x-pd-put_signal) {
-   pl08x-pd-put_signal(plchan-cd, plchan-phychan-signal);
-   plchan-phychan-signal = -1;
-   }
+   pl08x_release_mux(plchan);
pl08x_put_phy_channel(pl08x, plchan-phychan);
plchan-phychan = NULL;
 }
-- 
1.7.4.4

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[CFT 15/31] dmaengine: PL08x: move DMA signal muxing into pl08x_dma_chan struct

2012-06-07 Thread Russell King
Move the signal handling out of the physical channel structure into
the virtual channel structure, where it should belong as it has more
to do with the virtual channel than the physical one.

Acked-by: Linus Walleij linus.wall...@linaro.org
Signed-off-by: Russell King rmk+ker...@arm.linux.org.uk
---
 drivers/dma/amba-pl08x.c |   29 +++--
 1 files changed, 15 insertions(+), 14 deletions(-)

diff --git a/drivers/dma/amba-pl08x.c b/drivers/dma/amba-pl08x.c
index b579bac..c203d2f 100644
--- a/drivers/dma/amba-pl08x.c
+++ b/drivers/dma/amba-pl08x.c
@@ -136,17 +136,17 @@ struct pl08x_bus_data {
  * struct pl08x_phy_chan - holder for the physical channels
  * @id: physical index to this channel
  * @lock: a lock to use when altering an instance of this struct
- * @signal: the physical signal (aka channel) serving this physical channel
- * right now
  * @serving: the virtual channel currently being served by this physical
  * channel
+ * @locked: channel unavailable for the system, e.g. dedicated to secure
+ * world
  */
 struct pl08x_phy_chan {
unsigned int id;
void __iomem *base;
spinlock_t lock;
-   int signal;
struct pl08x_dma_chan *serving;
+   bool locked;
 };
 
 /**
@@ -226,6 +226,7 @@ enum pl08x_dma_chan_state {
  * @slave: whether this channel is a device (slave) or for memcpy
  * @waiting: a TX descriptor on this channel which is waiting for a physical
  * channel to become available
+ * @signal: the physical DMA request signal which this channel is using
  */
 struct pl08x_dma_chan {
struct dma_chan chan;
@@ -242,6 +243,7 @@ struct pl08x_dma_chan {
enum pl08x_dma_chan_state state;
bool slave;
struct pl08x_txd *waiting;
+   int signal;
 };
 
 /**
@@ -303,7 +305,7 @@ static inline struct pl08x_txd *to_pl08x_txd(struct 
dma_async_tx_descriptor *tx)
  * via a board/SoC specific external MUX.  One important point to note
  * here is that this does not depend on the physical channel.
  */
-static int pl08x_request_mux(struct pl08x_dma_chan *plchan, struct 
pl08x_phy_chan *ch)
+static int pl08x_request_mux(struct pl08x_dma_chan *plchan)
 {
const struct pl08x_platform_data *pd = plchan-host-pd;
int ret;
@@ -313,7 +315,7 @@ static int pl08x_request_mux(struct pl08x_dma_chan *plchan, 
struct pl08x_phy_cha
if (ret  0)
return ret;
 
-   ch-signal = ret;
+   plchan-signal = ret;
}
return 0;
 }
@@ -322,9 +324,9 @@ static void pl08x_release_mux(struct pl08x_dma_chan *plchan)
 {
const struct pl08x_platform_data *pd = plchan-host-pd;
 
-   if (plchan-phychan-signal = 0  pd-put_signal) {
-   pd-put_signal(plchan-cd, plchan-phychan-signal);
-   plchan-phychan-signal = -1;
+   if (plchan-signal = 0  pd-put_signal) {
+   pd-put_signal(plchan-cd, plchan-signal);
+   plchan-signal = -1;
}
 }
 
@@ -549,7 +551,6 @@ pl08x_get_phy_channel(struct pl08x_driver_data *pl08x,
 
if (!ch-locked  !ch-serving) {
ch-serving = virt_chan;
-   ch-signal = -1;
spin_unlock_irqrestore(ch-lock, flags);
break;
}
@@ -1033,7 +1034,7 @@ static int prep_phy_channel(struct pl08x_dma_chan *plchan,
 * Can the platform allow us to use this channel?
 */
if (plchan-slave) {
-   ret = pl08x_request_mux(plchan, ch);
+   ret = pl08x_request_mux(plchan);
if (ret  0) {
dev_dbg(pl08x-adev-dev,
unable to use physical channel %d for transfer 
on %s due to platform restrictions\n,
@@ -1047,15 +1048,15 @@ static int prep_phy_channel(struct pl08x_dma_chan 
*plchan,
plchan-phychan = ch;
dev_dbg(pl08x-adev-dev, allocated physical channel %d and signal %d 
for xfer on %s\n,
 ch-id,
-ch-signal,
+plchan-signal,
 plchan-name);
 
 got_channel:
/* Assign the flow control signal to this channel */
if (txd-direction == DMA_MEM_TO_DEV)
-   txd-ccfg |= ch-signal  PL080_CONFIG_DST_SEL_SHIFT;
+   txd-ccfg |= plchan-signal  PL080_CONFIG_DST_SEL_SHIFT;
else if (txd-direction == DMA_DEV_TO_MEM)
-   txd-ccfg |= ch-signal  PL080_CONFIG_SRC_SEL_SHIFT;
+   txd-ccfg |= plchan-signal  PL080_CONFIG_SRC_SEL_SHIFT;
 
plchan-phychan_hold++;
 
@@ -1825,6 +1826,7 @@ static int pl08x_dma_init_virtual_channels(struct 
pl08x_driver_data *pl08x,
 
chan-host = pl08x;
chan-state = PL08X_CHAN_IDLE;
+   chan-signal = -1;
 
if (slave) {
chan-cd = pl08x-pd-slave_channels[i];
@@ -2062,7 +2064,6 @@ static int pl08x_probe(struct amba_device *adev, const 
struct 

[CFT 16/31] dmaengine: PL08x: track mux usage on a per-channel basis.

2012-06-07 Thread Russell King
Keep track of the number of descriptors currently using a MUX setting
on a per-channel basis.  This allows us to know when we have descriptors
queued somewhere which have been assigned a DMA request signal.

Acked-by: Linus Walleij linus.wall...@linaro.org
Signed-off-by: Russell King rmk+ker...@arm.linux.org.uk
---
 drivers/dma/amba-pl08x.c |   18 +-
 1 files changed, 13 insertions(+), 5 deletions(-)

diff --git a/drivers/dma/amba-pl08x.c b/drivers/dma/amba-pl08x.c
index c203d2f..ac9fdcc 100644
--- a/drivers/dma/amba-pl08x.c
+++ b/drivers/dma/amba-pl08x.c
@@ -227,6 +227,7 @@ enum pl08x_dma_chan_state {
  * @waiting: a TX descriptor on this channel which is waiting for a physical
  * channel to become available
  * @signal: the physical DMA request signal which this channel is using
+ * @mux_use: count of descriptors using this DMA request signal setting
  */
 struct pl08x_dma_chan {
struct dma_chan chan;
@@ -244,6 +245,7 @@ struct pl08x_dma_chan {
bool slave;
struct pl08x_txd *waiting;
int signal;
+   unsigned mux_use;
 };
 
 /**
@@ -310,10 +312,12 @@ static int pl08x_request_mux(struct pl08x_dma_chan 
*plchan)
const struct pl08x_platform_data *pd = plchan-host-pd;
int ret;
 
-   if (pd-get_signal) {
+   if (plchan-mux_use++ == 0  pd-get_signal) {
ret = pd-get_signal(plchan-cd);
-   if (ret  0)
+   if (ret  0) {
+   plchan-mux_use = 0;
return ret;
+   }
 
plchan-signal = ret;
}
@@ -324,9 +328,13 @@ static void pl08x_release_mux(struct pl08x_dma_chan 
*plchan)
 {
const struct pl08x_platform_data *pd = plchan-host-pd;
 
-   if (plchan-signal = 0  pd-put_signal) {
-   pd-put_signal(plchan-cd, plchan-signal);
-   plchan-signal = -1;
+   if (plchan-signal = 0) {
+   WARN_ON(plchan-mux_use == 0);
+
+   if (--plchan-mux_use == 0  pd-put_signal) {
+   pd-put_signal(plchan-cd, plchan-signal);
+   plchan-signal = -1;
+   }
}
 }
 
-- 
1.7.4.4

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[CFT 17/31] dmaengine: PL08x: convert to a list of completed descriptors

2012-06-07 Thread Russell King
Convert PL08x to use a list of completed descriptors rather than
merely relying upon a single pointer.  This makes it possible to
schedule the tasklet for other purposes, and makes our behaviour
similar to virt-dma.

Acked-by: Linus Walleij linus.wall...@linaro.org
Signed-off-by: Russell King rmk+ker...@arm.linux.org.uk
---
 drivers/dma/amba-pl08x.c |   30 --
 1 files changed, 20 insertions(+), 10 deletions(-)

diff --git a/drivers/dma/amba-pl08x.c b/drivers/dma/amba-pl08x.c
index ac9fdcc..54e3eb0 100644
--- a/drivers/dma/amba-pl08x.c
+++ b/drivers/dma/amba-pl08x.c
@@ -219,6 +219,7 @@ enum pl08x_dma_chan_state {
  * @cd: channel platform data
  * @runtime_addr: address for RX/TX according to the runtime config
  * @pend_list: queued transactions pending on this channel
+ * @done_list: list of completed transactions
  * @at: active transaction on this channel
  * @lock: a lock for this channel data
  * @host: a pointer to the host (internal use)
@@ -238,6 +239,7 @@ struct pl08x_dma_chan {
const struct pl08x_channel_data *cd;
struct dma_slave_config cfg;
struct list_head pend_list;
+   struct list_head done_list;
struct pl08x_txd *at;
spinlock_t lock;
struct pl08x_driver_data *host;
@@ -1673,18 +1675,11 @@ static void pl08x_tasklet(unsigned long data)
 {
struct pl08x_dma_chan *plchan = (struct pl08x_dma_chan *) data;
struct pl08x_driver_data *pl08x = plchan-host;
-   struct pl08x_txd *txd;
unsigned long flags;
+   LIST_HEAD(head);
 
spin_lock_irqsave(plchan-lock, flags);
-
-   txd = plchan-at;
-   plchan-at = NULL;
-
-   if (txd) {
-   /* Update last completed */
-   dma_cookie_complete(txd-tx);
-   }
+   list_splice_tail_init(plchan-done_list, head);
 
/* If a new descriptor is queued, set it up plchan-at is NULL here */
if (!list_empty(plchan-pend_list)) {
@@ -1739,10 +1734,14 @@ static void pl08x_tasklet(unsigned long data)
 
spin_unlock_irqrestore(plchan-lock, flags);
 
-   if (txd) {
+   while (!list_empty(head)) {
+   struct pl08x_txd *txd = list_first_entry(head,
+   struct pl08x_txd, node);
dma_async_tx_callback callback = txd-tx.callback;
void *callback_param = txd-tx.callback_param;
 
+   list_del(txd-node);
+
/* Don't try to unmap buffers on slave channels */
if (!plchan-slave)
pl08x_unmap_buffers(txd);
@@ -1782,6 +1781,7 @@ static irqreturn_t pl08x_irq(int irq, void *dev)
/* Locate physical channel */
struct pl08x_phy_chan *phychan = pl08x-phy_chans[i];
struct pl08x_dma_chan *plchan = phychan-serving;
+   struct pl08x_txd *tx;
 
if (!plchan) {
dev_err(pl08x-adev-dev,
@@ -1790,6 +1790,15 @@ static irqreturn_t pl08x_irq(int irq, void *dev)
continue;
}
 
+   spin_lock(plchan-lock);
+   tx = plchan-at;
+   if (tx) {
+   plchan-at = NULL;
+   dma_cookie_complete(tx-tx);
+   list_add_tail(tx-node, plchan-done_list);
+   }
+   spin_unlock(plchan-lock);
+
/* Schedule tasklet on this channel */
tasklet_schedule(plchan-tasklet);
mask |= (1  i);
@@ -1856,6 +1865,7 @@ static int pl08x_dma_init_virtual_channels(struct 
pl08x_driver_data *pl08x,
 
spin_lock_init(chan-lock);
INIT_LIST_HEAD(chan-pend_list);
+   INIT_LIST_HEAD(chan-done_list);
tasklet_init(chan-tasklet, pl08x_tasklet,
 (unsigned long) chan);
 
-- 
1.7.4.4

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[CFT 18/31] dmaengine: PL08x: move DMA signal muxing into slave prepare code

2012-06-07 Thread Russell King
Move the DMA request muxing into the slave prepare code and txd
release/completion code.  This means we only hold the DMA request
mux while there are descriptors waiting to be started or are in
progress.

This leaves txd-direction as a write-only variable; remove it.

Acked-by: Linus Walleij linus.wall...@linaro.org
Signed-off-by: Russell King rmk+ker...@arm.linux.org.uk
---
 drivers/dma/amba-pl08x.c |   79 ++---
 1 files changed, 32 insertions(+), 47 deletions(-)

diff --git a/drivers/dma/amba-pl08x.c b/drivers/dma/amba-pl08x.c
index 54e3eb0..e04ca0b 100644
--- a/drivers/dma/amba-pl08x.c
+++ b/drivers/dma/amba-pl08x.c
@@ -168,7 +168,6 @@ struct pl08x_sg {
  * @tx: async tx descriptor
  * @node: node for txd list for channels
  * @dsg_list: list of children sg's
- * @direction: direction of transfer
  * @llis_bus: DMA memory address (physical) start for the LLIs
  * @llis_va: virtual memory address start for the LLIs
  * @cctl: control reg values for current txd
@@ -178,7 +177,6 @@ struct pl08x_txd {
struct dma_async_tx_descriptor tx;
struct list_head node;
struct list_head dsg_list;
-   enum dma_transfer_direction direction;
dma_addr_t llis_bus;
struct pl08x_lli *llis_va;
/* Default cctl value for LLIs */
@@ -997,6 +995,7 @@ static void pl08x_free_txd_list(struct pl08x_driver_data 
*pl08x,
if (!list_empty(plchan-pend_list)) {
list_for_each_entry_safe(txdi,
 next, plchan-pend_list, node) {
+   pl08x_release_mux(plchan);
list_del(txdi-node);
pl08x_free_txd(pl08x, txdi);
}
@@ -1018,12 +1017,10 @@ static void pl08x_free_chan_resources(struct dma_chan 
*chan)
 /*
  * This should be called with the channel plchan-lock held
  */
-static int prep_phy_channel(struct pl08x_dma_chan *plchan,
-   struct pl08x_txd *txd)
+static int prep_phy_channel(struct pl08x_dma_chan *plchan)
 {
struct pl08x_driver_data *pl08x = plchan-host;
struct pl08x_phy_chan *ch;
-   int ret;
 
/* Check if we already have a channel */
if (plchan-phychan) {
@@ -1038,36 +1035,11 @@ static int prep_phy_channel(struct pl08x_dma_chan 
*plchan,
return -EBUSY;
}
 
-   /*
-* OK we have a physical channel: for memcpy() this is all we
-* need, but for slaves the physical signals may be muxed!
-* Can the platform allow us to use this channel?
-*/
-   if (plchan-slave) {
-   ret = pl08x_request_mux(plchan);
-   if (ret  0) {
-   dev_dbg(pl08x-adev-dev,
-   unable to use physical channel %d for transfer 
on %s due to platform restrictions\n,
-   ch-id, plchan-name);
-   /* Release physical channel  return */
-   pl08x_put_phy_channel(pl08x, ch);
-   return -EBUSY;
-   }
-   }
-
plchan-phychan = ch;
-   dev_dbg(pl08x-adev-dev, allocated physical channel %d and signal %d 
for xfer on %s\n,
-ch-id,
-plchan-signal,
-plchan-name);
+   dev_dbg(pl08x-adev-dev, allocated physical channel %d for xfer on 
%s\n,
+ch-id, plchan-name);
 
 got_channel:
-   /* Assign the flow control signal to this channel */
-   if (txd-direction == DMA_MEM_TO_DEV)
-   txd-ccfg |= plchan-signal  PL080_CONFIG_DST_SEL_SHIFT;
-   else if (txd-direction == DMA_DEV_TO_MEM)
-   txd-ccfg |= plchan-signal  PL080_CONFIG_SRC_SEL_SHIFT;
-
plchan-phychan_hold++;
 
return 0;
@@ -1077,7 +1049,6 @@ static void release_phy_channel(struct pl08x_dma_chan 
*plchan)
 {
struct pl08x_driver_data *pl08x = plchan-host;
 
-   pl08x_release_mux(plchan);
pl08x_put_phy_channel(pl08x, plchan-phychan);
plchan-phychan = NULL;
 }
@@ -1340,19 +1311,12 @@ static int pl08x_prep_channel_resources(struct 
pl08x_dma_chan *plchan,
 * See if we already have a physical channel allocated,
 * else this is the time to try to get one.
 */
-   ret = prep_phy_channel(plchan, txd);
+   ret = prep_phy_channel(plchan);
if (ret) {
/*
 * No physical channel was available.
 *
 * memcpy transfers can be sorted out at submission time.
-*
-* Slave transfers may have been denied due to platform
-* channel muxing restrictions.  Since there is no guarantee
-* that this will ever be resolved, and the signal must be
-* acquired AFTER acquiring the physical channel, we will let
-* them be NACK:ed with -EBUSY here. The drivers can retry
-* the 

[CFT 19/31] dmaengine: PL08x: remove waiting descriptor pointer

2012-06-07 Thread Russell King
As we no longer need to pass a descriptor to prep_phy_channel(), we
don't need to keep track of the descriptor which is waiting for a
channel to become available.  So let's get rid of it.

Acked-by: Linus Walleij linus.wall...@linaro.org
Signed-off-by: Russell King rmk+ker...@arm.linux.org.uk
---
 drivers/dma/amba-pl08x.c |8 +---
 1 files changed, 1 insertions(+), 7 deletions(-)

diff --git a/drivers/dma/amba-pl08x.c b/drivers/dma/amba-pl08x.c
index e04ca0b..88661fa 100644
--- a/drivers/dma/amba-pl08x.c
+++ b/drivers/dma/amba-pl08x.c
@@ -223,8 +223,6 @@ enum pl08x_dma_chan_state {
  * @host: a pointer to the host (internal use)
  * @state: whether the channel is idle, paused, running etc
  * @slave: whether this channel is a device (slave) or for memcpy
- * @waiting: a TX descriptor on this channel which is waiting for a physical
- * channel to become available
  * @signal: the physical DMA request signal which this channel is using
  * @mux_use: count of descriptors using this DMA request signal setting
  */
@@ -243,7 +241,6 @@ struct pl08x_dma_chan {
struct pl08x_driver_data *host;
enum pl08x_dma_chan_state state;
bool slave;
-   struct pl08x_txd *waiting;
int signal;
unsigned mux_use;
 };
@@ -1074,7 +1071,6 @@ static dma_cookie_t pl08x_tx_submit(struct 
dma_async_tx_descriptor *tx)
if (!plchan-slave  !plchan-phychan) {
/* Do this memcpy whenever there is a channel ready */
plchan-state = PL08X_CHAN_WAITING;
-   plchan-waiting = txd;
} else {
plchan-phychan_hold--;
}
@@ -1696,8 +1692,7 @@ static void pl08x_tasklet(unsigned long data)
 */
list_for_each_entry(waiting, pl08x-memcpy.channels,
chan.device_node) {
-   if (waiting-state == PL08X_CHAN_WAITING 
-   waiting-waiting != NULL) {
+   if (waiting-state == PL08X_CHAN_WAITING) {
int ret;
 
/* This should REALLY not fail now */
@@ -1705,7 +1700,6 @@ static void pl08x_tasklet(unsigned long data)
BUG_ON(ret);
waiting-phychan_hold--;
waiting-state = PL08X_CHAN_RUNNING;
-   waiting-waiting = NULL;
pl08x_issue_pending(waiting-chan);
break;
}
-- 
1.7.4.4

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 04/11] ARM: OMAP2+: usb_host_fs: add custom reset for usb_host_fs (fsusb)

2012-06-07 Thread Tony Lindgren
* Paul Walmsley p...@pwsan.com [120607 03:24]:
 On Thu, 7 Jun 2012, Tony Lindgren wrote:
 
  * Paul Walmsley p...@pwsan.com [120607 00:44]:
   On Thu, 7 Jun 2012, Tony Lindgren wrote:
   
Here too I think driver like features like this should live in the
driver init for omap OHCI driver. In the likely case that FS OHCI is
not in use on the board, the OHCI glue can just reset it.
   
   What if the driver is not compiled into the kernel, but instead is built 
   as a loadable module?
  
  You can still have a core piece of the driver that's always built in, such
  as omap-ohci-common. But it should live under drivers, not in the bus level
  code. Or you can insmod/rmmod it to reset things properly.
 
 Do you know of any device drivers that do this now, with a core built-in 
 piece separate from a dynamically loadable part?

Hmm yeah good point, only driver frameworks tend to do that. It would require
the module registering with the core driver.
 
 Seems like it would be tricky to avoid linking in the entire driver, due 
 to the symbol dependencies.  Either that, or an extra, largely useless, 
 layer of indirection would be needed in the shim layer.

Yes probably better approach would be to only build in the reset and idle
part of the driver in the minimal case. And that too can get messy as the
makefiles may not even be included.

Until we have something generic in place to deal with stuff like unused driver
reset and idle, how about we set up the driver specific reset parts as inline
functions in the driver header?

That way the hwmod code can include those functions using the driver register
defines. Something like:

static inline int xyz_driver_reset(void __iomem *base, int flags)
{
...
}

Then instead of having a separate platform init file for each driver,
we could just have a list of reset functions:

static int hwmod_xyz_driver_reset(void __iomem *base, int flags)
{
int res;

/* do bus related reset here */
...

/* call the driver reset */
res = xyz_driver_reset(base, flags)


/* do more bus related reset here */
...
}

Regards,

Tony
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[CFT 20/31] dmaengine: PL08x: re-jig the starting of txds

2012-06-07 Thread Russell King
Rather than code the de-queue of the txd several times, move that into
the start_txd function.  Rename this to better illustrate what it's
now doing, and call this function when starting a delayed memcpy().

Acked-by: Linus Walleij linus.wall...@linaro.org
Signed-off-by: Russell King rmk+ker...@arm.linux.org.uk
---
 drivers/dma/amba-pl08x.c |   37 +
 1 files changed, 17 insertions(+), 20 deletions(-)

diff --git a/drivers/dma/amba-pl08x.c b/drivers/dma/amba-pl08x.c
index 88661fa..c278d23 100644
--- a/drivers/dma/amba-pl08x.c
+++ b/drivers/dma/amba-pl08x.c
@@ -354,20 +354,25 @@ static int pl08x_phy_channel_busy(struct pl08x_phy_chan 
*ch)
  * been set when the LLIs were constructed.  Poke them into the hardware
  * and start the transfer.
  */
-static void pl08x_start_txd(struct pl08x_dma_chan *plchan,
-   struct pl08x_txd *txd)
+static void pl08x_start_next_txd(struct pl08x_dma_chan *plchan)
 {
struct pl08x_driver_data *pl08x = plchan-host;
struct pl08x_phy_chan *phychan = plchan-phychan;
-   struct pl08x_lli *lli = txd-llis_va[0];
+   struct pl08x_lli *lli;
+   struct pl08x_txd *txd;
u32 val;
 
+   txd = list_first_entry(plchan-pend_list, struct pl08x_txd, node);
+   list_del(txd-node);
+
plchan-at = txd;
 
/* Wait for channel inactive */
while (pl08x_phy_channel_busy(phychan))
cpu_relax();
 
+   lli = txd-llis_va[0];
+
dev_vdbg(pl08x-adev-dev,
WRITE channel %d: csrc=0x%08x, cdst=0x%08x, 
clli=0x%08x, cctl=0x%08x, ccfg=0x%08x\n,
@@ -1272,15 +1277,8 @@ static void pl08x_issue_pending(struct dma_chan *chan)
 
/* Take the first element in the queue and execute it */
if (!list_empty(plchan-pend_list)) {
-   struct pl08x_txd *next;
-
-   next = list_first_entry(plchan-pend_list,
-   struct pl08x_txd,
-   node);
-   list_del(next-node);
plchan-state = PL08X_CHAN_RUNNING;
-
-   pl08x_start_txd(plchan, next);
+   pl08x_start_next_txd(plchan);
}
 
spin_unlock_irqrestore(plchan-lock, flags);
@@ -1661,14 +1659,7 @@ static void pl08x_tasklet(unsigned long data)
 
/* If a new descriptor is queued, set it up plchan-at is NULL here */
if (!list_empty(plchan-pend_list)) {
-   struct pl08x_txd *next;
-
-   next = list_first_entry(plchan-pend_list,
-   struct pl08x_txd,
-   node);
-   list_del(next-node);
-
-   pl08x_start_txd(plchan, next);
+   pl08x_start_next_txd(plchan);
} else if (plchan-phychan_hold) {
/*
 * This channel is still in use - we have a new txd being
@@ -1700,7 +1691,13 @@ static void pl08x_tasklet(unsigned long data)
BUG_ON(ret);
waiting-phychan_hold--;
waiting-state = PL08X_CHAN_RUNNING;
-   pl08x_issue_pending(waiting-chan);
+   /*
+* Eww.  We know this isn't going to deadlock
+* but lockdep probably doens't.
+*/
+   spin_lock(waiting-lock);
+   pl08x_start_next_txd(waiting);
+   spin_unlock(waiting-lock);
break;
}
}
-- 
1.7.4.4

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 04/11] ARM: OMAP2+: usb_host_fs: add custom reset for usb_host_fs (fsusb)

2012-06-07 Thread Paul Walmsley
On Thu, 7 Jun 2012, Cousson, Benoit wrote:

 In fact we should delay the reset to the very last moment and 
 potentially reset the IPs not under driver control later after a couple 
 of second for example. It will avoid reseting every IP that will be 
 handled properly by drivers.

We discussed this a couple of years ago on the list and aligned on late 
and lazy resets, from my recollection.  The main reason why it wasn't 
implemented was because there were some drivers that were not yet PM 
runtime-converted.  This would have caused crashes, since the core code 
would have no idea that the non-PM-runtime drivers had initialized their 
devices, and so the core just went ahead and reset those anyway.

It might actually be safe now to switch to the late reset arrangement, 
depending on whether the rest of the drivers have been PM 
runtime-converted by now.

Of course, it would all be moot if the reset is moved away from the hwmod 
code into the drivers.


- Paul
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[CFT 21/31] dmaengine: PL08x: split the pend_list in two

2012-06-07 Thread Russell King
Our behaviour wasn't correct; issue_pending is supposed to be called
before any submitted descriptors are available for processing by the
DMA engine.  Split the pend_list in two, one for submitted descriptors
and another list for issued descriptors.

Acked-by: Linus Walleij linus.wall...@linaro.org
Signed-off-by: Russell King rmk+ker...@arm.linux.org.uk
---
 drivers/dma/amba-pl08x.c |   41 -
 1 files changed, 28 insertions(+), 13 deletions(-)

diff --git a/drivers/dma/amba-pl08x.c b/drivers/dma/amba-pl08x.c
index c278d23..b613284 100644
--- a/drivers/dma/amba-pl08x.c
+++ b/drivers/dma/amba-pl08x.c
@@ -217,6 +217,7 @@ enum pl08x_dma_chan_state {
  * @cd: channel platform data
  * @runtime_addr: address for RX/TX according to the runtime config
  * @pend_list: queued transactions pending on this channel
+ * @issued_list: issued transactions for this channel
  * @done_list: list of completed transactions
  * @at: active transaction on this channel
  * @lock: a lock for this channel data
@@ -235,6 +236,7 @@ struct pl08x_dma_chan {
const struct pl08x_channel_data *cd;
struct dma_slave_config cfg;
struct list_head pend_list;
+   struct list_head issued_list;
struct list_head done_list;
struct pl08x_txd *at;
spinlock_t lock;
@@ -362,7 +364,7 @@ static void pl08x_start_next_txd(struct pl08x_dma_chan 
*plchan)
struct pl08x_txd *txd;
u32 val;
 
-   txd = list_first_entry(plchan-pend_list, struct pl08x_txd, node);
+   txd = list_first_entry(plchan-issued_list, struct pl08x_txd, node);
list_del(txd-node);
 
plchan-at = txd;
@@ -525,6 +527,15 @@ static u32 pl08x_getbytes_chan(struct pl08x_dma_chan 
*plchan)
}
 
/* Sum up all queued transactions */
+   if (!list_empty(plchan-issued_list)) {
+   struct pl08x_txd *txdi;
+   list_for_each_entry(txdi, plchan-issued_list, node) {
+   struct pl08x_sg *dsg;
+   list_for_each_entry(dsg, txd-dsg_list, node)
+   bytes += dsg-len;
+   }
+   }
+
if (!list_empty(plchan-pend_list)) {
struct pl08x_txd *txdi;
list_for_each_entry(txdi, plchan-pend_list, node) {
@@ -991,16 +1002,17 @@ static void pl08x_free_txd(struct pl08x_driver_data 
*pl08x,
 static void pl08x_free_txd_list(struct pl08x_driver_data *pl08x,
struct pl08x_dma_chan *plchan)
 {
-   struct pl08x_txd *txdi = NULL;
-   struct pl08x_txd *next;
+   LIST_HEAD(head);
+   struct pl08x_txd *txd;
 
-   if (!list_empty(plchan-pend_list)) {
-   list_for_each_entry_safe(txdi,
-next, plchan-pend_list, node) {
-   pl08x_release_mux(plchan);
-   list_del(txdi-node);
-   pl08x_free_txd(pl08x, txdi);
-   }
+   list_splice_tail_init(plchan-issued_list, head);
+   list_splice_tail_init(plchan-pend_list, head);
+
+   while (!list_empty(head)) {
+   txd = list_first_entry(head, struct pl08x_txd, node);
+   pl08x_release_mux(plchan);
+   list_del(txd-node);
+   pl08x_free_txd(pl08x, txd);
}
 }
 
@@ -1269,6 +1281,8 @@ static void pl08x_issue_pending(struct dma_chan *chan)
unsigned long flags;
 
spin_lock_irqsave(plchan-lock, flags);
+   list_splice_tail_init(plchan-pend_list, plchan-issued_list);
+
/* Something is already active, or we're waiting for a channel... */
if (plchan-at || plchan-state == PL08X_CHAN_WAITING) {
spin_unlock_irqrestore(plchan-lock, flags);
@@ -1276,7 +1290,7 @@ static void pl08x_issue_pending(struct dma_chan *chan)
}
 
/* Take the first element in the queue and execute it */
-   if (!list_empty(plchan-pend_list)) {
+   if (!list_empty(plchan-issued_list)) {
plchan-state = PL08X_CHAN_RUNNING;
pl08x_start_next_txd(plchan);
}
@@ -1658,9 +1672,9 @@ static void pl08x_tasklet(unsigned long data)
list_splice_tail_init(plchan-done_list, head);
 
/* If a new descriptor is queued, set it up plchan-at is NULL here */
-   if (!list_empty(plchan-pend_list)) {
+   if (!list_empty(plchan-issued_list)) {
pl08x_start_next_txd(plchan);
-   } else if (plchan-phychan_hold) {
+   } else if (!list_empty(plchan-pend_list) || plchan-phychan_hold) {
/*
 * This channel is still in use - we have a new txd being
 * prepared and will soon be queued.  Don't give up the
@@ -1841,6 +1855,7 @@ static int pl08x_dma_init_virtual_channels(struct 
pl08x_driver_data *pl08x,
 
spin_lock_init(chan-lock);
INIT_LIST_HEAD(chan-pend_list);
+   INIT_LIST_HEAD(chan-issued_list);

Re: [PATCH] ARM: omap: clock: Get rid of unwanted clkdm assocations within clks

2012-06-07 Thread Rajendra Nayak

Hi Paul,

On Thursday 07 June 2012 12:37 PM, Paul Walmsley wrote:

Hi

On Thu, 7 Jun 2012, Rajendra Nayak wrote:


On Thursday 17 May 2012 03:54 PM, Rajendra Nayak wrote:

clkdm assocations with clocks in the clock framework are useful
only for 'gate' clocks which have enable/disable ops populated.
Get rid of the clkdm_names populated in any other type of clocks.


I don't really see the point in changing this before the common clock
conversion.  The design of most of the current low-level OMAP PM layers
was predicated on each clock belonging to a clockdomain.  The testing
overhead of changing this before the common clock conversion is something
that I don't have time for, and almost no one else seems interested in
doing.

Your common clock conversion moots this patch anyway, right?


Yes, I can include this as part of the common clock conversion series.
What I was trying to say is that neither the clock framework not any
other OMAP PM layer today makes any use of this information except for
gate clocks. The only 2 places in the clock framework this is used is
in omap2_dflt_clk_enable()/omap2_dflt_clk_disable() functions, which
are nops for non gate clocks.
So I don;t fully understand what you mean by our current low-level PM
design being based on this assumption that every clock belongs to a
clockdomain.
Did I miss anything else our PM frameworks do with the clock-clkdm
association? The reason I am asking is because I am doing a lot of 
changes around based on this assumption and would really like to know

if I am missing something.

regards,
Rajendra



- Paul



--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[CFT 22/31] dmaengine: PL08x: start next descriptor from irq context

2012-06-07 Thread Russell King
Rather than waiting for the tasklet to run, we can start the next
descriptor from interrupt context, as soon as we know that the
previous descriptor has completed.

Acked-by: Linus Walleij linus.wall...@linaro.org
Signed-off-by: Russell King rmk+ker...@arm.linux.org.uk
---
 drivers/dma/amba-pl08x.c |9 +
 1 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/drivers/dma/amba-pl08x.c b/drivers/dma/amba-pl08x.c
index b613284..30b6921 100644
--- a/drivers/dma/amba-pl08x.c
+++ b/drivers/dma/amba-pl08x.c
@@ -1671,10 +1671,7 @@ static void pl08x_tasklet(unsigned long data)
spin_lock_irqsave(plchan-lock, flags);
list_splice_tail_init(plchan-done_list, head);
 
-   /* If a new descriptor is queued, set it up plchan-at is NULL here */
-   if (!list_empty(plchan-issued_list)) {
-   pl08x_start_next_txd(plchan);
-   } else if (!list_empty(plchan-pend_list) || plchan-phychan_hold) {
+   if (plchan-at || !list_empty(plchan-pend_list) || 
plchan-phychan_hold) {
/*
 * This channel is still in use - we have a new txd being
 * prepared and will soon be queued.  Don't give up the
@@ -1786,6 +1783,10 @@ static irqreturn_t pl08x_irq(int irq, void *dev)
pl08x_release_mux(plchan);
dma_cookie_complete(tx-tx);
list_add_tail(tx-node, plchan-done_list);
+
+   /* And start the next descriptor */
+   if (!list_empty(plchan-issued_list))
+   pl08x_start_next_txd(plchan);
}
spin_unlock(plchan-lock);
 
-- 
1.7.4.4

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[CFT 23/31] dmaengine: PL08x: rejig physical channel allocation

2012-06-07 Thread Russell King
Rework the physical channel allocation mechanism to only allocate
physical channels to virtual channels when they're about to be used.
This eliminates all the complexity with holding channels while
descriptors are being prepared, which is completely unnecessary.

This also brings this driver to a state where the generic virtual DMA
code can be used with this driver, and opens up the possibility of
properly scheduling and prioritorising physical DMA channels to
virtual DMA channels.

Acked-by: Linus Walleij linus.wall...@linaro.org
Signed-off-by: Russell King rmk+ker...@arm.linux.org.uk
---
 drivers/dma/amba-pl08x.c |  268 +++---
 1 files changed, 112 insertions(+), 156 deletions(-)

diff --git a/drivers/dma/amba-pl08x.c b/drivers/dma/amba-pl08x.c
index 30b6921..bbae30c 100644
--- a/drivers/dma/amba-pl08x.c
+++ b/drivers/dma/amba-pl08x.c
@@ -210,8 +210,6 @@ enum pl08x_dma_chan_state {
  * struct pl08x_dma_chan - this structure wraps a DMA ENGINE channel
  * @chan: wrappped abstract channel
  * @phychan: the physical channel utilized by this channel, if there is one
- * @phychan_hold: if non-zero, hold on to the physical channel even if we
- * have no pending entries
  * @tasklet: tasklet scheduled by the IRQ to handle actual work etc
  * @name: name of channel
  * @cd: channel platform data
@@ -230,7 +228,6 @@ enum pl08x_dma_chan_state {
 struct pl08x_dma_chan {
struct dma_chan chan;
struct pl08x_phy_chan *phychan;
-   int phychan_hold;
struct tasklet_struct tasklet;
const char *name;
const struct pl08x_channel_data *cd;
@@ -587,19 +584,111 @@ pl08x_get_phy_channel(struct pl08x_driver_data *pl08x,
return ch;
 }
 
+/* Mark the physical channel as free.  Note, this write is atomic. */
 static inline void pl08x_put_phy_channel(struct pl08x_driver_data *pl08x,
 struct pl08x_phy_chan *ch)
 {
-   unsigned long flags;
+   ch-serving = NULL;
+}
 
-   spin_lock_irqsave(ch-lock, flags);
+/*
+ * Try to allocate a physical channel.  When successful, assign it to
+ * this virtual channel, and initiate the next descriptor.  The
+ * virtual channel lock must be held at this point.
+ */
+static void pl08x_phy_alloc_and_start(struct pl08x_dma_chan *plchan)
+{
+   struct pl08x_driver_data *pl08x = plchan-host;
+   struct pl08x_phy_chan *ch;
 
-   /* Stop the channel and clear its interrupts */
-   pl08x_terminate_phy_chan(pl08x, ch);
+   ch = pl08x_get_phy_channel(pl08x, plchan);
+   if (!ch) {
+   dev_dbg(pl08x-adev-dev, no physical channel available for 
xfer on %s\n, plchan-name);
+   plchan-state = PL08X_CHAN_WAITING;
+   return;
+   }
 
-   /* Mark it as free */
-   ch-serving = NULL;
-   spin_unlock_irqrestore(ch-lock, flags);
+   dev_dbg(pl08x-adev-dev, allocated physical channel %d for xfer on 
%s\n,
+   ch-id, plchan-name);
+
+   plchan-phychan = ch;
+   plchan-state = PL08X_CHAN_RUNNING;
+   pl08x_start_next_txd(plchan);
+}
+
+static void pl08x_phy_reassign_start(struct pl08x_phy_chan *ch,
+   struct pl08x_dma_chan *plchan)
+{
+   struct pl08x_driver_data *pl08x = plchan-host;
+
+   dev_dbg(pl08x-adev-dev, reassigned physical channel %d for xfer on 
%s\n,
+   ch-id, plchan-name);
+
+   /*
+* We do this without taking the lock; we're really only concerned
+* about whether this pointer is NULL or not, and we're guaranteed
+* that this will only be called when it _already_ is non-NULL.
+*/
+   ch-serving = plchan;
+   plchan-phychan = ch;
+   plchan-state = PL08X_CHAN_RUNNING;
+   pl08x_start_next_txd(plchan);
+}
+
+/*
+ * Free a physical DMA channel, potentially reallocating it to another
+ * virtual channel if we have any pending.
+ */
+static void pl08x_phy_free(struct pl08x_dma_chan *plchan)
+{
+   struct pl08x_driver_data *pl08x = plchan-host;
+   struct pl08x_dma_chan *p, *next;
+
+ retry:
+   next = NULL;
+
+   /* Find a waiting virtual channel for the next transfer. */
+   list_for_each_entry(p, pl08x-memcpy.channels, chan.device_node)
+   if (p-state == PL08X_CHAN_WAITING) {
+   next = p;
+   break;
+   }
+
+   if (!next) {
+   list_for_each_entry(p, pl08x-slave.channels, chan.device_node)
+   if (p-state == PL08X_CHAN_WAITING) {
+   next = p;
+   break;
+   }
+   }
+
+   /* Ensure that the physical channel is stopped */
+   pl08x_terminate_phy_chan(pl08x, plchan-phychan);
+
+   if (next) {
+   bool success;
+
+   /*
+* Eww.  We know this isn't going to deadlock
+* but lockdep probably doesn't.
+*/
+ 

[CFT 24/31] dmaengine: PL08x: convert to use virt-dma structs

2012-06-07 Thread Russell King
Convert PL08x to use the virt-dma structures.

Acked-by: Linus Walleij linus.wall...@linaro.org
Signed-off-by: Russell King rmk+ker...@arm.linux.org.uk
---
 drivers/dma/amba-pl08x.c |   57 +++--
 1 files changed, 29 insertions(+), 28 deletions(-)

diff --git a/drivers/dma/amba-pl08x.c b/drivers/dma/amba-pl08x.c
index bbae30c..9a06428 100644
--- a/drivers/dma/amba-pl08x.c
+++ b/drivers/dma/amba-pl08x.c
@@ -86,6 +86,7 @@
 #include asm/hardware/pl080.h
 
 #include dmaengine.h
+#include virt-dma.h
 
 #define DRIVER_NAMEpl08xdmac
 
@@ -165,7 +166,7 @@ struct pl08x_sg {
 
 /**
  * struct pl08x_txd - wrapper for struct dma_async_tx_descriptor
- * @tx: async tx descriptor
+ * @vd: virtual DMA descriptor
  * @node: node for txd list for channels
  * @dsg_list: list of children sg's
  * @llis_bus: DMA memory address (physical) start for the LLIs
@@ -174,7 +175,7 @@ struct pl08x_sg {
  * @ccfg: config reg values for current txd
  */
 struct pl08x_txd {
-   struct dma_async_tx_descriptor tx;
+   struct virt_dma_desc vd;
struct list_head node;
struct list_head dsg_list;
dma_addr_t llis_bus;
@@ -208,7 +209,7 @@ enum pl08x_dma_chan_state {
 
 /**
  * struct pl08x_dma_chan - this structure wraps a DMA ENGINE channel
- * @chan: wrappped abstract channel
+ * @vc: wrappped virtual channel
  * @phychan: the physical channel utilized by this channel, if there is one
  * @tasklet: tasklet scheduled by the IRQ to handle actual work etc
  * @name: name of channel
@@ -226,7 +227,7 @@ enum pl08x_dma_chan_state {
  * @mux_use: count of descriptors using this DMA request signal setting
  */
 struct pl08x_dma_chan {
-   struct dma_chan chan;
+   struct virt_dma_chan vc;
struct pl08x_phy_chan *phychan;
struct tasklet_struct tasklet;
const char *name;
@@ -287,12 +288,12 @@ struct pl08x_driver_data {
 
 static inline struct pl08x_dma_chan *to_pl08x_chan(struct dma_chan *chan)
 {
-   return container_of(chan, struct pl08x_dma_chan, chan);
+   return container_of(chan, struct pl08x_dma_chan, vc.chan);
 }
 
 static inline struct pl08x_txd *to_pl08x_txd(struct dma_async_tx_descriptor 
*tx)
 {
-   return container_of(tx, struct pl08x_txd, tx);
+   return container_of(tx, struct pl08x_txd, vd.tx);
 }
 
 /*
@@ -648,14 +649,14 @@ static void pl08x_phy_free(struct pl08x_dma_chan *plchan)
next = NULL;
 
/* Find a waiting virtual channel for the next transfer. */
-   list_for_each_entry(p, pl08x-memcpy.channels, chan.device_node)
+   list_for_each_entry(p, pl08x-memcpy.channels, vc.chan.device_node)
if (p-state == PL08X_CHAN_WAITING) {
next = p;
break;
}
 
if (!next) {
-   list_for_each_entry(p, pl08x-slave.channels, chan.device_node)
+   list_for_each_entry(p, pl08x-slave.channels, 
vc.chan.device_node)
if (p-state == PL08X_CHAN_WAITING) {
next = p;
break;
@@ -1351,9 +1352,9 @@ static struct pl08x_txd *pl08x_get_txd(struct 
pl08x_dma_chan *plchan,
struct pl08x_txd *txd = kzalloc(sizeof(*txd), GFP_NOWAIT);
 
if (txd) {
-   dma_async_tx_descriptor_init(txd-tx, plchan-chan);
-   txd-tx.flags = flags;
-   txd-tx.tx_submit = pl08x_tx_submit;
+   dma_async_tx_descriptor_init(txd-vd.tx, plchan-vc.chan);
+   txd-vd.tx.flags = flags;
+   txd-vd.tx.tx_submit = pl08x_tx_submit;
INIT_LIST_HEAD(txd-node);
INIT_LIST_HEAD(txd-dsg_list);
 
@@ -1413,7 +1414,7 @@ static struct dma_async_tx_descriptor 
*pl08x_prep_dma_memcpy(
if (ret)
return NULL;
 
-   return txd-tx;
+   return txd-vd.tx;
 }
 
 static struct dma_async_tx_descriptor *pl08x_prep_slave_sg(
@@ -1529,7 +1530,7 @@ static struct dma_async_tx_descriptor 
*pl08x_prep_slave_sg(
if (ret)
return NULL;
 
-   return txd-tx;
+   return txd-vd.tx;
 }
 
 static int pl08x_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
@@ -1630,11 +1631,11 @@ static void pl08x_ensure_on(struct pl08x_driver_data 
*pl08x)
 
 static void pl08x_unmap_buffers(struct pl08x_txd *txd)
 {
-   struct device *dev = txd-tx.chan-device-dev;
+   struct device *dev = txd-vd.tx.chan-device-dev;
struct pl08x_sg *dsg;
 
-   if (!(txd-tx.flags  DMA_COMPL_SKIP_SRC_UNMAP)) {
-   if (txd-tx.flags  DMA_COMPL_SRC_UNMAP_SINGLE)
+   if (!(txd-vd.tx.flags  DMA_COMPL_SKIP_SRC_UNMAP)) {
+   if (txd-vd.tx.flags  DMA_COMPL_SRC_UNMAP_SINGLE)
list_for_each_entry(dsg, txd-dsg_list, node)
dma_unmap_single(dev, dsg-src_addr, dsg-len,
DMA_TO_DEVICE);
@@ -1644,8 +1645,8 @@ static void 

[CFT 25/31] dmaengine: PL08x: use vchan's spinlock

2012-06-07 Thread Russell King
Initialize the vchan struct, and use the provided spinlock rather than
our own.

Acked-by: Linus Walleij linus.wall...@linaro.org
Signed-off-by: Russell King rmk+ker...@arm.linux.org.uk
---
 drivers/dma/Kconfig  |1 +
 drivers/dma/amba-pl08x.c |   45 -
 2 files changed, 21 insertions(+), 25 deletions(-)

diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
index eb2b60e..be0dc3b 100644
--- a/drivers/dma/Kconfig
+++ b/drivers/dma/Kconfig
@@ -53,6 +53,7 @@ config AMBA_PL08X
bool ARM PrimeCell PL080 or PL081 support
depends on ARM_AMBA  EXPERIMENTAL
select DMA_ENGINE
+   select DMA_VIRTUAL_CHANNELS
help
  Platform has a PL08x DMAC device
  which can provide DMA engine support
diff --git a/drivers/dma/amba-pl08x.c b/drivers/dma/amba-pl08x.c
index 9a06428..398a5da 100644
--- a/drivers/dma/amba-pl08x.c
+++ b/drivers/dma/amba-pl08x.c
@@ -237,7 +237,6 @@ struct pl08x_dma_chan {
struct list_head issued_list;
struct list_head done_list;
struct pl08x_txd *at;
-   spinlock_t lock;
struct pl08x_driver_data *host;
enum pl08x_dma_chan_state state;
bool slave;
@@ -484,7 +483,7 @@ static u32 pl08x_getbytes_chan(struct pl08x_dma_chan 
*plchan)
unsigned long flags;
size_t bytes = 0;
 
-   spin_lock_irqsave(plchan-lock, flags);
+   spin_lock_irqsave(plchan-vc.lock, flags);
ch = plchan-phychan;
txd = plchan-at;
 
@@ -543,7 +542,7 @@ static u32 pl08x_getbytes_chan(struct pl08x_dma_chan 
*plchan)
}
}
 
-   spin_unlock_irqrestore(plchan-lock, flags);
+   spin_unlock_irqrestore(plchan-vc.lock, flags);
 
return bytes;
 }
@@ -673,12 +672,12 @@ static void pl08x_phy_free(struct pl08x_dma_chan *plchan)
 * Eww.  We know this isn't going to deadlock
 * but lockdep probably doesn't.
 */
-   spin_lock(next-lock);
+   spin_lock(next-vc.lock);
/* Re-check the state now that we have the lock */
success = next-state == PL08X_CHAN_WAITING;
if (success)
pl08x_phy_reassign_start(plchan-phychan, next);
-   spin_unlock(next-lock);
+   spin_unlock(next-vc.lock);
 
/* If the state changed, try to find another channel */
if (!success)
@@ -1125,12 +1124,12 @@ static dma_cookie_t pl08x_tx_submit(struct 
dma_async_tx_descriptor *tx)
unsigned long flags;
dma_cookie_t cookie;
 
-   spin_lock_irqsave(plchan-lock, flags);
+   spin_lock_irqsave(plchan-vc.lock, flags);
cookie = dma_cookie_assign(tx);
 
/* Put this onto the pending list */
list_add_tail(txd-node, plchan-pend_list);
-   spin_unlock_irqrestore(plchan-lock, flags);
+   spin_unlock_irqrestore(plchan-vc.lock, flags);
 
return cookie;
 }
@@ -1318,13 +1317,13 @@ static void pl08x_issue_pending(struct dma_chan *chan)
struct pl08x_dma_chan *plchan = to_pl08x_chan(chan);
unsigned long flags;
 
-   spin_lock_irqsave(plchan-lock, flags);
+   spin_lock_irqsave(plchan-vc.lock, flags);
list_splice_tail_init(plchan-pend_list, plchan-issued_list);
if (!list_empty(plchan-issued_list)) {
if (!plchan-phychan  plchan-state != PL08X_CHAN_WAITING)
pl08x_phy_alloc_and_start(plchan);
}
-   spin_unlock_irqrestore(plchan-lock, flags);
+   spin_unlock_irqrestore(plchan-vc.lock, flags);
 }
 
 static int pl08x_prep_channel_resources(struct pl08x_dma_chan *plchan,
@@ -1337,9 +1336,9 @@ static int pl08x_prep_channel_resources(struct 
pl08x_dma_chan *plchan,
if (!num_llis) {
unsigned long flags;
 
-   spin_lock_irqsave(plchan-lock, flags);
+   spin_lock_irqsave(plchan-vc.lock, flags);
pl08x_free_txd(pl08x, txd);
-   spin_unlock_irqrestore(plchan-lock, flags);
+   spin_unlock_irqrestore(plchan-vc.lock, flags);
 
return -EINVAL;
}
@@ -1551,9 +1550,9 @@ static int pl08x_control(struct dma_chan *chan, enum 
dma_ctrl_cmd cmd,
 * Anything succeeds on channels with no physical allocation and
 * no queued transfers.
 */
-   spin_lock_irqsave(plchan-lock, flags);
+   spin_lock_irqsave(plchan-vc.lock, flags);
if (!plchan-phychan  !plchan-at) {
-   spin_unlock_irqrestore(plchan-lock, flags);
+   spin_unlock_irqrestore(plchan-vc.lock, flags);
return 0;
}
 
@@ -1592,7 +1591,7 @@ static int pl08x_control(struct dma_chan *chan, enum 
dma_ctrl_cmd cmd,
break;
}
 
-   spin_unlock_irqrestore(plchan-lock, flags);
+   spin_unlock_irqrestore(plchan-vc.lock, flags);
 
return ret;
 }
@@ -1664,9 +1663,9 @@ static void 

[CFT 26/31] dmaengine: PL08x: convert to use vchan submitted/issued lists

2012-06-07 Thread Russell King
Convert to use the virtual dma channel submitted/issued descriptor
lists rather than our own private lists, and use the virtual dma
channel support functions to manage these lists.

Acked-by: Linus Walleij linus.wall...@linaro.org
Signed-off-by: Russell King rmk+ker...@arm.linux.org.uk
---
 drivers/dma/amba-pl08x.c |   64 -
 1 files changed, 17 insertions(+), 47 deletions(-)

diff --git a/drivers/dma/amba-pl08x.c b/drivers/dma/amba-pl08x.c
index 398a5da..5333a91 100644
--- a/drivers/dma/amba-pl08x.c
+++ b/drivers/dma/amba-pl08x.c
@@ -215,8 +215,6 @@ enum pl08x_dma_chan_state {
  * @name: name of channel
  * @cd: channel platform data
  * @runtime_addr: address for RX/TX according to the runtime config
- * @pend_list: queued transactions pending on this channel
- * @issued_list: issued transactions for this channel
  * @done_list: list of completed transactions
  * @at: active transaction on this channel
  * @lock: a lock for this channel data
@@ -233,8 +231,6 @@ struct pl08x_dma_chan {
const char *name;
const struct pl08x_channel_data *cd;
struct dma_slave_config cfg;
-   struct list_head pend_list;
-   struct list_head issued_list;
struct list_head done_list;
struct pl08x_txd *at;
struct pl08x_driver_data *host;
@@ -357,12 +353,12 @@ static void pl08x_start_next_txd(struct pl08x_dma_chan 
*plchan)
 {
struct pl08x_driver_data *pl08x = plchan-host;
struct pl08x_phy_chan *phychan = plchan-phychan;
+   struct virt_dma_desc *vd = vchan_next_desc(plchan-vc);
+   struct pl08x_txd *txd = to_pl08x_txd(vd-tx);
struct pl08x_lli *lli;
-   struct pl08x_txd *txd;
u32 val;
 
-   txd = list_first_entry(plchan-issued_list, struct pl08x_txd, node);
-   list_del(txd-node);
+   list_del(txd-vd.node);
 
plchan-at = txd;
 
@@ -524,18 +520,18 @@ static u32 pl08x_getbytes_chan(struct pl08x_dma_chan 
*plchan)
}
 
/* Sum up all queued transactions */
-   if (!list_empty(plchan-issued_list)) {
+   if (!list_empty(plchan-vc.desc_issued)) {
struct pl08x_txd *txdi;
-   list_for_each_entry(txdi, plchan-issued_list, node) {
+   list_for_each_entry(txdi, plchan-vc.desc_issued, vd.node) {
struct pl08x_sg *dsg;
list_for_each_entry(dsg, txd-dsg_list, node)
bytes += dsg-len;
}
}
 
-   if (!list_empty(plchan-pend_list)) {
+   if (!list_empty(plchan-vc.desc_submitted)) {
struct pl08x_txd *txdi;
-   list_for_each_entry(txdi, plchan-pend_list, node) {
+   list_for_each_entry(txdi, plchan-vc.desc_submitted, vd.node) {
struct pl08x_sg *dsg;
list_for_each_entry(dsg, txd-dsg_list, node)
bytes += dsg-len;
@@ -1094,13 +1090,12 @@ static void pl08x_free_txd_list(struct 
pl08x_driver_data *pl08x,
LIST_HEAD(head);
struct pl08x_txd *txd;
 
-   list_splice_tail_init(plchan-issued_list, head);
-   list_splice_tail_init(plchan-pend_list, head);
+   vchan_get_all_descriptors(plchan-vc, head);
 
while (!list_empty(head)) {
-   txd = list_first_entry(head, struct pl08x_txd, node);
+   txd = list_first_entry(head, struct pl08x_txd, vd.node);
pl08x_release_mux(plchan);
-   list_del(txd-node);
+   list_del(txd-vd.node);
pl08x_free_txd(pl08x, txd);
}
 }
@@ -1117,23 +1112,6 @@ static void pl08x_free_chan_resources(struct dma_chan 
*chan)
 {
 }
 
-static dma_cookie_t pl08x_tx_submit(struct dma_async_tx_descriptor *tx)
-{
-   struct pl08x_dma_chan *plchan = to_pl08x_chan(tx-chan);
-   struct pl08x_txd *txd = to_pl08x_txd(tx);
-   unsigned long flags;
-   dma_cookie_t cookie;
-
-   spin_lock_irqsave(plchan-vc.lock, flags);
-   cookie = dma_cookie_assign(tx);
-
-   /* Put this onto the pending list */
-   list_add_tail(txd-node, plchan-pend_list);
-   spin_unlock_irqrestore(plchan-vc.lock, flags);
-
-   return cookie;
-}
-
 static struct dma_async_tx_descriptor *pl08x_prep_dma_interrupt(
struct dma_chan *chan, unsigned long flags)
 {
@@ -1318,8 +1296,7 @@ static void pl08x_issue_pending(struct dma_chan *chan)
unsigned long flags;
 
spin_lock_irqsave(plchan-vc.lock, flags);
-   list_splice_tail_init(plchan-pend_list, plchan-issued_list);
-   if (!list_empty(plchan-issued_list)) {
+   if (vchan_issue_pending(plchan-vc)) {
if (!plchan-phychan  plchan-state != PL08X_CHAN_WAITING)
pl08x_phy_alloc_and_start(plchan);
}
@@ -1345,16 +1322,11 @@ static int pl08x_prep_channel_resources(struct 
pl08x_dma_chan *plchan,
return 0;
 }
 
-static struct pl08x_txd 

[CFT 29/31] dmaengine: PL08x: get rid of pl08x_prep_channel_resources

2012-06-07 Thread Russell King
This function is now unnecessary; we can move its internals inline
instead.

Acked-by: Linus Walleij linus.wall...@linaro.org
Signed-off-by: Russell King rmk+ker...@arm.linux.org.uk
---
 drivers/dma/amba-pl08x.c |   32 +---
 1 files changed, 9 insertions(+), 23 deletions(-)

diff --git a/drivers/dma/amba-pl08x.c b/drivers/dma/amba-pl08x.c
index c42c7ef..9297240 100644
--- a/drivers/dma/amba-pl08x.c
+++ b/drivers/dma/amba-pl08x.c
@@ -1352,25 +1352,6 @@ static void pl08x_issue_pending(struct dma_chan *chan)
spin_unlock_irqrestore(plchan-vc.lock, flags);
 }
 
-static int pl08x_prep_channel_resources(struct pl08x_dma_chan *plchan,
-   struct pl08x_txd *txd)
-{
-   struct pl08x_driver_data *pl08x = plchan-host;
-   int num_llis;
-
-   num_llis = pl08x_fill_llis_for_desc(pl08x, txd);
-   if (!num_llis) {
-   unsigned long flags;
-
-   spin_lock_irqsave(plchan-vc.lock, flags);
-   pl08x_free_txd(pl08x, txd);
-   spin_unlock_irqrestore(plchan-vc.lock, flags);
-
-   return -EINVAL;
-   }
-   return 0;
-}
-
 static struct pl08x_txd *pl08x_get_txd(struct pl08x_dma_chan *plchan)
 {
struct pl08x_txd *txd = kzalloc(sizeof(*txd), GFP_NOWAIT);
@@ -1430,9 +1411,11 @@ static struct dma_async_tx_descriptor 
*pl08x_prep_dma_memcpy(
txd-cctl |= pl08x_select_bus(pl08x-mem_buses,
  pl08x-mem_buses);
 
-   ret = pl08x_prep_channel_resources(plchan, txd);
-   if (ret)
+   ret = pl08x_fill_llis_for_desc(plchan-host, txd);
+   if (!ret) {
+   pl08x_free_txd(pl08x, txd);
return NULL;
+   }
 
return vchan_tx_prep(plchan-vc, txd-vd, flags);
 }
@@ -1546,9 +1529,12 @@ static struct dma_async_tx_descriptor 
*pl08x_prep_slave_sg(
}
}
 
-   ret = pl08x_prep_channel_resources(plchan, txd);
-   if (ret)
+   ret = pl08x_fill_llis_for_desc(plchan-host, txd);
+   if (!ret) {
+   pl08x_release_mux(plchan);
+   pl08x_free_txd(pl08x, txd);
return NULL;
+   }
 
return vchan_tx_prep(plchan-vc, txd-vd, flags);
 }
-- 
1.7.4.4

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[CFT 30/31] dmaengine: PL08x: get rid of write only pool_ctr and free_txd locking

2012-06-07 Thread Russell King
The free function says the pl08x lock should be taken before calling
it.  However, the DMA pool allocation/freeing is already properly
locked.  The only thing that would need this is pool_ctr, which
happens to be a write-only variable.

Let's get rid of this, and eliminate any need for additional locking
here.

Acked-by: Linus Walleij linus.wall...@linaro.org
Signed-off-by: Russell King rmk+ker...@arm.linux.org.uk
---
 drivers/dma/amba-pl08x.c |   12 
 1 files changed, 0 insertions(+), 12 deletions(-)

diff --git a/drivers/dma/amba-pl08x.c b/drivers/dma/amba-pl08x.c
index 9297240..a5d85b1 100644
--- a/drivers/dma/amba-pl08x.c
+++ b/drivers/dma/amba-pl08x.c
@@ -247,7 +247,6 @@ struct pl08x_dma_chan {
  * @pd: platform data passed in from the platform/machine
  * @phy_chans: array of data for the physical channels
  * @pool: a pool for the LLI descriptors
- * @pool_ctr: counter of LLIs in the pool
  * @lli_buses: bitmask to or in to LLI pointer selecting AHB port for LLI
  * fetches
  * @mem_buses: set to indicate memory transfers on AHB2.
@@ -262,7 +261,6 @@ struct pl08x_driver_data {
struct pl08x_platform_data *pd;
struct pl08x_phy_chan *phy_chans;
struct dma_pool *pool;
-   int pool_ctr;
u8 lli_buses;
u8 mem_buses;
 };
@@ -821,8 +819,6 @@ static int pl08x_fill_llis_for_desc(struct 
pl08x_driver_data *pl08x,
return 0;
}
 
-   pl08x-pool_ctr++;
-
bd.txd = txd;
bd.lli_bus = (pl08x-lli_buses  PL08X_AHB2) ? PL080_LLI_LM_AHB2 : 0;
cctl = txd-cctl;
@@ -1038,18 +1034,14 @@ static int pl08x_fill_llis_for_desc(struct 
pl08x_driver_data *pl08x,
return num_llis;
 }
 
-/* You should call this with the struct pl08x lock held */
 static void pl08x_free_txd(struct pl08x_driver_data *pl08x,
   struct pl08x_txd *txd)
 {
struct pl08x_sg *dsg, *_dsg;
 
-   /* Free the LLI */
if (txd-llis_va)
dma_pool_free(pl08x-pool, txd-llis_va, txd-llis_bus);
 
-   pl08x-pool_ctr--;
-
list_for_each_entry_safe(dsg, _dsg, txd-dsg_list, node) {
list_del(dsg-node);
kfree(dsg);
@@ -1090,8 +1082,6 @@ static void pl08x_desc_free(struct virt_dma_desc *vd)
 {
struct pl08x_txd *txd = to_pl08x_txd(vd-tx);
struct pl08x_dma_chan *plchan = to_pl08x_chan(vd-tx.chan);
-   struct pl08x_driver_data *pl08x = plchan-host;
-   unsigned long flags;
 
if (!plchan-slave)
pl08x_unmap_buffers(txd);
@@ -1099,9 +1089,7 @@ static void pl08x_desc_free(struct virt_dma_desc *vd)
if (!txd-done)
pl08x_release_mux(plchan);
 
-   spin_lock_irqsave(pl08x-lock, flags);
pl08x_free_txd(plchan-host, txd);
-   spin_unlock_irqrestore(pl08x-lock, flags);
 }
 
 static void pl08x_free_txd_list(struct pl08x_driver_data *pl08x,
-- 
1.7.4.4

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[CFT 28/31] dmaengine: PL08x: fix tx_status function to return correct residue

2012-06-07 Thread Russell King
Now that we're converted to use the generic vchan support, we can fix
the residue return from tx_status to be compliant with dmaengine.  This
returns the number of bytes remaining for the _specified_ cookie, not
the number of bytes in all pending transfers on the channel.

Acked-by: Linus Walleij linus.wall...@linaro.org
Signed-off-by: Russell King rmk+ker...@arm.linux.org.uk
---
 drivers/dma/amba-pl08x.c |   61 +
 1 files changed, 34 insertions(+), 27 deletions(-)

diff --git a/drivers/dma/amba-pl08x.c b/drivers/dma/amba-pl08x.c
index 6a35e37..c42c7ef 100644
--- a/drivers/dma/amba-pl08x.c
+++ b/drivers/dma/amba-pl08x.c
@@ -473,10 +473,8 @@ static u32 pl08x_getbytes_chan(struct pl08x_dma_chan 
*plchan)
 {
struct pl08x_phy_chan *ch;
struct pl08x_txd *txd;
-   unsigned long flags;
size_t bytes = 0;
 
-   spin_lock_irqsave(plchan-vc.lock, flags);
ch = plchan-phychan;
txd = plchan-at;
 
@@ -516,27 +514,6 @@ static u32 pl08x_getbytes_chan(struct pl08x_dma_chan 
*plchan)
}
}
 
-   /* Sum up all queued transactions */
-   if (!list_empty(plchan-vc.desc_issued)) {
-   struct pl08x_txd *txdi;
-   list_for_each_entry(txdi, plchan-vc.desc_issued, vd.node) {
-   struct pl08x_sg *dsg;
-   list_for_each_entry(dsg, txd-dsg_list, node)
-   bytes += dsg-len;
-   }
-   }
-
-   if (!list_empty(plchan-vc.desc_submitted)) {
-   struct pl08x_txd *txdi;
-   list_for_each_entry(txdi, plchan-vc.desc_submitted, vd.node) {
-   struct pl08x_sg *dsg;
-   list_for_each_entry(dsg, txd-dsg_list, node)
-   bytes += dsg-len;
-   }
-   }
-
-   spin_unlock_irqrestore(plchan-vc.lock, flags);
-
return bytes;
 }
 
@@ -1171,23 +1148,53 @@ static enum dma_status pl08x_dma_tx_status(struct 
dma_chan *chan,
dma_cookie_t cookie, struct dma_tx_state *txstate)
 {
struct pl08x_dma_chan *plchan = to_pl08x_chan(chan);
+   struct virt_dma_desc *vd;
+   unsigned long flags;
enum dma_status ret;
+   size_t bytes = 0;
 
ret = dma_cookie_status(chan, cookie, txstate);
if (ret == DMA_SUCCESS)
return ret;
 
/*
+* There's no point calculating the residue if there's
+* no txstate to store the value.
+*/
+   if (!txstate) {
+   if (plchan-state == PL08X_CHAN_PAUSED)
+   ret = DMA_PAUSED;
+   return ret;
+   }
+
+   spin_lock_irqsave(plchan-vc.lock, flags);
+   ret = dma_cookie_status(chan, cookie, txstate);
+   if (ret != DMA_SUCCESS) {
+   vd = vchan_find_desc(plchan-vc, cookie);
+   if (vd) {
+   /* On the issued list, so hasn't been processed yet */
+   struct pl08x_txd *txd = to_pl08x_txd(vd-tx);
+   struct pl08x_sg *dsg;
+
+   list_for_each_entry(dsg, txd-dsg_list, node)
+   bytes += dsg-len;
+   } else {
+   bytes = pl08x_getbytes_chan(plchan);
+   }
+   }
+   spin_unlock_irqrestore(plchan-vc.lock, flags);
+
+   /*
 * This cookie not complete yet
 * Get number of bytes left in the active transactions and queue
 */
-   dma_set_residue(txstate, pl08x_getbytes_chan(plchan));
+   dma_set_residue(txstate, bytes);
 
-   if (plchan-state == PL08X_CHAN_PAUSED)
-   return DMA_PAUSED;
+   if (plchan-state == PL08X_CHAN_PAUSED  ret == DMA_IN_PROGRESS)
+   ret = DMA_PAUSED;
 
/* Whether waiting or running, we're in progress */
-   return DMA_IN_PROGRESS;
+   return ret;
 }
 
 /* PrimeCell DMA extension */
-- 
1.7.4.4

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[CFT 31/31] dmaengine: PL08x: ensure all descriptors are freed when channel is released

2012-06-07 Thread Russell King
Ensure all queued descriptors are freed when the channel is released,
ensuring we don't leak memory

Acked-by: Linus Walleij linus.wall...@linaro.org
Signed-off-by: Russell King rmk+ker...@arm.linux.org.uk
---
 drivers/dma/amba-pl08x.c |2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/drivers/dma/amba-pl08x.c b/drivers/dma/amba-pl08x.c
index a5d85b1..6fbeebb 100644
--- a/drivers/dma/amba-pl08x.c
+++ b/drivers/dma/amba-pl08x.c
@@ -1117,6 +1117,8 @@ static int pl08x_alloc_chan_resources(struct dma_chan 
*chan)
 
 static void pl08x_free_chan_resources(struct dma_chan *chan)
 {
+   /* Ensure all queued descriptors are freed */
+   vchan_free_chan_resources(to_virt_chan(chan));
 }
 
 static struct dma_async_tx_descriptor *pl08x_prep_dma_interrupt(
-- 
1.7.4.4

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[CFT] OMAP patches

2012-06-07 Thread Russell King - ARM Linux
And the last set - the OMAP patches.

 Documentation/feature-removal-schedule.txt |   11 +
 arch/arm/mach-omap1/board-h2-mmc.c |1 -
 arch/arm/mach-omap1/board-h3-mmc.c |1 -
 arch/arm/mach-omap1/board-nokia770.c   |1 -
 arch/arm/mach-omap2/board-n8x0.c   |1 -
 arch/arm/mach-omap2/hsmmc.c|1 -
 arch/arm/plat-omap/include/plat/mmc.h  |2 -
 drivers/dma/Kconfig|6 +
 drivers/dma/Makefile   |1 +
 drivers/dma/omap-dma.c |  522 
 drivers/mmc/host/omap.c|  368 +---
 drivers/mmc/host/omap_hsmmc.c  |  202 ++--
 drivers/mtd/nand/omap2.c   |  106 +++---
 drivers/spi/spi-omap2-mcspi.c  |  229 +++--
 include/linux/omap-dma.h   |   24 ++
 15 files changed, 1010 insertions(+), 466 deletions(-)

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[CFT 01/11] dmaengine: add OMAP DMA engine driver

2012-06-07 Thread Russell King
Tested-by: Tony Lindgren t...@atomide.com
Signed-off-by: Russell King rmk+ker...@arm.linux.org.uk
---
 drivers/dma/Kconfig  |6 +
 drivers/dma/Makefile |1 +
 drivers/dma/omap-dma.c   |  522 ++
 include/linux/omap-dma.h |   24 ++
 4 files changed, 553 insertions(+), 0 deletions(-)
 create mode 100644 drivers/dma/omap-dma.c
 create mode 100644 include/linux/omap-dma.h

diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
index eb2b60e..8be3bf6 100644
--- a/drivers/dma/Kconfig
+++ b/drivers/dma/Kconfig
@@ -261,6 +261,12 @@ config DMA_SA11X0
  SA-1110 SoCs.  This DMA engine can only be used with on-chip
  devices.
 
+config DMA_OMAP
+   tristate OMAP DMA support
+   depends on ARCH_OMAP
+   select DMA_ENGINE
+   select DMA_VIRTUAL_CHANNELS
+
 config DMA_ENGINE
bool
 
diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile
index fc05f7d..ddc291a 100644
--- a/drivers/dma/Makefile
+++ b/drivers/dma/Makefile
@@ -29,3 +29,4 @@ obj-$(CONFIG_PCH_DMA) += pch_dma.o
 obj-$(CONFIG_AMBA_PL08X) += amba-pl08x.o
 obj-$(CONFIG_EP93XX_DMA) += ep93xx_dma.o
 obj-$(CONFIG_DMA_SA11X0) += sa11x0-dma.o
+obj-$(CONFIG_DMA_OMAP) += omap-dma.o
diff --git a/drivers/dma/omap-dma.c b/drivers/dma/omap-dma.c
new file mode 100644
index 000..500bc71
--- /dev/null
+++ b/drivers/dma/omap-dma.c
@@ -0,0 +1,522 @@
+/*
+ * OMAP DMAengine support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include linux/dmaengine.h
+#include linux/dma-mapping.h
+#include linux/err.h
+#include linux/init.h
+#include linux/interrupt.h
+#include linux/list.h
+#include linux/module.h
+#include linux/omap-dma.h
+#include linux/platform_device.h
+#include linux/slab.h
+#include linux/spinlock.h
+
+#include virt-dma.h
+#include plat/dma.h
+
+struct omap_dmadev {
+   struct dma_device ddev;
+   spinlock_t lock;
+   struct tasklet_struct task;
+   struct list_head pending;
+};
+
+struct omap_chan {
+   struct virt_dma_chan vc;
+   struct list_head node;
+
+   struct dma_slave_config cfg;
+   unsigned dma_sig;
+
+   int dma_ch;
+   struct omap_desc *desc;
+   unsigned sgidx;
+};
+
+struct omap_sg {
+   dma_addr_t addr;
+   uint32_t en;/* number of elements (24-bit) */
+   uint32_t fn;/* number of frames (16-bit) */
+};
+
+struct omap_desc {
+   struct virt_dma_desc vd;
+   enum dma_transfer_direction dir;
+   dma_addr_t dev_addr;
+
+   uint8_t es; /* element size */
+   uint8_t sync_mode;  /* OMAP_DMA_SYNC_xxx */
+   uint8_t sync_type;  /* OMAP_DMA_xxx_SYNC* */
+   uint8_t periph_port;/* Peripheral port */
+
+   unsigned sglen;
+   struct omap_sg sg[0];
+};
+
+static inline struct omap_dmadev *to_omap_dma_dev(struct dma_device *d)
+{
+   return container_of(d, struct omap_dmadev, ddev);
+}
+
+static inline struct omap_chan *to_omap_dma_chan(struct dma_chan *c)
+{
+   return container_of(c, struct omap_chan, vc.chan);
+}
+
+static inline struct omap_desc *to_omap_dma_desc(struct 
dma_async_tx_descriptor *t)
+{
+   return container_of(t, struct omap_desc, vd.tx);
+}
+
+static void omap_dma_desc_free(struct virt_dma_desc *vd)
+{
+   kfree(container_of(vd, struct omap_desc, vd));
+}
+
+static void omap_dma_start_sg(struct omap_chan *c, struct omap_desc *d,
+   unsigned idx)
+{
+   struct omap_sg *sg = d-sg + idx;
+
+   if (d-dir == DMA_DEV_TO_MEM)
+   omap_set_dma_dest_params(c-dma_ch, OMAP_DMA_PORT_EMIFF,
+   OMAP_DMA_AMODE_POST_INC, sg-addr, 0, 0);
+   else
+   omap_set_dma_src_params(c-dma_ch, OMAP_DMA_PORT_EMIFF,
+   OMAP_DMA_AMODE_POST_INC, sg-addr, 0, 0);
+
+   omap_set_dma_transfer_params(c-dma_ch, d-es, sg-en, sg-fn,
+   d-sync_mode, c-dma_sig, d-sync_type);
+
+   omap_start_dma(c-dma_ch);
+}
+
+static void omap_dma_start_desc(struct omap_chan *c)
+{
+   struct virt_dma_desc *vd = vchan_next_desc(c-vc);
+   struct omap_desc *d;
+
+   if (!vd) {
+   c-desc = NULL;
+   return;
+   }
+
+   list_del(vd-node);
+
+   c-desc = d = to_omap_dma_desc(vd-tx);
+   c-sgidx = 0;
+
+   if (d-dir == DMA_DEV_TO_MEM)
+   omap_set_dma_src_params(c-dma_ch, d-periph_port,
+   OMAP_DMA_AMODE_CONSTANT, d-dev_addr, 0, 0);
+   else
+   omap_set_dma_dest_params(c-dma_ch, d-periph_port,
+   OMAP_DMA_AMODE_CONSTANT, d-dev_addr, 0, 0);
+
+   omap_dma_start_sg(c, d, 0);
+}
+
+static void omap_dma_callback(int ch, u16 status, void *data)
+{
+   struct omap_chan *c = data;
+   struct omap_desc *d;
+   unsigned long flags;
+
+   

[CFT 02/11] mmc: omap_hsmmc: add DMA engine support

2012-06-07 Thread Russell King
Add DMA engine support to the OMAP HSMMC driver.  This supplements the
private DMA API implementation contained within this driver, and the
driver can be switched at build time between using DMA engine and the
private DMA API.

Tested-by: Grazvydas Ignotas nota...@gmail.com
Signed-off-by: Russell King rmk+ker...@arm.linux.org.uk
---
 drivers/mmc/host/omap_hsmmc.c |  192 +++--
 1 files changed, 165 insertions(+), 27 deletions(-)

diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index 9a7a60a..f80361f 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -19,6 +19,7 @@
 #include linux/init.h
 #include linux/kernel.h
 #include linux/debugfs.h
+#include linux/dmaengine.h
 #include linux/seq_file.h
 #include linux/interrupt.h
 #include linux/delay.h
@@ -167,7 +168,9 @@ struct omap_hsmmc_host {
u32 bytesleft;
int suspended;
int irq;
-   int use_dma, dma_ch;
+   int use_dma, dma_ch, dma2;
+   struct dma_chan *tx_chan;
+   struct dma_chan *rx_chan;
int dma_line_tx, dma_line_rx;
int slot_id;
int response_busy;
@@ -802,19 +805,26 @@ omap_hsmmc_get_dma_dir(struct omap_hsmmc_host *host, 
struct mmc_data *data)
return DMA_FROM_DEVICE;
 }
 
+static struct dma_chan *omap_hsmmc_get_dma_chan(struct omap_hsmmc_host *host,
+   struct mmc_data *data)
+{
+   return data-flags  MMC_DATA_WRITE ? host-tx_chan : host-rx_chan;
+}
+
 static void omap_hsmmc_request_done(struct omap_hsmmc_host *host, struct 
mmc_request *mrq)
 {
-   int dma_ch;
+   int dma_ch, dma2;
unsigned long flags;
 
spin_lock_irqsave(host-irq_lock, flags);
host-req_in_progress = 0;
dma_ch = host-dma_ch;
+   dma2 = host-dma2;
spin_unlock_irqrestore(host-irq_lock, flags);
 
omap_hsmmc_disable_irq(host);
/* Do not complete the request if DMA is still in progress */
-   if (mrq-data  host-use_dma  dma_ch != -1)
+   if (mrq-data  host-use_dma  (dma_ch != -1 || dma2 != -1))
return;
host-mrq = NULL;
mmc_request_done(host-mmc, mrq);
@@ -886,7 +896,7 @@ omap_hsmmc_cmd_done(struct omap_hsmmc_host *host, struct 
mmc_command *cmd)
  */
 static void omap_hsmmc_dma_cleanup(struct omap_hsmmc_host *host, int errno)
 {
-   int dma_ch;
+   int dma_ch, dma2;
unsigned long flags;
 
host-data-error = errno;
@@ -894,8 +904,20 @@ static void omap_hsmmc_dma_cleanup(struct omap_hsmmc_host 
*host, int errno)
spin_lock_irqsave(host-irq_lock, flags);
dma_ch = host-dma_ch;
host-dma_ch = -1;
+   dma2 = host-dma2;
+   host-dma2 = -1;
spin_unlock_irqrestore(host-irq_lock, flags);
 
+   if (host-use_dma  dma2 != -1) {
+   struct dma_chan *chan = omap_hsmmc_get_dma_chan(host, 
host-data);
+
+   dmaengine_terminate_all(chan);
+   dma_unmap_sg(chan-device-dev,
+   host-data-sg, host-data-sg_len,
+   omap_hsmmc_get_dma_dir(host, host-data));
+
+   host-data-host_cookie = 0;
+   }
if (host-use_dma  dma_ch != -1) {
dma_unmap_sg(mmc_dev(host-mmc), host-data-sg,
host-data-sg_len,
@@ -1292,9 +1314,43 @@ static void omap_hsmmc_dma_cb(int lch, u16 ch_status, 
void *cb_data)
}
 }
 
+static void omap_hsmmc_dma_callback(void *param)
+{
+   struct omap_hsmmc_host *host = param;
+   struct dma_chan *chan;
+   struct mmc_data *data;
+   int req_in_progress;
+
+   spin_lock_irq(host-irq_lock);
+   if (host-dma2  0) {
+   spin_unlock_irq(host-irq_lock);
+   return;
+   }
+
+   data = host-mrq-data;
+   chan = omap_hsmmc_get_dma_chan(host, data);
+   if (!data-host_cookie)
+   dma_unmap_sg(chan-device-dev,
+data-sg, data-sg_len,
+omap_hsmmc_get_dma_dir(host, data));
+
+   req_in_progress = host-req_in_progress;
+   host-dma2 = -1;
+   spin_unlock_irq(host-irq_lock);
+
+   /* If DMA has finished after TC, complete the request */
+   if (!req_in_progress) {
+   struct mmc_request *mrq = host-mrq;
+
+   host-mrq = NULL;
+   mmc_request_done(host-mmc, mrq);
+   }
+}
+
 static int omap_hsmmc_pre_dma_transfer(struct omap_hsmmc_host *host,
   struct mmc_data *data,
-  struct omap_hsmmc_next *next)
+  struct omap_hsmmc_next *next,
+  struct device *dev)
 {
int dma_len;
 
@@ -1309,8 +1365,7 @@ static int 

[CFT 03/11] mmc: omap_hsmmc: remove private DMA API implementation

2012-06-07 Thread Russell King
Remove the private DMA API implementation from omap_hsmmc, making it
use entirely the DMA engine API.

Signed-off-by: Russell King rmk+ker...@arm.linux.org.uk
---
 drivers/mmc/host/omap_hsmmc.c |  265 ++---
 1 files changed, 64 insertions(+), 201 deletions(-)

diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index f80361f..9504092 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -38,7 +38,6 @@
 #include linux/gpio.h
 #include linux/regulator/consumer.h
 #include linux/pm_runtime.h
-#include plat/dma.h
 #include mach/hardware.h
 #include plat/board.h
 #include plat/mmc.h
@@ -168,10 +167,9 @@ struct omap_hsmmc_host {
u32 bytesleft;
int suspended;
int irq;
-   int use_dma, dma_ch, dma2;
+   int use_dma, dma_ch;
struct dma_chan *tx_chan;
struct dma_chan *rx_chan;
-   int dma_line_tx, dma_line_rx;
int slot_id;
int response_busy;
int context_loss;
@@ -813,18 +811,17 @@ static struct dma_chan *omap_hsmmc_get_dma_chan(struct 
omap_hsmmc_host *host,
 
 static void omap_hsmmc_request_done(struct omap_hsmmc_host *host, struct 
mmc_request *mrq)
 {
-   int dma_ch, dma2;
+   int dma_ch;
unsigned long flags;
 
spin_lock_irqsave(host-irq_lock, flags);
host-req_in_progress = 0;
dma_ch = host-dma_ch;
-   dma2 = host-dma2;
spin_unlock_irqrestore(host-irq_lock, flags);
 
omap_hsmmc_disable_irq(host);
/* Do not complete the request if DMA is still in progress */
-   if (mrq-data  host-use_dma  (dma_ch != -1 || dma2 != -1))
+   if (mrq-data  host-use_dma  dma_ch != -1)
return;
host-mrq = NULL;
mmc_request_done(host-mmc, mrq);
@@ -896,7 +893,7 @@ omap_hsmmc_cmd_done(struct omap_hsmmc_host *host, struct 
mmc_command *cmd)
  */
 static void omap_hsmmc_dma_cleanup(struct omap_hsmmc_host *host, int errno)
 {
-   int dma_ch, dma2;
+   int dma_ch;
unsigned long flags;
 
host-data-error = errno;
@@ -904,11 +901,9 @@ static void omap_hsmmc_dma_cleanup(struct omap_hsmmc_host 
*host, int errno)
spin_lock_irqsave(host-irq_lock, flags);
dma_ch = host-dma_ch;
host-dma_ch = -1;
-   dma2 = host-dma2;
-   host-dma2 = -1;
spin_unlock_irqrestore(host-irq_lock, flags);
 
-   if (host-use_dma  dma2 != -1) {
+   if (host-use_dma  dma_ch != -1) {
struct dma_chan *chan = omap_hsmmc_get_dma_chan(host, 
host-data);
 
dmaengine_terminate_all(chan);
@@ -918,13 +913,6 @@ static void omap_hsmmc_dma_cleanup(struct omap_hsmmc_host 
*host, int errno)
 
host-data-host_cookie = 0;
}
-   if (host-use_dma  dma_ch != -1) {
-   dma_unmap_sg(mmc_dev(host-mmc), host-data-sg,
-   host-data-sg_len,
-   omap_hsmmc_get_dma_dir(host, host-data));
-   omap_free_dma(dma_ch);
-   host-data-host_cookie = 0;
-   }
host-data = NULL;
 }
 
@@ -1220,100 +1208,6 @@ static irqreturn_t omap_hsmmc_detect(int irq, void 
*dev_id)
return IRQ_HANDLED;
 }
 
-static int omap_hsmmc_get_dma_sync_dev(struct omap_hsmmc_host *host,
-struct mmc_data *data)
-{
-   int sync_dev;
-
-   if (data-flags  MMC_DATA_WRITE)
-   sync_dev = host-dma_line_tx;
-   else
-   sync_dev = host-dma_line_rx;
-   return sync_dev;
-}
-
-static void omap_hsmmc_config_dma_params(struct omap_hsmmc_host *host,
-  struct mmc_data *data,
-  struct scatterlist *sgl)
-{
-   int blksz, nblk, dma_ch;
-
-   dma_ch = host-dma_ch;
-   if (data-flags  MMC_DATA_WRITE) {
-   omap_set_dma_dest_params(dma_ch, 0, OMAP_DMA_AMODE_CONSTANT,
-   (host-mapbase + OMAP_HSMMC_DATA), 0, 0);
-   omap_set_dma_src_params(dma_ch, 0, OMAP_DMA_AMODE_POST_INC,
-   sg_dma_address(sgl), 0, 0);
-   } else {
-   omap_set_dma_src_params(dma_ch, 0, OMAP_DMA_AMODE_CONSTANT,
-   (host-mapbase + OMAP_HSMMC_DATA), 0, 0);
-   omap_set_dma_dest_params(dma_ch, 0, OMAP_DMA_AMODE_POST_INC,
-   sg_dma_address(sgl), 0, 0);
-   }
-
-   blksz = host-data-blksz;
-   nblk = sg_dma_len(sgl) / blksz;
-
-   omap_set_dma_transfer_params(dma_ch, OMAP_DMA_DATA_TYPE_S32,
-   blksz / 4, nblk, OMAP_DMA_SYNC_FRAME,
-   omap_hsmmc_get_dma_sync_dev(host, data),
-   !(data-flags  MMC_DATA_WRITE));
-
-   omap_start_dma(dma_ch);
-}
-

[CFT 04/11] mmc: omap: add DMA engine support

2012-06-07 Thread Russell King
Add DMA engine support to the OMAP driver.  This supplements the
private DMA API implementation contained within this driver, and the
driver can be switched at build time between using DMA engine and the
private DMA API.

Signed-off-by: Russell King rmk+ker...@arm.linux.org.uk
---
 drivers/mmc/host/omap.c   |  199 ++--
 drivers/mmc/host/omap_hsmmc.c |3 +-
 2 files changed, 190 insertions(+), 12 deletions(-)

diff --git a/drivers/mmc/host/omap.c b/drivers/mmc/host/omap.c
index 552196c..eaea251 100644
--- a/drivers/mmc/host/omap.c
+++ b/drivers/mmc/host/omap.c
@@ -17,10 +17,12 @@
 #include linux/ioport.h
 #include linux/platform_device.h
 #include linux/interrupt.h
+#include linux/dmaengine.h
 #include linux/dma-mapping.h
 #include linux/delay.h
 #include linux/spinlock.h
 #include linux/timer.h
+#include linux/omap-dma.h
 #include linux/mmc/host.h
 #include linux/mmc/card.h
 #include linux/clk.h
@@ -99,6 +101,8 @@
 
 struct mmc_omap_host;
 
+#define USE_DMA_PRIVATE
+
 struct mmc_omap_slot {
int id;
unsigned intvdd;
@@ -128,6 +132,10 @@ struct mmc_omap_host {
unsigned char   id; /* 16xx chips have 2 MMC blocks */
struct clk *iclk;
struct clk *fclk;
+   struct dma_chan *dma_rx;
+   u32 dma_rx_burst;
+   struct dma_chan *dma_tx;
+   u32 dma_tx_burst;
struct resource *mem_res;
void __iomem*virt_base;
unsigned intphys_base;
@@ -153,12 +161,14 @@ struct mmc_omap_host {
 
unsigneduse_dma:1;
unsignedbrs_received:1, dma_done:1;
-   unsigneddma_is_read:1;
unsigneddma_in_use:1;
+#ifdef USE_DMA_PRIVATE
+   unsigneddma_is_read:1;
int dma_ch;
-   spinlock_t  dma_lock;
struct timer_list   dma_timer;
unsigneddma_len;
+#endif
+   spinlock_t  dma_lock;
 
struct mmc_omap_slot*slots[OMAP_MMC_MAX_SLOTS];
struct mmc_omap_slot*current_slot;
@@ -406,18 +416,32 @@ mmc_omap_release_dma(struct mmc_omap_host *host, struct 
mmc_data *data,
 int abort)
 {
enum dma_data_direction dma_data_dir;
+   struct device *dev = mmc_dev(host-mmc);
+   struct dma_chan *c;
 
+#ifdef USE_DMA_PRIVATE
BUG_ON(host-dma_ch  0);
if (data-error)
omap_stop_dma(host-dma_ch);
/* Release DMA channel lazily */
mod_timer(host-dma_timer, jiffies + HZ);
-   if (data-flags  MMC_DATA_WRITE)
+#endif
+   if (data-flags  MMC_DATA_WRITE) {
dma_data_dir = DMA_TO_DEVICE;
-   else
+   c = host-dma_tx;
+   } else {
dma_data_dir = DMA_FROM_DEVICE;
-   dma_unmap_sg(mmc_dev(host-mmc), data-sg, host-sg_len,
-dma_data_dir);
+   c = host-dma_rx;
+   }
+   if (c) {
+   if (data-error) {
+   dmaengine_terminate_all(c);
+   /* Claim nothing transferred on error... */
+   data-bytes_xfered = 0;
+   }
+   dev = c-device-dev;
+   }
+   dma_unmap_sg(dev, data-sg, host-sg_len, dma_data_dir);
 }
 
 static void mmc_omap_send_stop_work(struct work_struct *work)
@@ -524,6 +548,7 @@ mmc_omap_end_of_data(struct mmc_omap_host *host, struct 
mmc_data *data)
mmc_omap_xfer_done(host, data);
 }
 
+#ifdef USE_DMA_PRIVATE
 static void
 mmc_omap_dma_timer(unsigned long data)
 {
@@ -533,6 +558,7 @@ mmc_omap_dma_timer(unsigned long data)
omap_free_dma(host-dma_ch);
host-dma_ch = -1;
 }
+#endif
 
 static void
 mmc_omap_dma_done(struct mmc_omap_host *host, struct mmc_data *data)
@@ -891,6 +917,18 @@ static void mmc_omap_cover_handler(unsigned long param)
  jiffies + msecs_to_jiffies(OMAP_MMC_COVER_POLL_DELAY));
 }
 
+static void mmc_omap_dma_callback(void *priv)
+{
+   struct mmc_omap_host *host = priv;
+   struct mmc_data *data = host-data;
+
+   /* If we got to the end of DMA, assume everything went well */
+   data-bytes_xfered += data-blocks * data-blksz;
+
+   mmc_omap_dma_done(host, data);
+}
+
+#ifdef USE_DMA_PRIVATE
 /* Prepare to transfer the next segment of a scatterlist */
 static void
 mmc_omap_prepare_dma(struct mmc_omap_host *host, struct mmc_data *data)
@@ -1045,6 +1083,7 @@ static int mmc_omap_get_dma_channel(struct mmc_omap_host 
*host, struct mmc_data
 
return 0;
 }
+#endif
 
 static inline void set_cmd_timeout(struct mmc_omap_host *host, struct 
mmc_request *req)
 {
@@ -1118,6 +1157,80 @@ mmc_omap_prepare_data(struct mmc_omap_host *host, struct 
mmc_request *req)
 
host-sg_idx = 0;
if (use_dma) {
+   

[CFT 05/11] mmc: omap: remove private DMA API implementation

2012-06-07 Thread Russell King
Remove the private DMA API implementation from omap, making it use
entirely the DMA engine API.

Signed-off-by: Russell King rmk+ker...@arm.linux.org.uk
---
 drivers/mmc/host/omap.c |  235 +-
 1 files changed, 6 insertions(+), 229 deletions(-)

diff --git a/drivers/mmc/host/omap.c b/drivers/mmc/host/omap.c
index eaea251..4026392 100644
--- a/drivers/mmc/host/omap.c
+++ b/drivers/mmc/host/omap.c
@@ -101,8 +101,6 @@
 
 struct mmc_omap_host;
 
-#define USE_DMA_PRIVATE
-
 struct mmc_omap_slot {
int id;
unsigned intvdd;
@@ -162,12 +160,6 @@ struct mmc_omap_host {
unsigneduse_dma:1;
unsignedbrs_received:1, dma_done:1;
unsigneddma_in_use:1;
-#ifdef USE_DMA_PRIVATE
-   unsigneddma_is_read:1;
-   int dma_ch;
-   struct timer_list   dma_timer;
-   unsigneddma_len;
-#endif
spinlock_t  dma_lock;
 
struct mmc_omap_slot*slots[OMAP_MMC_MAX_SLOTS];
@@ -419,13 +411,6 @@ mmc_omap_release_dma(struct mmc_omap_host *host, struct 
mmc_data *data,
struct device *dev = mmc_dev(host-mmc);
struct dma_chan *c;
 
-#ifdef USE_DMA_PRIVATE
-   BUG_ON(host-dma_ch  0);
-   if (data-error)
-   omap_stop_dma(host-dma_ch);
-   /* Release DMA channel lazily */
-   mod_timer(host-dma_timer, jiffies + HZ);
-#endif
if (data-flags  MMC_DATA_WRITE) {
dma_data_dir = DMA_TO_DEVICE;
c = host-dma_tx;
@@ -548,18 +533,6 @@ mmc_omap_end_of_data(struct mmc_omap_host *host, struct 
mmc_data *data)
mmc_omap_xfer_done(host, data);
 }
 
-#ifdef USE_DMA_PRIVATE
-static void
-mmc_omap_dma_timer(unsigned long data)
-{
-   struct mmc_omap_host *host = (struct mmc_omap_host *) data;
-
-   BUG_ON(host-dma_ch  0);
-   omap_free_dma(host-dma_ch);
-   host-dma_ch = -1;
-}
-#endif
-
 static void
 mmc_omap_dma_done(struct mmc_omap_host *host, struct mmc_data *data)
 {
@@ -928,163 +901,6 @@ static void mmc_omap_dma_callback(void *priv)
mmc_omap_dma_done(host, data);
 }
 
-#ifdef USE_DMA_PRIVATE
-/* Prepare to transfer the next segment of a scatterlist */
-static void
-mmc_omap_prepare_dma(struct mmc_omap_host *host, struct mmc_data *data)
-{
-   int dma_ch = host-dma_ch;
-   unsigned long data_addr;
-   u16 buf, frame;
-   u32 count;
-   struct scatterlist *sg = data-sg[host-sg_idx];
-   int src_port = 0;
-   int dst_port = 0;
-   int sync_dev = 0;
-
-   data_addr = host-phys_base + OMAP_MMC_REG(host, DATA);
-   frame = data-blksz;
-   count = sg_dma_len(sg);
-
-   if ((data-blocks == 1)  (count  data-blksz))
-   count = frame;
-
-   host-dma_len = count;
-
-   /* FIFO is 16x2 bytes on 15xx, and 32x2 bytes on 16xx and 24xx.
-* Use 16 or 32 word frames when the blocksize is at least that large.
-* Blocksize is usually 512 bytes; but not for some SD reads.
-*/
-   if (cpu_is_omap15xx()  frame  32)
-   frame = 32;
-   else if (frame  64)
-   frame = 64;
-   count /= frame;
-   frame = 1;
-
-   if (!(data-flags  MMC_DATA_WRITE)) {
-   buf = 0x800f | ((frame - 1)  8);
-
-   if (cpu_class_is_omap1()) {
-   src_port = OMAP_DMA_PORT_TIPB;
-   dst_port = OMAP_DMA_PORT_EMIFF;
-   }
-   if (cpu_is_omap24xx())
-   sync_dev = OMAP24XX_DMA_MMC1_RX;
-
-   omap_set_dma_src_params(dma_ch, src_port,
-   OMAP_DMA_AMODE_CONSTANT,
-   data_addr, 0, 0);
-   omap_set_dma_dest_params(dma_ch, dst_port,
-OMAP_DMA_AMODE_POST_INC,
-sg_dma_address(sg), 0, 0);
-   omap_set_dma_dest_data_pack(dma_ch, 1);
-   omap_set_dma_dest_burst_mode(dma_ch, OMAP_DMA_DATA_BURST_4);
-   } else {
-   buf = 0x0f80 | ((frame - 1)  0);
-
-   if (cpu_class_is_omap1()) {
-   src_port = OMAP_DMA_PORT_EMIFF;
-   dst_port = OMAP_DMA_PORT_TIPB;
-   }
-   if (cpu_is_omap24xx())
-   sync_dev = OMAP24XX_DMA_MMC1_TX;
-
-   omap_set_dma_dest_params(dma_ch, dst_port,
-OMAP_DMA_AMODE_CONSTANT,
-data_addr, 0, 0);
-   omap_set_dma_src_params(dma_ch, src_port,
-   OMAP_DMA_AMODE_POST_INC,
-   sg_dma_address(sg), 0, 0);
-   omap_set_dma_src_data_pack(dma_ch, 1);
-   omap_set_dma_src_burst_mode(dma_ch, 

[CFT 06/11] ARM: omap: remove mmc platform data dma_mask and initialization

2012-06-07 Thread Russell King
DMAengine uses the DMA engine device structure when mapping/unmapping
memory for DMA, so the MMC devices do not need their DMA masks
initialized (this reflects hardware: the MMC device is not the device
doing DMA.)

Signed-off-by: Russell King rmk+ker...@arm.linux.org.uk
---
 arch/arm/mach-omap1/board-h2-mmc.c|1 -
 arch/arm/mach-omap1/board-h3-mmc.c|1 -
 arch/arm/mach-omap1/board-nokia770.c  |1 -
 arch/arm/mach-omap2/board-n8x0.c  |1 -
 arch/arm/mach-omap2/hsmmc.c   |1 -
 arch/arm/plat-omap/include/plat/mmc.h |2 --
 6 files changed, 0 insertions(+), 7 deletions(-)

diff --git a/arch/arm/mach-omap1/board-h2-mmc.c 
b/arch/arm/mach-omap1/board-h2-mmc.c
index da0e37d..e1362ce 100644
--- a/arch/arm/mach-omap1/board-h2-mmc.c
+++ b/arch/arm/mach-omap1/board-h2-mmc.c
@@ -54,7 +54,6 @@ static struct omap_mmc_platform_data mmc1_data = {
.nr_slots   = 1,
.init   = mmc_late_init,
.cleanup= mmc_cleanup,
-   .dma_mask   = 0x,
.slots[0]   = {
.set_power  = mmc_set_power,
.ocr_mask   = MMC_VDD_32_33 | MMC_VDD_33_34,
diff --git a/arch/arm/mach-omap1/board-h3-mmc.c 
b/arch/arm/mach-omap1/board-h3-mmc.c
index f8242aa..c74daac 100644
--- a/arch/arm/mach-omap1/board-h3-mmc.c
+++ b/arch/arm/mach-omap1/board-h3-mmc.c
@@ -36,7 +36,6 @@ static int mmc_set_power(struct device *dev, int slot, int 
power_on,
  */
 static struct omap_mmc_platform_data mmc1_data = {
.nr_slots   = 1,
-   .dma_mask   = 0x,
.slots[0]   = {
.set_power  = mmc_set_power,
.ocr_mask   = MMC_VDD_32_33 | MMC_VDD_33_34,
diff --git a/arch/arm/mach-omap1/board-nokia770.c 
b/arch/arm/mach-omap1/board-nokia770.c
index 7212ae9..c54b45f 100644
--- a/arch/arm/mach-omap1/board-nokia770.c
+++ b/arch/arm/mach-omap1/board-nokia770.c
@@ -185,7 +185,6 @@ static int nokia770_mmc_get_cover_state(struct device *dev, 
int slot)
 
 static struct omap_mmc_platform_data nokia770_mmc2_data = {
.nr_slots   = 1,
-   .dma_mask   = 0x,
.max_freq   = 1200,
.slots[0]   = {
.set_power  = nokia770_mmc_set_power,
diff --git a/arch/arm/mach-omap2/board-n8x0.c b/arch/arm/mach-omap2/board-n8x0.c
index 8ca14e8..6d70e81 100644
--- a/arch/arm/mach-omap2/board-n8x0.c
+++ b/arch/arm/mach-omap2/board-n8x0.c
@@ -470,7 +470,6 @@ static struct omap_mmc_platform_data mmc1_data = {
.cleanup= n8x0_mmc_cleanup,
.shutdown   = n8x0_mmc_shutdown,
.max_freq   = 2400,
-   .dma_mask   = 0x,
.slots[0] = {
.wires  = 4,
.set_power  = n8x0_mmc_set_power,
diff --git a/arch/arm/mach-omap2/hsmmc.c b/arch/arm/mach-omap2/hsmmc.c
index be697d4..a9675d8 100644
--- a/arch/arm/mach-omap2/hsmmc.c
+++ b/arch/arm/mach-omap2/hsmmc.c
@@ -315,7 +315,6 @@ static int __init omap_hsmmc_pdata_init(struct 
omap2_hsmmc_info *c,
mmc-slots[0].caps = c-caps;
mmc-slots[0].pm_caps = c-pm_caps;
mmc-slots[0].internal_clock = !c-ext_clock;
-   mmc-dma_mask = 0x;
mmc-max_freq = c-max_freq;
if (cpu_is_omap44xx())
mmc-reg_offset = OMAP4_MMC_REG_OFFSET;
diff --git a/arch/arm/plat-omap/include/plat/mmc.h 
b/arch/arm/plat-omap/include/plat/mmc.h
index a7754a8..a76f423 100644
--- a/arch/arm/plat-omap/include/plat/mmc.h
+++ b/arch/arm/plat-omap/include/plat/mmc.h
@@ -81,8 +81,6 @@ struct omap_mmc_platform_data {
/* Return context loss count due to PM states changing */
int (*get_context_loss_count)(struct device *dev);
 
-   u64 dma_mask;
-
/* Integrating attributes from the omap_hwmod layer */
u8 controller_flags;
 
-- 
1.7.4.4

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[CFT 07/11] spi: omap2-mcspi: add DMA engine support

2012-06-07 Thread Russell King
Add DMA engine support to the OMAP SPI driver.  This supplements the
private DMA API implementation contained within this driver, and the
driver can be independently switched at build time between using DMA
engine and the private DMA API for the transmit and receive sides.

Tested-by: Shubhrajyoti shubhrajy...@ti.com
Acked-by: Grant Likely grant.lik...@secretlab.ca
Signed-off-by: Russell King rmk+ker...@arm.linux.org.uk
---
 drivers/spi/spi-omap2-mcspi.c |  183 +---
 1 files changed, 151 insertions(+), 32 deletions(-)

diff --git a/drivers/spi/spi-omap2-mcspi.c b/drivers/spi/spi-omap2-mcspi.c
index 46ef5fe..ca016df 100644
--- a/drivers/spi/spi-omap2-mcspi.c
+++ b/drivers/spi/spi-omap2-mcspi.c
@@ -20,6 +20,8 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  *
  */
+#define USE_DMA_ENGINE_RX
+#define USE_DMA_ENGINE_TX
 
 #include linux/kernel.h
 #include linux/init.h
@@ -28,6 +30,8 @@
 #include linux/device.h
 #include linux/delay.h
 #include linux/dma-mapping.h
+#include linux/dmaengine.h
+#include linux/omap-dma.h
 #include linux/platform_device.h
 #include linux/err.h
 #include linux/clk.h
@@ -93,6 +97,8 @@
 
 /* We have 2 DMA channels per CS, one for RX and one for TX */
 struct omap2_mcspi_dma {
+   struct dma_chan *dma_tx;
+   struct dma_chan *dma_rx;
int dma_tx_channel;
int dma_rx_channel;
 
@@ -300,6 +306,30 @@ static int mcspi_wait_for_reg_bit(void __iomem *reg, 
unsigned long bit)
return 0;
 }
 
+static void omap2_mcspi_rx_callback(void *data)
+{
+   struct spi_device *spi = data;
+   struct omap2_mcspi *mcspi = spi_master_get_devdata(spi-master);
+   struct omap2_mcspi_dma *mcspi_dma = 
mcspi-dma_channels[spi-chip_select];
+
+   complete(mcspi_dma-dma_rx_completion);
+
+   /* We must disable the DMA RX request */
+   omap2_mcspi_set_dma_req(spi, 1, 0);
+}
+
+static void omap2_mcspi_tx_callback(void *data)
+{
+   struct spi_device *spi = data;
+   struct omap2_mcspi *mcspi = spi_master_get_devdata(spi-master);
+   struct omap2_mcspi_dma *mcspi_dma = 
mcspi-dma_channels[spi-chip_select];
+
+   complete(mcspi_dma-dma_tx_completion);
+
+   /* We must disable the DMA TX request */
+   omap2_mcspi_set_dma_req(spi, 0, 0);
+}
+
 static unsigned
 omap2_mcspi_txrx_dma(struct spi_device *spi, struct spi_transfer *xfer)
 {
@@ -314,6 +344,9 @@ omap2_mcspi_txrx_dma(struct spi_device *spi, struct 
spi_transfer *xfer)
u8  * rx;
const u8* tx;
void __iomem*chstat_reg;
+   struct dma_slave_config cfg;
+   enum dma_slave_buswidth width;
+   unsigned es;
 
mcspi = spi_master_get_devdata(spi-master);
mcspi_dma = mcspi-dma_channels[spi-chip_select];
@@ -321,6 +354,71 @@ omap2_mcspi_txrx_dma(struct spi_device *spi, struct 
spi_transfer *xfer)
 
chstat_reg = cs-base + OMAP2_MCSPI_CHSTAT0;
 
+   if (cs-word_len = 8) {
+   width = DMA_SLAVE_BUSWIDTH_1_BYTE;
+   es = 1;
+   } else if (cs-word_len = 16) {
+   width = DMA_SLAVE_BUSWIDTH_2_BYTES;
+   es = 2;
+   } else {
+   width = DMA_SLAVE_BUSWIDTH_4_BYTES;
+   es = 4;
+   }
+
+   memset(cfg, 0, sizeof(cfg));
+   cfg.src_addr = cs-phys + OMAP2_MCSPI_RX0;
+   cfg.dst_addr = cs-phys + OMAP2_MCSPI_TX0;
+   cfg.src_addr_width = width;
+   cfg.dst_addr_width = width;
+   cfg.src_maxburst = 1;
+   cfg.dst_maxburst = 1;
+
+   if (xfer-tx_buf  mcspi_dma-dma_tx) {
+   struct dma_async_tx_descriptor *tx;
+   struct scatterlist sg;
+
+   dmaengine_slave_config(mcspi_dma-dma_tx, cfg);
+
+   sg_init_table(sg, 1);
+   sg_dma_address(sg) = xfer-tx_dma;
+   sg_dma_len(sg) = xfer-len;
+
+   tx = dmaengine_prep_slave_sg(mcspi_dma-dma_tx, sg, 1,
+   DMA_MEM_TO_DEV, DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
+   if (tx) {
+   tx-callback = omap2_mcspi_tx_callback;
+   tx-callback_param = spi;
+   dmaengine_submit(tx);
+   } else {
+   /* FIXME: fall back to PIO? */
+   }
+   }
+
+   if (xfer-rx_buf  mcspi_dma-dma_rx) {
+   struct dma_async_tx_descriptor *tx;
+   struct scatterlist sg;
+   size_t len = xfer-len - es;
+
+   dmaengine_slave_config(mcspi_dma-dma_rx, cfg);
+
+   if (l  OMAP2_MCSPI_CHCONF_TURBO)
+   len -= es;
+
+   sg_init_table(sg, 1);
+   sg_dma_address(sg) = xfer-rx_dma;
+   sg_dma_len(sg) = len;
+
+   tx = dmaengine_prep_slave_sg(mcspi_dma-dma_rx, sg, 1,
+   DMA_DEV_TO_MEM, DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
+   if (tx) {
+ 

Re: [PATCH 02/11] ARM: OMAP4+: AESS: enable internal auto-gating during initial setup

2012-06-07 Thread Tony Lindgren
* Paul Walmsley p...@pwsan.com [120607 03:49]:
 On Thu, 7 Jun 2012, Tony Lindgren wrote:
 
  OK so that's not too bad then. But there's also the 
  omap2_wd_timer_disable pre_shutdown too. And there's also the sysconfig 
  autoidle bit for each driver that we're tweaking in the bus level code?
 
 I think I lost your point here.  The ioremap() issue is separate from the 
 reset functions, etc., in my view.  Moving the reset functions out to 
 drivers/ seems potentially more reasonable than dropping the ioremap().
 
  If we can remove the ioremapping and accessing driver registers in the 
  bus level code things get much simpler for the bus level code.
 
 That's like saying if PCI Configuration Header handling were to be moved 
 into the driver code, then the PCI bus-level code would be much simpler 
 :-)
 
 The hwmod code ioremaps the device registers to handle the 
 integration-level registers at the beginning of the device's address 
 space.  These registers can be thought of as part of the PRCM, not part of 
 the IP block.  It would have been better if TI had put these integration 
 registers in a separate address space like PCI does.  But we are stuck 
 with the existing hardware design.  The integration registers also differ 
 from chip to chip even with the same underlying IP block, see for example 
 the 32k sync timer.

Yes having these registers in the device address space sucks.
 
 The main reasons why these integration registers are handled now in common 
 code are:
 
 1. to avoid duplicating integration code between lots of different drivers 
that is unrelated to the driver itself, such as bus-level reset
 
 2. to ensure consistency of the OCP registers with the rest of the PM
state
 
 3. to avoid callbacks into drivers that might otherwise be needed for 
bitfields like CLOCKACTIVITY 
 
 4. to make it easier to debug integration problems with drivers

Sure that all makes sense.
 
 If we don't handle those registers in common code, the number of SoC 
 integration workarounds that need to be placed into the drivers will 
 increase.  For example, when OMAP4 added the smart-idle-with-wakeup and 
 smart-standby-with-wakeup OCP idle modes, only a couple of files needed to 
 be changed.  If those integration-level details were still in the drivers, 
 a large number of files would need to be changed.  And $DEITY help us if 
 the code sequence for dealing with those bits were to ever change in the 
 future - we'd need to change a bunch of drivers, rather than just one or 
 two files.  Also some people are going to need to audit the driver code 
 from an integration level pretty carefully for PM to work consistently.
 
 I suppose one option, if we were to have a real omap_device, would be to 
 define callbacks for each driver to implement that would read and write 
 the OCP header registers.  Then the omap_bus code could call those 
 callbacks to handle the OCP register accesses, when called from the 
 driver's PM runtime calls.  Adds another layer of indirection, but would 
 localize IP block register accesses to the IP block's driver.

Yes there may be some way to deal with this cleanly while keeping the
driver registers in the drivers. Maybe inline functions in the driver
headers that hwmod code could include would be enough here.
 
 ...
 
 As far as the reset and preconfiguration aspects of the hwmod code go, 
 they just happen to be possible since we're doing the ioremap anyway.  It 
 can be ensured that no matter what drivers are present, or what the 
 bootloader or previous OS did or didn't do, a minimal kernel should behave 
 predictably.
 
 It seems like it might be reasonable to move these to some built-in driver 
 shim layer as you suggest in your other E-mail.  But that is assuming that 
 it can be made to work without needless layers of indirection.  I don't 
 know of any driver that does this now.  Maybe you know of one?

Yes good point, see the suggestion on the driver header inline functions
in the other email I just sent.

Regards,

Tony
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[CFT 08/11] spi: omap2-mcspi: remove private DMA API implementation

2012-06-07 Thread Russell King
Remove the private DMA API implementation from spi-omap2-mcspi.c,
making it use entirely the DMA engine API.

Acked-by: Grant Likely grant.lik...@secretlab.ca
Signed-off-by: Russell King rmk+ker...@arm.linux.org.uk
---
 drivers/spi/spi-omap2-mcspi.c |  104 ++---
 1 files changed, 5 insertions(+), 99 deletions(-)

diff --git a/drivers/spi/spi-omap2-mcspi.c b/drivers/spi/spi-omap2-mcspi.c
index ca016df..9d3409a 100644
--- a/drivers/spi/spi-omap2-mcspi.c
+++ b/drivers/spi/spi-omap2-mcspi.c
@@ -20,8 +20,6 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  *
  */
-#define USE_DMA_ENGINE_RX
-#define USE_DMA_ENGINE_TX
 
 #include linux/kernel.h
 #include linux/init.h
@@ -43,7 +41,6 @@
 
 #include linux/spi/spi.h
 
-#include plat/dma.h
 #include plat/clock.h
 #include plat/mcspi.h
 
@@ -99,8 +96,6 @@
 struct omap2_mcspi_dma {
struct dma_chan *dma_tx;
struct dma_chan *dma_rx;
-   int dma_tx_channel;
-   int dma_rx_channel;
 
int dma_tx_sync_dev;
int dma_rx_sync_dev;
@@ -336,9 +331,8 @@ omap2_mcspi_txrx_dma(struct spi_device *spi, struct 
spi_transfer *xfer)
struct omap2_mcspi  *mcspi;
struct omap2_mcspi_cs   *cs = spi-controller_state;
struct omap2_mcspi_dma  *mcspi_dma;
-   unsigned intcount, c;
-   unsigned long   base, tx_reg, rx_reg;
-   int word_len, data_type, element_count;
+   unsigned intcount;
+   int word_len, element_count;
int elements = 0;
u32 l;
u8  * rx;
@@ -420,73 +414,26 @@ omap2_mcspi_txrx_dma(struct spi_device *spi, struct 
spi_transfer *xfer)
}
 
count = xfer-len;
-   c = count;
word_len = cs-word_len;
 
-   base = cs-phys;
-   tx_reg = base + OMAP2_MCSPI_TX0;
-   rx_reg = base + OMAP2_MCSPI_RX0;
rx = xfer-rx_buf;
tx = xfer-tx_buf;
 
if (word_len = 8) {
-   data_type = OMAP_DMA_DATA_TYPE_S8;
element_count = count;
} else if (word_len = 16) {
-   data_type = OMAP_DMA_DATA_TYPE_S16;
element_count = count  1;
} else /* word_len = 32 */ {
-   data_type = OMAP_DMA_DATA_TYPE_S32;
element_count = count  2;
}
 
-   if (tx != NULL  mcspi_dma-dma_tx_channel != -1) {
-   omap_set_dma_transfer_params(mcspi_dma-dma_tx_channel,
-   data_type, element_count, 1,
-   OMAP_DMA_SYNC_ELEMENT,
-   mcspi_dma-dma_tx_sync_dev, 0);
-
-   omap_set_dma_dest_params(mcspi_dma-dma_tx_channel, 0,
-   OMAP_DMA_AMODE_CONSTANT,
-   tx_reg, 0, 0);
-
-   omap_set_dma_src_params(mcspi_dma-dma_tx_channel, 0,
-   OMAP_DMA_AMODE_POST_INC,
-   xfer-tx_dma, 0, 0);
-   }
-
-   if (rx != NULL  mcspi_dma-dma_rx_channel != -1) {
-   elements = element_count - 1;
-   if (l  OMAP2_MCSPI_CHCONF_TURBO)
-   elements--;
-
-   omap_set_dma_transfer_params(mcspi_dma-dma_rx_channel,
-   data_type, elements, 1,
-   OMAP_DMA_SYNC_ELEMENT,
-   mcspi_dma-dma_rx_sync_dev, 1);
-
-   omap_set_dma_src_params(mcspi_dma-dma_rx_channel, 0,
-   OMAP_DMA_AMODE_CONSTANT,
-   rx_reg, 0, 0);
-
-   omap_set_dma_dest_params(mcspi_dma-dma_rx_channel, 0,
-   OMAP_DMA_AMODE_POST_INC,
-   xfer-rx_dma, 0, 0);
-   }
-
if (tx != NULL) {
-   if (mcspi_dma-dma_tx)
-   dma_async_issue_pending(mcspi_dma-dma_tx);
-   else
-   omap_start_dma(mcspi_dma-dma_tx_channel);
+   dma_async_issue_pending(mcspi_dma-dma_tx);
omap2_mcspi_set_dma_req(spi, 0, 1);
}
 
if (rx != NULL) {
-   if (mcspi_dma-dma_rx)
-   dma_async_issue_pending(mcspi_dma-dma_rx);
-   else
-   omap_start_dma(mcspi_dma-dma_rx_channel);
+   dma_async_issue_pending(mcspi_dma-dma_rx);
omap2_mcspi_set_dma_req(spi, 1, 1);
}
 
@@ -830,16 +777,6 @@ static int omap2_mcspi_setup_transfer(struct spi_device 
*spi,
return 0;
 }
 
-static void omap2_mcspi_dma_rx_callback(int lch, u16 ch_status, void *data)
-{
-   omap2_mcspi_rx_callback(data);
-}
-
-static void omap2_mcspi_dma_tx_callback(int lch, u16 ch_status, void *data)
-{
-   omap2_mcspi_tx_callback(data);
-}
-
 static int omap2_mcspi_request_dma(struct 

[CFT 09/11] mtd: omap2: add DMA engine support

2012-06-07 Thread Russell King
Add DMA engine support to the OMAP2 NAND driver.  This supplements the
private DMA API implementation contained within this driver, and the
driver can be independently switched at build time between using DMA
engine and the private DMA API.

Tested-by: Grazvydas Ignotas nota...@gmail.com
Signed-off-by: Russell King rmk+ker...@arm.linux.org.uk
---
 drivers/mtd/nand/omap2.c |   92 +-
 1 files changed, 91 insertions(+), 1 deletions(-)

diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
index d7f681d..2912d6c 100644
--- a/drivers/mtd/nand/omap2.c
+++ b/drivers/mtd/nand/omap2.c
@@ -9,6 +9,7 @@
  */
 
 #include linux/platform_device.h
+#include linux/dmaengine.h
 #include linux/dma-mapping.h
 #include linux/delay.h
 #include linux/module.h
@@ -18,6 +19,7 @@
 #include linux/mtd/mtd.h
 #include linux/mtd/nand.h
 #include linux/mtd/partitions.h
+#include linux/omap-dma.h
 #include linux/io.h
 #include linux/slab.h
 
@@ -123,6 +125,7 @@ struct omap_nand_info {
int gpmc_cs;
unsigned long   phys_base;
struct completion   comp;
+   struct dma_chan *dma;
int dma_ch;
int gpmc_irq;
enum {
@@ -345,6 +348,10 @@ static void omap_nand_dma_cb(int lch, u16 ch_status, void 
*data)
 {
complete((struct completion *) data);
 }
+static void omap_nand_dma_callback(void *data)
+{
+   complete((struct completion *) data);
+}
 
 /*
  * omap_nand_dma_transfer: configer and start dma transfer
@@ -382,6 +389,56 @@ static inline int omap_nand_dma_transfer(struct mtd_info 
*mtd, void *addr,
addr = page_address(p1) + ((size_t)addr  ~PAGE_MASK);
}
 
+   if (info-dma) {
+   struct dma_async_tx_descriptor *tx;
+   struct scatterlist sg;
+   unsigned n;
+
+   sg_init_one(sg, addr, len);
+   n = dma_map_sg(info-dma-device-dev, sg, 1, dir);
+   if (n == 0) {
+   dev_err(info-pdev-dev,
+   Couldn't DMA map a %d byte buffer\n, len);
+   goto out_copy;
+   }
+
+   tx = dmaengine_prep_slave_sg(info-dma, sg, n,
+   is_write ? DMA_MEM_TO_DEV : DMA_DEV_TO_MEM,
+   DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
+   if (!tx) {
+   dma_unmap_sg(info-dma-device-dev, sg, 1, dir);
+   goto out_copy;
+   }
+   tx-callback = omap_nand_dma_callback;
+   tx-callback_param = info-comp;
+   dmaengine_submit(tx);
+
+   /*  configure and start prefetch transfer */
+   ret = gpmc_prefetch_enable(info-gpmc_cs,
+   PREFETCH_FIFOTHRESHOLD_MAX, 0x1, len, is_write);
+   if (ret) {
+   /* PFPW engine is busy, use cpu copy method */
+   dma_unmap_sg(info-dma-device-dev, sg, 1, dir);
+   goto out_copy;
+   }
+
+   init_completion(info-comp);
+   dma_async_issue_pending(info-dma);
+
+   /* setup and start DMA using dma_addr */
+   wait_for_completion(info-comp);
+   tim = 0;
+   limit = (loops_per_jiffy * 
msecs_to_jiffies(OMAP_NAND_TIMEOUT_MS));
+   while (gpmc_read_status(GPMC_PREFETCH_COUNT)  (tim++  limit))
+   cpu_relax();
+
+   /* disable and stop the PFPW engine */
+   gpmc_prefetch_reset(info-gpmc_cs);
+
+   dma_unmap_sg(info-dma-device-dev, sg, 1, dir);
+   return 0;
+   }
+
dma_addr = dma_map_single(info-pdev-dev, addr, len, dir);
if (dma_mapping_error(info-pdev-dev, dma_addr)) {
dev_err(info-pdev-dev,
@@ -414,7 +471,6 @@ static inline int omap_nand_dma_transfer(struct mtd_info 
*mtd, void *addr,
goto out_copy_unmap;
 
init_completion(info-comp);
-
omap_start_dma(info-dma_ch);
 
/* setup and start DMA using dma_addr */
@@ -1164,6 +1220,8 @@ static int __devinit omap_nand_probe(struct 
platform_device *pdev)
struct omap_nand_platform_data  *pdata;
int err;
int i, offset;
+   dma_cap_mask_t mask;
+   unsigned sig;
 
pdata = pdev-dev.platform_data;
if (pdata == NULL) {
@@ -1244,6 +1302,33 @@ static int __devinit omap_nand_probe(struct 
platform_device *pdev)
break;
 
case NAND_OMAP_PREFETCH_DMA:
+   dma_cap_zero(mask);
+   dma_cap_set(DMA_SLAVE, mask);
+   sig = OMAP24XX_DMA_GPMC;
+   info-dma = dma_request_channel(mask, omap_dma_filter_fn, sig);
+   if (!info-dma) {
+  

[CFT 10/11] mtd: omap2: remove private DMA API implementation

2012-06-07 Thread Russell King
Remove the private DMA API implementation from nand/omap2.c
making it use entirely the DMA engine API.

Signed-off-by: Russell King rmk+ker...@arm.linux.org.uk
---
 drivers/mtd/nand/omap2.c |  136 +-
 1 files changed, 26 insertions(+), 110 deletions(-)

diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
index 2912d6c..e9309b3 100644
--- a/drivers/mtd/nand/omap2.c
+++ b/drivers/mtd/nand/omap2.c
@@ -126,7 +126,6 @@ struct omap_nand_info {
unsigned long   phys_base;
struct completion   comp;
struct dma_chan *dma;
-   int dma_ch;
int gpmc_irq;
enum {
OMAP_NAND_IO_READ = 0,  /* read */
@@ -339,15 +338,9 @@ static void omap_write_buf_pref(struct mtd_info *mtd,
 }
 
 /*
- * omap_nand_dma_cb: callback on the completion of dma transfer
- * @lch: logical channel
- * @ch_satuts: channel status
+ * omap_nand_dma_callback: callback on the completion of dma transfer
  * @data: pointer to completion data structure
  */
-static void omap_nand_dma_cb(int lch, u16 ch_status, void *data)
-{
-   complete((struct completion *) data);
-}
 static void omap_nand_dma_callback(void *data)
 {
complete((struct completion *) data);
@@ -365,17 +358,13 @@ static inline int omap_nand_dma_transfer(struct mtd_info 
*mtd, void *addr,
 {
struct omap_nand_info *info = container_of(mtd,
struct omap_nand_info, mtd);
+   struct dma_async_tx_descriptor *tx;
enum dma_data_direction dir = is_write ? DMA_TO_DEVICE :
DMA_FROM_DEVICE;
-   dma_addr_t dma_addr;
-   int ret;
+   struct scatterlist sg;
unsigned long tim, limit;
-
-   /* The fifo depth is 64 bytes max.
-* But configure the FIFO-threahold to 32 to get a sync at each frame
-* and frame length is 32 bytes.
-*/
-   int buf_len = len  6;
+   unsigned n;
+   int ret;
 
if (addr = high_memory) {
struct page *p1;
@@ -389,89 +378,33 @@ static inline int omap_nand_dma_transfer(struct mtd_info 
*mtd, void *addr,
addr = page_address(p1) + ((size_t)addr  ~PAGE_MASK);
}
 
-   if (info-dma) {
-   struct dma_async_tx_descriptor *tx;
-   struct scatterlist sg;
-   unsigned n;
-
-   sg_init_one(sg, addr, len);
-   n = dma_map_sg(info-dma-device-dev, sg, 1, dir);
-   if (n == 0) {
-   dev_err(info-pdev-dev,
-   Couldn't DMA map a %d byte buffer\n, len);
-   goto out_copy;
-   }
-
-   tx = dmaengine_prep_slave_sg(info-dma, sg, n,
-   is_write ? DMA_MEM_TO_DEV : DMA_DEV_TO_MEM,
-   DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
-   if (!tx) {
-   dma_unmap_sg(info-dma-device-dev, sg, 1, dir);
-   goto out_copy;
-   }
-   tx-callback = omap_nand_dma_callback;
-   tx-callback_param = info-comp;
-   dmaengine_submit(tx);
-
-   /*  configure and start prefetch transfer */
-   ret = gpmc_prefetch_enable(info-gpmc_cs,
-   PREFETCH_FIFOTHRESHOLD_MAX, 0x1, len, is_write);
-   if (ret) {
-   /* PFPW engine is busy, use cpu copy method */
-   dma_unmap_sg(info-dma-device-dev, sg, 1, dir);
-   goto out_copy;
-   }
-
-   init_completion(info-comp);
-   dma_async_issue_pending(info-dma);
-
-   /* setup and start DMA using dma_addr */
-   wait_for_completion(info-comp);
-   tim = 0;
-   limit = (loops_per_jiffy * 
msecs_to_jiffies(OMAP_NAND_TIMEOUT_MS));
-   while (gpmc_read_status(GPMC_PREFETCH_COUNT)  (tim++  limit))
-   cpu_relax();
-
-   /* disable and stop the PFPW engine */
-   gpmc_prefetch_reset(info-gpmc_cs);
-
-   dma_unmap_sg(info-dma-device-dev, sg, 1, dir);
-   return 0;
-   }
-
-   dma_addr = dma_map_single(info-pdev-dev, addr, len, dir);
-   if (dma_mapping_error(info-pdev-dev, dma_addr)) {
+   sg_init_one(sg, addr, len);
+   n = dma_map_sg(info-dma-device-dev, sg, 1, dir);
+   if (n == 0) {
dev_err(info-pdev-dev,
Couldn't DMA map a %d byte buffer\n, len);
goto out_copy;
}
 
-   if (is_write) {
-   omap_set_dma_dest_params(info-dma_ch, 0, OMAP_DMA_AMODE_CONSTANT,
-   info-phys_base, 0, 0);
-   omap_set_dma_src_params(info-dma_ch, 0, 

[CFT 11/11] Add feature removal of old OMAP private DMA implementation

2012-06-07 Thread Russell King
Acked-by: Linus Walleij linus.wall...@linaro.org
Signed-off-by: Russell King rmk+ker...@arm.linux.org.uk
---
 Documentation/feature-removal-schedule.txt |   11 +++
 1 files changed, 11 insertions(+), 0 deletions(-)

diff --git a/Documentation/feature-removal-schedule.txt 
b/Documentation/feature-removal-schedule.txt
index 56000b3..1f7ba35 100644
--- a/Documentation/feature-removal-schedule.txt
+++ b/Documentation/feature-removal-schedule.txt
@@ -612,3 +612,14 @@ When:  June 2013
 Why:   Unsupported/unmaintained/unused since 2.6
 
 
+
+What:  OMAP private DMA implementation
+When:  2013
+Why:   We have a DMA engine implementation; all users should be updated
+   to use this rather than persisting with the old APIs.  The old APIs
+   block merging the old DMA engine implementation into the DMA
+   engine driver.
+Who:   Russell King li...@arm.linux.org.uk,
+   Santosh Shilimkar santosh.shilim...@ti.com
+
+
-- 
1.7.4.4

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 04/11] ARM: OMAP2+: usb_host_fs: add custom reset for usb_host_fs (fsusb)

2012-06-07 Thread Cousson, Benoit

+ Ohad

On 6/7/2012 12:52 PM, Paul Walmsley wrote:

On Thu, 7 Jun 2012, Cousson, Benoit wrote:


In fact we should delay the reset to the very last moment and
potentially reset the IPs not under driver control later after a couple
of second for example. It will avoid reseting every IP that will be
handled properly by drivers.


We discussed this a couple of years ago on the list and aligned on late
and lazy resets, from my recollection.


Indeed, what I did not mention is that potentially the whole device init 
should be done ondemand as well. Meaning the whole hwmod setup phase 
should be done only when the driver will probe the device.



The main reason why it wasn't
implemented was because there were some drivers that were not yet PM
runtime-converted.  This would have caused crashes, since the core code
would have no idea that the non-PM-runtime drivers had initialized their
devices, and so the core just went ahead and reset those anyway.

It might actually be safe now to switch to the late reset arrangement,
depending on whether the rest of the drivers have been PM
runtime-converted by now.

Of course, it would all be moot if the reset is moved away from the hwmod
code into the drivers.


I do think that moving that to driver code seems much better since all 
these customs reset code (I2C, DSS, USB...) does anyway require access 
to the device itself. The is driver responsibility to do that.


So ideally it should not be in OMAP architecture code.

Regards,
Benoit
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [CFT 01/11] dmaengine: add OMAP DMA engine driver

2012-06-07 Thread S, Venkatraman
On Thu, Jun 7, 2012 at 4:36 PM, Russell King
rmk+ker...@arm.linux.org.uk wrote:
 Tested-by: Tony Lindgren t...@atomide.com
 Signed-off-by: Russell King rmk+ker...@arm.linux.org.uk
 ---
  drivers/dma/Kconfig      |    6 +
  drivers/dma/Makefile     |    1 +
  drivers/dma/omap-dma.c   |  522 
 ++
  include/linux/omap-dma.h |   24 ++
  4 files changed, 553 insertions(+), 0 deletions(-)
  create mode 100644 drivers/dma/omap-dma.c
  create mode 100644 include/linux/omap-dma.h

 diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
 index eb2b60e..8be3bf6 100644
 --- a/drivers/dma/Kconfig
 +++ b/drivers/dma/Kconfig
 @@ -261,6 +261,12 @@ config DMA_SA11X0
          SA-1110 SoCs.  This DMA engine can only be used with on-chip
          devices.

 +config DMA_OMAP
 +       tristate OMAP DMA support
 +       depends on ARCH_OMAP
 +       select DMA_ENGINE
 +       select DMA_VIRTUAL_CHANNELS
 +
  config DMA_ENGINE
        bool

 diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile
 index fc05f7d..ddc291a 100644
 --- a/drivers/dma/Makefile
 +++ b/drivers/dma/Makefile
 @@ -29,3 +29,4 @@ obj-$(CONFIG_PCH_DMA) += pch_dma.o
  obj-$(CONFIG_AMBA_PL08X) += amba-pl08x.o
  obj-$(CONFIG_EP93XX_DMA) += ep93xx_dma.o
  obj-$(CONFIG_DMA_SA11X0) += sa11x0-dma.o
 +obj-$(CONFIG_DMA_OMAP) += omap-dma.o
 diff --git a/drivers/dma/omap-dma.c b/drivers/dma/omap-dma.c
 new file mode 100644
 index 000..500bc71
 --- /dev/null
 +++ b/drivers/dma/omap-dma.c
 @@ -0,0 +1,522 @@
 +/*
 + * OMAP DMAengine support
 + *
 + * This program is free software; you can redistribute it and/or modify
 + * it under the terms of the GNU General Public License version 2 as
 + * published by the Free Software Foundation.
 + */
 +#include linux/dmaengine.h
 +#include linux/dma-mapping.h
 +#include linux/err.h
 +#include linux/init.h
 +#include linux/interrupt.h
 +#include linux/list.h
 +#include linux/module.h
 +#include linux/omap-dma.h
 +#include linux/platform_device.h
 +#include linux/slab.h
 +#include linux/spinlock.h
 +
 +#include virt-dma.h
Russell,
  I applied your entire series on 3.5-rc1 and build fails as it can't
find virt-dma.h
Perhaps a missed git add ?

 +#include plat/dma.h
 +
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [CFT 09/11] mtd: omap2: add DMA engine support

2012-06-07 Thread Artem Bityutskiy
On Thu, 2012-06-07 at 12:09 +0100, Russell King wrote:
 Add DMA engine support to the OMAP2 NAND driver.  This supplements the
 private DMA API implementation contained within this driver, and the
 driver can be independently switched at build time between using DMA
 engine and the private DMA API.
 
 Tested-by: Grazvydas Ignotas nota...@gmail.com
 Signed-off-by: Russell King rmk+ker...@arm.linux.org.uk

I guess it is makes sense to make this stuff to go in via the OMAP tree.

-- 
Best Regards,
Artem Bityutskiy


signature.asc
Description: This is a digitally signed message part


Re: [CFT 01/11] dmaengine: add OMAP DMA engine driver

2012-06-07 Thread S, Venkatraman
On Thu, Jun 7, 2012 at 6:10 PM, S, Venkatraman svenk...@ti.com wrote:
 On Thu, Jun 7, 2012 at 4:36 PM, Russell King
 rmk+ker...@arm.linux.org.uk wrote:
 Tested-by: Tony Lindgren t...@atomide.com
 Signed-off-by: Russell King rmk+ker...@arm.linux.org.uk
 ---
  drivers/dma/Kconfig      |    6 +
  drivers/dma/Makefile     |    1 +
  drivers/dma/omap-dma.c   |  522 
 ++
  include/linux/omap-dma.h |   24 ++
  4 files changed, 553 insertions(+), 0 deletions(-)
  create mode 100644 drivers/dma/omap-dma.c
  create mode 100644 include/linux/omap-dma.h

 diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
 index eb2b60e..8be3bf6 100644
 --- a/drivers/dma/Kconfig
 +++ b/drivers/dma/Kconfig
 @@ -261,6 +261,12 @@ config DMA_SA11X0
          SA-1110 SoCs.  This DMA engine can only be used with on-chip
          devices.

 +config DMA_OMAP
 +       tristate OMAP DMA support
 +       depends on ARCH_OMAP
 +       select DMA_ENGINE
 +       select DMA_VIRTUAL_CHANNELS
 +
  config DMA_ENGINE
        bool

 diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile
 index fc05f7d..ddc291a 100644
 --- a/drivers/dma/Makefile
 +++ b/drivers/dma/Makefile
 @@ -29,3 +29,4 @@ obj-$(CONFIG_PCH_DMA) += pch_dma.o
  obj-$(CONFIG_AMBA_PL08X) += amba-pl08x.o
  obj-$(CONFIG_EP93XX_DMA) += ep93xx_dma.o
  obj-$(CONFIG_DMA_SA11X0) += sa11x0-dma.o
 +obj-$(CONFIG_DMA_OMAP) += omap-dma.o
 diff --git a/drivers/dma/omap-dma.c b/drivers/dma/omap-dma.c
 new file mode 100644
 index 000..500bc71
 --- /dev/null
 +++ b/drivers/dma/omap-dma.c
 @@ -0,0 +1,522 @@
 +/*
 + * OMAP DMAengine support
 + *
 + * This program is free software; you can redistribute it and/or modify
 + * it under the terms of the GNU General Public License version 2 as
 + * published by the Free Software Foundation.
 + */
 +#include linux/dmaengine.h
 +#include linux/dma-mapping.h
 +#include linux/err.h
 +#include linux/init.h
 +#include linux/interrupt.h
 +#include linux/list.h
 +#include linux/module.h
 +#include linux/omap-dma.h
 +#include linux/platform_device.h
 +#include linux/slab.h
 +#include linux/spinlock.h
 +
 +#include virt-dma.h
 Russell,
  I applied your entire series on 3.5-rc1 and build fails as it can't
 find virt-dma.h
 Perhaps a missed git add ?

Ok I reread your messages again and these 11 are based on the generic
dma-engine series.

 +#include plat/dma.h
 +
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [CFT 09/11] mtd: omap2: add DMA engine support

2012-06-07 Thread Russell King - ARM Linux
On Thu, Jun 07, 2012 at 03:49:35PM +0300, Artem Bityutskiy wrote:
 On Thu, 2012-06-07 at 12:09 +0100, Russell King wrote:
  Add DMA engine support to the OMAP2 NAND driver.  This supplements the
  private DMA API implementation contained within this driver, and the
  driver can be independently switched at build time between using DMA
  engine and the private DMA API.
  
  Tested-by: Grazvydas Ignotas nota...@gmail.com
  Signed-off-by: Russell King rmk+ker...@arm.linux.org.uk
 
 I guess it is makes sense to make this stuff to go in via the OMAP tree.

No, it makes sense to get this stuff via a single tree all together,
because, as you can see from the thread structure, it isn't purely
an OMAP thing.

The OMAP stuff depends on a core set, as does a bunch of PL08x and
SA11x0 changes.  We can't stuff all that through the OMAP tree, that
wouldn't make any sense.

What probably should happen is that the tip of the OMAP stuff gets
pulled by Tony into his tree, and we share those commits between my
tree and his - and then it doesn't matter what goes in when and by
whom.
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [CFT 09/11] mtd: omap2: add DMA engine support

2012-06-07 Thread Artem Bityutskiy
On Thu, 2012-06-07 at 14:11 +0100, Russell King - ARM Linux wrote:
 No, it makes sense to get this stuff via a single tree all together,
 because, as you can see from the thread structure, it isn't purely
 an OMAP thing.
 
 The OMAP stuff depends on a core set, as does a bunch of PL08x and
 SA11x0 changes.  We can't stuff all that through the OMAP tree, that
 wouldn't make any sense.
 
 What probably should happen is that the tip of the OMAP stuff gets
 pulled by Tony into his tree, and we share those commits between my
 tree and his - and then it doesn't matter what goes in when and by
 whom.

Oh, sure, sorry, I actually wanted to say that these to patches should
_not_ got via the MTD tree.

-- 
Best Regards,
Artem Bityutskiy


signature.asc
Description: This is a digitally signed message part


RE: [PATCH 00/10] Prepare for GPMC driver conversion (w.r.t MTD)

2012-06-07 Thread Mohammed, Afzal
Hi,

On Mon, Jun 04, 2012 at 12:15:01, Mohammed, Afzal wrote:
 Hi,
 
 This series cleans up gpmc mtd interactions so that GPMC driver
 conversion which is going to happen shortly would happen smoothly
 by not creating much disturbance outside of arch/arm/*omap*/
 
 This series,
 1. provides the ability for OMAP NAND driver to configure GPMC-NAND
registers by NAND driver itself instead of using exported GPMC
symbols
 2. modifies GPMC to provide OMAP ONENAND  NAND drivers with GPMC
allocated address space as resource
 3. creates a fictitious GPMC interrupt chip and provide the clients
with interrupts that could be handled using standard APIs (helps
in removing the requirement for driver of peripheral connected to
GPMC having the knowledge about GPMC interrupt handling). The
only user is OMAP NAND driver, it has also been modified to take
advantage of this
 
 This series has been made over 3.5-rc1

Ping

Regards
Afzal
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


how to specify dma_mask and coherent_dma_mask in hwmod

2012-06-07 Thread N, Mugunthan V
Hi 

While converting platform device registry to Hwmod for CPSW Ethernet driver 
which is present in AM335X (OMAP2+), I am not finding a way to specify
dma_mask and coherent_dma_mask.
Is there a way to specify dma_mask and coherent_dma_mask in hwmod?

---
Regards,
Mugunthan V N. 

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [CFT 02/11] mmc: omap_hsmmc: add DMA engine support

2012-06-07 Thread Tony Lindgren
* Russell King rmk+ker...@arm.linux.org.uk [120607 04:11]:
 Add DMA engine support to the OMAP HSMMC driver.  This supplements the
 private DMA API implementation contained within this driver, and the
 driver can be switched at build time between using DMA engine and the
 private DMA API.
 
 Tested-by: Grazvydas Ignotas nota...@gmail.com
 Signed-off-by: Russell King rmk+ker...@arm.linux.org.uk

Gave this quick boot test on 2430sdp, zoom3, n900 and blaze:

Tested-by: Tony Lindgren t...@atomide.com
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [CFT 03/11] mmc: omap_hsmmc: remove private DMA API implementation

2012-06-07 Thread Tony Lindgren
* Russell King rmk+ker...@arm.linux.org.uk [120607 04:11]:
 Remove the private DMA API implementation from omap_hsmmc, making it
 use entirely the DMA engine API.
 
 Signed-off-by: Russell King rmk+ker...@arm.linux.org.uk

Tested-by: Tony Lindgren t...@atomide.com
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [CFT 05/11] mmc: omap: remove private DMA API implementation

2012-06-07 Thread Tony Lindgren
* Russell King rmk+ker...@arm.linux.org.uk [120607 04:12]:
 Remove the private DMA API implementation from omap, making it use
 entirely the DMA engine API.
 
 Signed-off-by: Russell King rmk+ker...@arm.linux.org.uk

Tested-by: Tony Lindgren t...@atomide.com
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [CFT 06/11] ARM: omap: remove mmc platform data dma_mask and initialization

2012-06-07 Thread Tony Lindgren
* Russell King rmk+ker...@arm.linux.org.uk [120607 04:12]:
 DMAengine uses the DMA engine device structure when mapping/unmapping
 memory for DMA, so the MMC devices do not need their DMA masks
 initialized (this reflects hardware: the MMC device is not the device
 doing DMA.)
 
 Signed-off-by: Russell King rmk+ker...@arm.linux.org.uk

Tested-by: Tony Lindgren t...@atomide.com
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [CFT 11/11] Add feature removal of old OMAP private DMA implementation

2012-06-07 Thread Tony Lindgren
* Russell King rmk+ker...@arm.linux.org.uk [120607 04:14]:
 Acked-by: Linus Walleij linus.wall...@linaro.org
 Signed-off-by: Russell King rmk+ker...@arm.linux.org.uk

Acked-by: Tony Lindgren t...@atomide.com

 ---
  Documentation/feature-removal-schedule.txt |   11 +++
  1 files changed, 11 insertions(+), 0 deletions(-)
 
 diff --git a/Documentation/feature-removal-schedule.txt 
 b/Documentation/feature-removal-schedule.txt
 index 56000b3..1f7ba35 100644
 --- a/Documentation/feature-removal-schedule.txt
 +++ b/Documentation/feature-removal-schedule.txt
 @@ -612,3 +612,14 @@ When:June 2013
  Why: Unsupported/unmaintained/unused since 2.6
  
  
 +
 +What:OMAP private DMA implementation
 +When:2013
 +Why: We have a DMA engine implementation; all users should be updated
 + to use this rather than persisting with the old APIs.  The old APIs
 + block merging the old DMA engine implementation into the DMA
 + engine driver.
 +Who: Russell King li...@arm.linux.org.uk,
 + Santosh Shilimkar santosh.shilim...@ti.com
 +
 +
 -- 
 1.7.4.4
 
 --
 To unsubscribe from this list: send the line unsubscribe linux-omap in
 the body of a message to majord...@vger.kernel.org
 More majordomo info at  http://vger.kernel.org/majordomo-info.html
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [CFT 09/11] mtd: omap2: add DMA engine support

2012-06-07 Thread Tony Lindgren
* Artem Bityutskiy dedeki...@gmail.com [120607 06:28]:
 On Thu, 2012-06-07 at 14:11 +0100, Russell King - ARM Linux wrote:
  No, it makes sense to get this stuff via a single tree all together,
  because, as you can see from the thread structure, it isn't purely
  an OMAP thing.
  
  The OMAP stuff depends on a core set, as does a bunch of PL08x and
  SA11x0 changes.  We can't stuff all that through the OMAP tree, that
  wouldn't make any sense.
  
  What probably should happen is that the tip of the OMAP stuff gets
  pulled by Tony into his tree, and we share those commits between my
  tree and his - and then it doesn't matter what goes in when and by
  whom.
 
 Oh, sure, sorry, I actually wanted to say that these to patches should
 _not_ got via the MTD tree.

What Russell is suggesting works good for me.

Regards,

Tony
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [CFT 03/11] mmc: omap_hsmmc: remove private DMA API implementation

2012-06-07 Thread S, Venkatraman
On Thu, Jun 7, 2012 at 4:37 PM, Russell King
rmk+ker...@arm.linux.org.uk wrote:
 Remove the private DMA API implementation from omap_hsmmc, making it
 use entirely the DMA engine API.

 Signed-off-by: Russell King rmk+ker...@arm.linux.org.uk

Tested this on 4430SDP with rootfs usage, untarring the kernel source
and compiling it natively.

Tested-by: Venkatraman S svenk...@ti.com

 ---
  drivers/mmc/host/omap_hsmmc.c |  265 
 ++---
  1 files changed, 64 insertions(+), 201 deletions(-)

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


RE: [PATCH 05/11] ARM: OMAP2+: hwmod code/data: fix 32K sync timer

2012-06-07 Thread Hiremath, Vaibhav
On Thu, Jun 07, 2012 at 12:38:50, Paul Walmsley wrote:
 Hi
 
 On Thu, 7 Jun 2012, Hiremath, Vaibhav wrote:
 
  Isn't this impact AM33xx devices, where we do not support smart idle mode???
  Anyway, I will also test it on both OMAP3EVM and AM33xx platform now...
 
 Thanks, please let me know how your tests go.  If it doesn't work, we'll 
 go back to the flag-based approach in the patch I posted already.  
 

Paul,

I couldn't finish my testing today, got into continuous meetings.
Tomorrow, I will test it and update you on this.

Thanks,
Vaibhav
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


  1   2   >