summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>2013-12-21 15:47:29 -0800
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2013-12-21 15:47:29 -0800
commit2a3e95c7300ae27e3c7f3f98c38ae617b74b03fe (patch)
treead0e1258871fdbc850e64a88a74af742344037cd
parent4e5a531b408ef65da0489afbcb2842cc5e4bab4f (diff)
downloadlinux-3.10-2a3e95c7300ae27e3c7f3f98c38ae617b74b03fe.tar.gz
linux-3.10-2a3e95c7300ae27e3c7f3f98c38ae617b74b03fe.tar.bz2
linux-3.10-2a3e95c7300ae27e3c7f3f98c38ae617b74b03fe.zip
fuzz cleanup in the baytrail patches and some others
-rw-r--r--patches.baytrail/0008-usb-Don-t-enable-USB-2.0-Link-PM-by-default.patch45
-rw-r--r--patches.baytrail/0520-drm-gem-convert-to-new-unified-vma-manager.patch103
-rw-r--r--patches.baytrail/0596-drm-gem-create-drm_gem_dumb_destroy.patch241
-rw-r--r--patches.baytrail/1123-drivers-i2c-busses-don-t-check-resource-with-devm_io.patch41
-rw-r--r--patches.baytrail/1137-dma-move-dw_dmac-driver-to-an-own-directory.patch4615
-rw-r--r--patches.baytrail/1170-i2c-use-dev_get_platdata.patch157
-rw-r--r--patches.baytrail/1191-ARM-EXYNOS-Select-PINCTRL_EXYNOS-for-exynos4-5-at-ch.patch13
-rw-r--r--patches.zynq/0010-ARM-zynq-Add-cpuidle-support.patch24
8 files changed, 4785 insertions, 454 deletions
diff --git a/patches.baytrail/0008-usb-Don-t-enable-USB-2.0-Link-PM-by-default.patch b/patches.baytrail/0008-usb-Don-t-enable-USB-2.0-Link-PM-by-default.patch
index e4084d6d7d2..333541c21de 100644
--- a/patches.baytrail/0008-usb-Don-t-enable-USB-2.0-Link-PM-by-default.patch
+++ b/patches.baytrail/0008-usb-Don-t-enable-USB-2.0-Link-PM-by-default.patch
@@ -75,19 +75,17 @@ Cc: stable@vger.kernel.org
(cherry picked from commit de68bab4fa96014cfaa6fcbcdb9750e32969fb86)
Signed-off-by: Darren Hart <dvhart@linux.intel.com>
---
- drivers/usb/core/driver.c | 3 +
- drivers/usb/core/hub.c | 1 +
- drivers/usb/core/sysfs.c | 6 +-
- drivers/usb/host/xhci-mem.c | 10 ---
- drivers/usb/host/xhci.c | 161 +++++---------------------------------------
- include/linux/usb.h | 4 +-
+ drivers/usb/core/driver.c | 3
+ drivers/usb/core/hub.c | 1
+ drivers/usb/core/sysfs.c | 6 +
+ drivers/usb/host/xhci-mem.c | 10 --
+ drivers/usb/host/xhci.c | 161 ++++----------------------------------------
+ include/linux/usb.h | 4 -
6 files changed, 29 insertions(+), 156 deletions(-)
-diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c
-index 6eab440e1542..bed14edd8ef5 100644
--- a/drivers/usb/core/driver.c
+++ b/drivers/usb/core/driver.c
-@@ -1773,6 +1773,9 @@ int usb_set_usb2_hardware_lpm(struct usb_device *udev, int enable)
+@@ -1773,6 +1773,9 @@ int usb_set_usb2_hardware_lpm(struct usb
struct usb_hcd *hcd = bus_to_hcd(udev->bus);
int ret = -EPERM;
@@ -97,11 +95,9 @@ index 6eab440e1542..bed14edd8ef5 100644
if (hcd->driver->set_usb2_hw_lpm) {
ret = hcd->driver->set_usb2_hw_lpm(hcd, udev, enable);
if (!ret)
-diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
-index 1424a8988849..a5a1fcc09e9d 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
-@@ -5186,6 +5186,7 @@ static int usb_reset_and_verify_device(struct usb_device *udev)
+@@ -5187,6 +5187,7 @@ static int usb_reset_and_verify_device(s
done:
/* Now that the alt settings are re-installed, enable LTM and LPM. */
@@ -109,11 +105,9 @@ index 1424a8988849..a5a1fcc09e9d 100644
usb_unlocked_enable_lpm(udev);
usb_enable_ltm(udev);
return 0;
-diff --git a/drivers/usb/core/sysfs.c b/drivers/usb/core/sysfs.c
-index d9284b998bd7..9e6f9a945026 100644
--- a/drivers/usb/core/sysfs.c
+++ b/drivers/usb/core/sysfs.c
-@@ -463,7 +463,7 @@ show_usb2_hardware_lpm(struct device *dev, struct device_attribute *attr,
+@@ -463,7 +463,7 @@ show_usb2_hardware_lpm(struct device *de
struct usb_device *udev = to_usb_device(dev);
const char *p;
@@ -122,7 +116,7 @@ index d9284b998bd7..9e6f9a945026 100644
p = "enabled";
else
p = "disabled";
-@@ -483,8 +483,10 @@ set_usb2_hardware_lpm(struct device *dev, struct device_attribute *attr,
+@@ -483,8 +483,10 @@ set_usb2_hardware_lpm(struct device *dev
ret = strtobool(buf, &value);
@@ -134,11 +128,9 @@ index d9284b998bd7..9e6f9a945026 100644
usb_unlock_device(udev);
-diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
-index 0fc539dc1cb8..27062e6010c2 100644
--- a/drivers/usb/host/xhci-mem.c
+++ b/drivers/usb/host/xhci-mem.c
-@@ -1763,9 +1763,7 @@ void xhci_free_command(struct xhci_hcd *xhci,
+@@ -1763,9 +1763,7 @@ void xhci_free_command(struct xhci_hcd *
void xhci_mem_cleanup(struct xhci_hcd *xhci)
{
struct pci_dev *pdev = to_pci_dev(xhci_to_hcd(xhci)->self.controller);
@@ -148,7 +140,7 @@ index 0fc539dc1cb8..27062e6010c2 100644
int size;
int i, j, num_ports;
-@@ -1824,13 +1822,6 @@ void xhci_mem_cleanup(struct xhci_hcd *xhci)
+@@ -1824,13 +1822,6 @@ void xhci_mem_cleanup(struct xhci_hcd *x
scratchpad_free(xhci);
@@ -162,7 +154,7 @@ index 0fc539dc1cb8..27062e6010c2 100644
if (!xhci->rh_bw)
goto no_bw;
-@@ -2289,7 +2280,6 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags)
+@@ -2289,7 +2280,6 @@ int xhci_mem_init(struct xhci_hcd *xhci,
u32 page_size, temp;
int i;
@@ -170,11 +162,9 @@ index 0fc539dc1cb8..27062e6010c2 100644
INIT_LIST_HEAD(&xhci->cancel_cmd_list);
page_size = xhci_readl(xhci, &xhci->op_regs->page_size);
-diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
-index a228b796c300..10b15d3aa117 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
-@@ -3940,133 +3940,6 @@ static int xhci_calculate_usb2_hw_lpm_params(struct usb_device *udev)
+@@ -3940,133 +3940,6 @@ static int xhci_calculate_usb2_hw_lpm_pa
return PORT_BESLD(besld) | PORT_L1_TIMEOUT(l1) | PORT_HIRDM(hirdm);
}
@@ -308,7 +298,7 @@ index a228b796c300..10b15d3aa117 100644
int xhci_set_usb2_hardware_lpm(struct usb_hcd *hcd,
struct usb_device *udev, int enable)
{
-@@ -4194,24 +4067,26 @@ static int xhci_check_usb2_port_capability(struct xhci_hcd *xhci, int port,
+@@ -4194,24 +4067,26 @@ static int xhci_check_usb2_port_capabili
int xhci_update_device(struct usb_hcd *hcd, struct usb_device *udev)
{
struct xhci_hcd *xhci = hcd_to_xhci(hcd);
@@ -351,8 +341,6 @@ index a228b796c300..10b15d3aa117 100644
}
return 0;
-diff --git a/include/linux/usb.h b/include/linux/usb.h
-index 1f7d63f3ab8b..0ffae80ab1e5 100644
--- a/include/linux/usb.h
+++ b/include/linux/usb.h
@@ -485,7 +485,8 @@ struct usb3_lpm_parameters {
@@ -373,6 +361,3 @@ index 1f7d63f3ab8b..0ffae80ab1e5 100644
unsigned usb3_lpm_enabled:1;
int string_langid;
---
-1.8.5.rc3
-
diff --git a/patches.baytrail/0520-drm-gem-convert-to-new-unified-vma-manager.patch b/patches.baytrail/0520-drm-gem-convert-to-new-unified-vma-manager.patch
index 1ef454237dc..640b3607f1f 100644
--- a/patches.baytrail/0520-drm-gem-convert-to-new-unified-vma-manager.patch
+++ b/patches.baytrail/0520-drm-gem-convert-to-new-unified-vma-manager.patch
@@ -35,21 +35,19 @@ Signed-off-by: Dave Airlie <airlied@gmail.com>
(cherry picked from commit 0de23977cfeb5b357ec884ba15417ae118ff9e9b)
Signed-off-by: Darren Hart <dvhart@linux.intel.com>
---
- drivers/gpu/drm/drm_gem.c | 89 +++++-------------------------
- drivers/gpu/drm/drm_gem_cma_helper.c | 16 ++----
- drivers/gpu/drm/exynos/exynos_drm_gem.c | 14 ++---
- drivers/gpu/drm/gma500/gem.c | 15 ++---
- drivers/gpu/drm/i915/i915_gem.c | 10 ++--
- drivers/gpu/drm/omapdrm/omap_gem.c | 28 +++++-----
- drivers/gpu/drm/omapdrm/omap_gem_helpers.c | 49 +---------------
- drivers/gpu/drm/udl/udl_gem.c | 13 ++---
- drivers/gpu/host1x/drm/gem.c | 5 +-
- include/drm/drmP.h | 7 +--
- include/uapi/drm/drm.h | 2 +-
+ drivers/gpu/drm/drm_gem.c | 89 ++++-------------------------
+ drivers/gpu/drm/drm_gem_cma_helper.c | 16 +----
+ drivers/gpu/drm/exynos/exynos_drm_gem.c | 14 +---
+ drivers/gpu/drm/gma500/gem.c | 15 +---
+ drivers/gpu/drm/i915/i915_gem.c | 10 +--
+ drivers/gpu/drm/omapdrm/omap_gem.c | 28 ++++-----
+ drivers/gpu/drm/omapdrm/omap_gem_helpers.c | 49 ---------------
+ drivers/gpu/drm/udl/udl_gem.c | 13 +---
+ drivers/gpu/host1x/drm/gem.c | 5 -
+ include/drm/drmP.h | 7 --
+ include/uapi/drm/drm.h | 2
11 files changed, 62 insertions(+), 186 deletions(-)
-diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c
-index df6c89ec27ec..d1ba36512fe4 100644
--- a/drivers/gpu/drm/drm_gem.c
+++ b/drivers/gpu/drm/drm_gem.c
@@ -37,6 +37,7 @@
@@ -88,7 +86,7 @@ index df6c89ec27ec..d1ba36512fe4 100644
kfree(mm);
dev->mm_private = NULL;
}
-@@ -302,12 +297,8 @@ drm_gem_free_mmap_offset(struct drm_gem_object *obj)
+@@ -302,12 +297,8 @@ drm_gem_free_mmap_offset(struct drm_gem_
{
struct drm_device *dev = obj->dev;
struct drm_gem_mm *mm = dev->mm_private;
@@ -102,7 +100,7 @@ index df6c89ec27ec..d1ba36512fe4 100644
}
EXPORT_SYMBOL(drm_gem_free_mmap_offset);
-@@ -327,54 +318,9 @@ drm_gem_create_mmap_offset(struct drm_gem_object *obj)
+@@ -327,54 +318,9 @@ drm_gem_create_mmap_offset(struct drm_ge
{
struct drm_device *dev = obj->dev;
struct drm_gem_mm *mm = dev->mm_private;
@@ -130,7 +128,7 @@ index df6c89ec27ec..d1ba36512fe4 100644
- ret = -ENOSPC;
- goto out_free_list;
- }
-
+-
- list->file_offset_node = drm_mm_get_block(list->file_offset_node,
- obj->size / PAGE_SIZE, 0);
- if (!list->file_offset_node) {
@@ -146,7 +144,7 @@ index df6c89ec27ec..d1ba36512fe4 100644
- }
-
- return 0;
--
+
-out_free_mm:
- drm_mm_put_block(list->file_offset_node);
-out_free_list:
@@ -159,7 +157,7 @@ index df6c89ec27ec..d1ba36512fe4 100644
}
EXPORT_SYMBOL(drm_gem_create_mmap_offset);
-@@ -699,8 +645,8 @@ int drm_gem_mmap(struct file *filp, struct vm_area_struct *vma)
+@@ -699,8 +645,8 @@ int drm_gem_mmap(struct file *filp, stru
struct drm_file *priv = filp->private_data;
struct drm_device *dev = priv->minor->dev;
struct drm_gem_mm *mm = dev->mm_private;
@@ -170,7 +168,7 @@ index df6c89ec27ec..d1ba36512fe4 100644
int ret = 0;
if (drm_device_is_unplugged(dev))
-@@ -708,21 +654,16 @@ int drm_gem_mmap(struct file *filp, struct vm_area_struct *vma)
+@@ -708,21 +654,16 @@ int drm_gem_mmap(struct file *filp, stru
mutex_lock(&dev->struct_mutex);
@@ -197,11 +195,9 @@ index df6c89ec27ec..d1ba36512fe4 100644
mutex_unlock(&dev->struct_mutex);
return ret;
-diff --git a/drivers/gpu/drm/drm_gem_cma_helper.c b/drivers/gpu/drm/drm_gem_cma_helper.c
-index 0a7e011509bd..11b616ef9dc2 100644
--- a/drivers/gpu/drm/drm_gem_cma_helper.c
+++ b/drivers/gpu/drm/drm_gem_cma_helper.c
-@@ -26,11 +26,7 @@
+@@ -27,11 +27,7 @@
#include <drm/drmP.h>
#include <drm/drm.h>
#include <drm/drm_gem_cma_helper.h>
@@ -212,9 +208,9 @@ index 0a7e011509bd..11b616ef9dc2 100644
-}
+#include <drm/drm_vma_manager.h>
- static void drm_gem_cma_buf_destroy(struct drm_device *drm,
- struct drm_gem_cma_object *cma_obj)
-@@ -140,8 +136,7 @@ void drm_gem_cma_free_object(struct drm_gem_object *gem_obj)
+ /*
+ * __drm_gem_cma_create - Create a GEM CMA object without allocating memory
+@@ -172,8 +168,7 @@ void drm_gem_cma_free_object(struct drm_
{
struct drm_gem_cma_object *cma_obj;
@@ -222,9 +218,9 @@ index 0a7e011509bd..11b616ef9dc2 100644
- drm_gem_free_mmap_offset(gem_obj);
+ drm_gem_free_mmap_offset(gem_obj);
- drm_gem_object_release(gem_obj);
+ cma_obj = to_drm_gem_cma_obj(gem_obj);
-@@ -199,7 +194,7 @@ int drm_gem_cma_dumb_map_offset(struct drm_file *file_priv,
+@@ -240,7 +235,7 @@ int drm_gem_cma_dumb_map_offset(struct d
return -EINVAL;
}
@@ -233,7 +229,7 @@ index 0a7e011509bd..11b616ef9dc2 100644
drm_gem_object_unreference(gem_obj);
-@@ -255,12 +250,11 @@ void drm_gem_cma_describe(struct drm_gem_cma_object *cma_obj, struct seq_file *m
+@@ -304,12 +299,11 @@ void drm_gem_cma_describe(struct drm_gem
{
struct drm_gem_object *obj = &cma_obj->base;
struct drm_device *dev = obj->dev;
@@ -248,8 +244,6 @@ index 0a7e011509bd..11b616ef9dc2 100644
seq_printf(m, "%2d (%2d) %08llx %08Zx %p %d",
obj->name, obj->refcount.refcount.counter,
-diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.c b/drivers/gpu/drm/exynos/exynos_drm_gem.c
-index cf4543ffa079..408b71f4c95e 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_gem.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_gem.c
@@ -10,6 +10,7 @@
@@ -270,7 +264,7 @@ index cf4543ffa079..408b71f4c95e 100644
/* release file pointer to gem object. */
drm_gem_object_release(obj);
-@@ -721,13 +721,11 @@ int exynos_drm_gem_dumb_map_offset(struct drm_file *file_priv,
+@@ -721,13 +721,11 @@ int exynos_drm_gem_dumb_map_offset(struc
goto unlock;
}
@@ -288,8 +282,6 @@ index cf4543ffa079..408b71f4c95e 100644
DRM_DEBUG_KMS("offset = 0x%lx\n", (unsigned long)*offset);
out:
-diff --git a/drivers/gpu/drm/gma500/gem.c b/drivers/gpu/drm/gma500/gem.c
-index fe1d3320ce6a..2f77bea30b11 100644
--- a/drivers/gpu/drm/gma500/gem.c
+++ b/drivers/gpu/drm/gma500/gem.c
@@ -26,6 +26,7 @@
@@ -300,7 +292,7 @@ index fe1d3320ce6a..2f77bea30b11 100644
#include "psb_drv.h"
int psb_gem_init_object(struct drm_gem_object *obj)
-@@ -38,8 +39,7 @@ void psb_gem_free_object(struct drm_gem_object *obj)
+@@ -38,8 +39,7 @@ void psb_gem_free_object(struct drm_gem_
struct gtt_range *gtt = container_of(obj, struct gtt_range, gem);
/* Remove the list map if one is present */
@@ -310,7 +302,7 @@ index fe1d3320ce6a..2f77bea30b11 100644
drm_gem_object_release(obj);
/* This must occur last as it frees up the memory of the GEM object */
-@@ -81,13 +81,10 @@ int psb_gem_dumb_map_gtt(struct drm_file *file, struct drm_device *dev,
+@@ -81,13 +81,10 @@ int psb_gem_dumb_map_gtt(struct drm_file
/* What validation is needed here ? */
/* Make it mmapable */
@@ -328,8 +320,6 @@ index fe1d3320ce6a..2f77bea30b11 100644
out:
drm_gem_object_unreference(obj);
unlock:
-diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
-index 050eb9b92595..607dc675840e 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -26,6 +26,7 @@
@@ -340,7 +330,7 @@ index 050eb9b92595..607dc675840e 100644
#include <drm/i915_drm.h>
#include "i915_drv.h"
#include "i915_trace.h"
-@@ -1424,7 +1425,7 @@ i915_gem_release_mmap(struct drm_i915_gem_object *obj)
+@@ -1424,7 +1425,7 @@ i915_gem_release_mmap(struct drm_i915_ge
if (obj->base.dev->dev_mapping)
unmap_mapping_range(obj->base.dev->dev_mapping,
@@ -349,7 +339,7 @@ index 050eb9b92595..607dc675840e 100644
obj->base.size, 1);
obj->fault_mappable = false;
-@@ -1482,7 +1483,7 @@ static int i915_gem_object_create_mmap_offset(struct drm_i915_gem_object *obj)
+@@ -1482,7 +1483,7 @@ static int i915_gem_object_create_mmap_o
struct drm_i915_private *dev_priv = obj->base.dev->dev_private;
int ret;
@@ -377,8 +367,6 @@ index 050eb9b92595..607dc675840e 100644
out:
drm_gem_object_unreference(&obj->base);
-diff --git a/drivers/gpu/drm/omapdrm/omap_gem.c b/drivers/gpu/drm/omapdrm/omap_gem.c
-index cbcd71e6ed83..f90531fc00c9 100644
--- a/drivers/gpu/drm/omapdrm/omap_gem.c
+++ b/drivers/gpu/drm/omapdrm/omap_gem.c
@@ -20,6 +20,7 @@
@@ -389,7 +377,7 @@ index cbcd71e6ed83..f90531fc00c9 100644
#include "omap_drv.h"
#include "omap_dmm_tiler.h"
-@@ -308,21 +309,20 @@ uint32_t omap_gem_flags(struct drm_gem_object *obj)
+@@ -308,21 +309,20 @@ uint32_t omap_gem_flags(struct drm_gem_o
static uint64_t mmap_offset(struct drm_gem_object *obj)
{
struct drm_device *dev = obj->dev;
@@ -420,7 +408,7 @@ index cbcd71e6ed83..f90531fc00c9 100644
}
uint64_t omap_gem_mmap_offset(struct drm_gem_object *obj)
-@@ -997,12 +997,11 @@ void omap_gem_describe(struct drm_gem_object *obj, struct seq_file *m)
+@@ -997,12 +997,11 @@ void omap_gem_describe(struct drm_gem_ob
{
struct drm_device *dev = obj->dev;
struct omap_gem_object *omap_obj = to_omap_bo(obj);
@@ -435,7 +423,7 @@ index cbcd71e6ed83..f90531fc00c9 100644
seq_printf(m, "%08x: %2d (%2d) %08llx %08Zx (%2d) %p %4d",
omap_obj->flags, obj->name, obj->refcount.refcount.counter,
-@@ -1309,8 +1308,7 @@ void omap_gem_free_object(struct drm_gem_object *obj)
+@@ -1309,8 +1308,7 @@ void omap_gem_free_object(struct drm_gem
list_del(&omap_obj->mm_list);
@@ -445,18 +433,16 @@ index cbcd71e6ed83..f90531fc00c9 100644
/* this means the object is still pinned.. which really should
* not happen. I think..
-diff --git a/drivers/gpu/drm/omapdrm/omap_gem_helpers.c b/drivers/gpu/drm/omapdrm/omap_gem_helpers.c
-index f9eb679eb79b..dbb157542f8f 100644
--- a/drivers/gpu/drm/omapdrm/omap_gem_helpers.c
+++ b/drivers/gpu/drm/omapdrm/omap_gem_helpers.c
-@@ -118,52 +118,7 @@ _drm_gem_create_mmap_offset_size(struct drm_gem_object *obj, size_t size)
+@@ -118,52 +118,7 @@ _drm_gem_create_mmap_offset_size(struct
{
struct drm_device *dev = obj->dev;
struct drm_gem_mm *mm = dev->mm_private;
- struct drm_map_list *list;
- struct drm_local_map *map;
- int ret = 0;
--
+
- /* Set the object up for mmap'ing */
- list = &obj->map_list;
- list->map = kzalloc(sizeof(struct drm_map_list), GFP_KERNEL);
@@ -499,16 +485,14 @@ index f9eb679eb79b..dbb157542f8f 100644
-out_free_list:
- kfree(list->map);
- list->map = NULL;
-
+-
- return ret;
+ return drm_vma_offset_add(&mm->vma_manager, &obj->vma_node,
+ size / PAGE_SIZE);
}
-diff --git a/drivers/gpu/drm/udl/udl_gem.c b/drivers/gpu/drm/udl/udl_gem.c
-index ef034fa3e6f5..2a4cb2f83b36 100644
--- a/drivers/gpu/drm/udl/udl_gem.c
+++ b/drivers/gpu/drm/udl/udl_gem.c
-@@ -223,8 +223,7 @@ void udl_gem_free_object(struct drm_gem_object *gem_obj)
+@@ -223,8 +223,7 @@ void udl_gem_free_object(struct drm_gem_
if (obj->pages)
udl_gem_put_pages(obj);
@@ -518,7 +502,7 @@ index ef034fa3e6f5..2a4cb2f83b36 100644
}
/* the dumb interface doesn't work with the GEM straight MMAP
-@@ -247,13 +246,11 @@ int udl_gem_mmap(struct drm_file *file, struct drm_device *dev,
+@@ -247,13 +246,11 @@ int udl_gem_mmap(struct drm_file *file,
ret = udl_gem_get_pages(gobj, GFP_KERNEL);
if (ret)
goto out;
@@ -536,11 +520,9 @@ index ef034fa3e6f5..2a4cb2f83b36 100644
out:
drm_gem_object_unreference(&gobj->base);
-diff --git a/drivers/gpu/host1x/drm/gem.c b/drivers/gpu/host1x/drm/gem.c
-index c5e9a9b494c2..bc323b3dbe4d 100644
--- a/drivers/gpu/host1x/drm/gem.c
+++ b/drivers/gpu/host1x/drm/gem.c
-@@ -108,7 +108,7 @@ static void tegra_bo_destroy(struct drm_device *drm, struct tegra_bo *bo)
+@@ -108,7 +108,7 @@ static void tegra_bo_destroy(struct drm_
unsigned int tegra_bo_get_mmap_offset(struct tegra_bo *bo)
{
@@ -549,7 +531,7 @@ index c5e9a9b494c2..bc323b3dbe4d 100644
}
struct tegra_bo *tegra_bo_create(struct drm_device *drm, unsigned int size)
-@@ -182,8 +182,7 @@ void tegra_bo_free_object(struct drm_gem_object *gem)
+@@ -182,8 +182,7 @@ void tegra_bo_free_object(struct drm_gem
{
struct tegra_bo *bo = to_tegra_bo(gem);
@@ -559,8 +541,6 @@ index c5e9a9b494c2..bc323b3dbe4d 100644
drm_gem_object_release(gem);
tegra_bo_destroy(gem->dev, bo);
-diff --git a/include/drm/drmP.h b/include/drm/drmP.h
-index 5ff88ad7b23c..bf677c0b4cae 100644
--- a/include/drm/drmP.h
+++ b/include/drm/drmP.h
@@ -74,6 +74,7 @@
@@ -598,8 +578,6 @@ index 5ff88ad7b23c..bf677c0b4cae 100644
/**
* Size of the object, in bytes. Immutable over the object's
-diff --git a/include/uapi/drm/drm.h b/include/uapi/drm/drm.h
-index 5a57be68bab7..1d1c6f03021e 100644
--- a/include/uapi/drm/drm.h
+++ b/include/uapi/drm/drm.h
@@ -181,7 +181,7 @@ enum drm_map_type {
@@ -611,6 +589,3 @@ index 5a57be68bab7..1d1c6f03021e 100644
};
/**
---
-1.8.5.rc3
-
diff --git a/patches.baytrail/0596-drm-gem-create-drm_gem_dumb_destroy.patch b/patches.baytrail/0596-drm-gem-create-drm_gem_dumb_destroy.patch
index c846b3f54c6..db964ac1232 100644
--- a/patches.baytrail/0596-drm-gem-create-drm_gem_dumb_destroy.patch
+++ b/patches.baytrail/0596-drm-gem-create-drm_gem_dumb_destroy.patch
@@ -31,53 +31,51 @@ Conflicts:
(we don't have this driver in our tree)
Signed-off-by: Darren Hart <dvhart@linux.intel.com>
---
- drivers/gpu/drm/ast/ast_drv.c | 2 +-
- drivers/gpu/drm/ast/ast_drv.h | 3 ---
- drivers/gpu/drm/ast/ast_main.c | 7 -------
- drivers/gpu/drm/cirrus/cirrus_drv.c | 2 +-
- drivers/gpu/drm/cirrus/cirrus_drv.h | 3 ---
- drivers/gpu/drm/cirrus/cirrus_main.c | 7 -------
- drivers/gpu/drm/drm_gem.c | 14 ++++++++++++++
- drivers/gpu/drm/drm_gem_cma_helper.c | 10 ----------
- drivers/gpu/drm/exynos/exynos_drm_drv.c | 2 +-
- drivers/gpu/drm/exynos/exynos_drm_gem.c | 22 ----------------------
- drivers/gpu/drm/exynos/exynos_drm_gem.h | 9 ---------
- drivers/gpu/drm/gma500/gem.c | 17 -----------------
- drivers/gpu/drm/gma500/psb_drv.c | 2 +-
- drivers/gpu/drm/gma500/psb_drv.h | 2 --
- drivers/gpu/drm/i915/i915_drv.c | 2 +-
- drivers/gpu/drm/i915/i915_drv.h | 2 --
- drivers/gpu/drm/i915/i915_gem.c | 7 -------
- drivers/gpu/drm/mgag200/mgag200_drv.c | 2 +-
- drivers/gpu/drm/mgag200/mgag200_drv.h | 3 ---
- drivers/gpu/drm/mgag200/mgag200_main.c | 7 -------
- drivers/gpu/drm/nouveau/nouveau_display.c | 7 -------
- drivers/gpu/drm/nouveau/nouveau_display.h | 2 --
- drivers/gpu/drm/nouveau/nouveau_drm.c | 2 +-
- drivers/gpu/drm/omapdrm/omap_drv.c | 2 +-
- drivers/gpu/drm/omapdrm/omap_drv.h | 2 --
- drivers/gpu/drm/omapdrm/omap_gem.c | 15 ---------------
- drivers/gpu/drm/qxl/qxl_drv.c | 2 +-
- drivers/gpu/drm/qxl/qxl_drv.h | 3 ---
- drivers/gpu/drm/qxl/qxl_dumb.c | 7 -------
- drivers/gpu/drm/radeon/radeon.h | 3 ---
- drivers/gpu/drm/radeon/radeon_drv.c | 5 +----
- drivers/gpu/drm/radeon/radeon_gem.c | 7 -------
- drivers/gpu/drm/shmobile/shmob_drm_drv.c | 2 +-
- drivers/gpu/drm/tilcdc/tilcdc_drv.c | 2 +-
- drivers/gpu/drm/udl/udl_drv.c | 2 +-
- drivers/gpu/drm/udl/udl_drv.h | 2 --
- drivers/gpu/drm/udl/udl_gem.c | 6 ------
- drivers/gpu/host1x/drm/drm.c | 2 +-
- drivers/gpu/host1x/drm/gem.c | 6 ------
- drivers/gpu/host1x/drm/gem.h | 2 --
- drivers/staging/imx-drm/imx-drm-core.c | 2 +-
- include/drm/drmP.h | 3 +++
- include/drm/drm_gem_cma_helper.h | 8 --------
+ drivers/gpu/drm/ast/ast_drv.c | 2 +-
+ drivers/gpu/drm/ast/ast_drv.h | 3 ---
+ drivers/gpu/drm/ast/ast_main.c | 7 -------
+ drivers/gpu/drm/cirrus/cirrus_drv.c | 2 +-
+ drivers/gpu/drm/cirrus/cirrus_drv.h | 3 ---
+ drivers/gpu/drm/cirrus/cirrus_main.c | 7 -------
+ drivers/gpu/drm/drm_gem.c | 14 ++++++++++++++
+ drivers/gpu/drm/drm_gem_cma_helper.c | 10 ----------
+ drivers/gpu/drm/exynos/exynos_drm_drv.c | 2 +-
+ drivers/gpu/drm/exynos/exynos_drm_gem.c | 22 ----------------------
+ drivers/gpu/drm/exynos/exynos_drm_gem.h | 9 ---------
+ drivers/gpu/drm/gma500/gem.c | 17 -----------------
+ drivers/gpu/drm/gma500/psb_drv.c | 2 +-
+ drivers/gpu/drm/gma500/psb_drv.h | 2 --
+ drivers/gpu/drm/i915/i915_drv.c | 2 +-
+ drivers/gpu/drm/i915/i915_drv.h | 2 --
+ drivers/gpu/drm/i915/i915_gem.c | 7 -------
+ drivers/gpu/drm/mgag200/mgag200_drv.c | 2 +-
+ drivers/gpu/drm/mgag200/mgag200_drv.h | 3 ---
+ drivers/gpu/drm/mgag200/mgag200_main.c | 7 -------
+ drivers/gpu/drm/nouveau/nouveau_display.c | 7 -------
+ drivers/gpu/drm/nouveau/nouveau_display.h | 2 --
+ drivers/gpu/drm/nouveau/nouveau_drm.c | 2 +-
+ drivers/gpu/drm/omapdrm/omap_drv.c | 2 +-
+ drivers/gpu/drm/omapdrm/omap_drv.h | 2 --
+ drivers/gpu/drm/omapdrm/omap_gem.c | 15 ---------------
+ drivers/gpu/drm/qxl/qxl_drv.c | 2 +-
+ drivers/gpu/drm/qxl/qxl_drv.h | 3 ---
+ drivers/gpu/drm/qxl/qxl_dumb.c | 7 -------
+ drivers/gpu/drm/radeon/radeon.h | 3 ---
+ drivers/gpu/drm/radeon/radeon_drv.c | 5 +----
+ drivers/gpu/drm/radeon/radeon_gem.c | 7 -------
+ drivers/gpu/drm/shmobile/shmob_drm_drv.c | 2 +-
+ drivers/gpu/drm/tilcdc/tilcdc_drv.c | 2 +-
+ drivers/gpu/drm/udl/udl_drv.c | 2 +-
+ drivers/gpu/drm/udl/udl_drv.h | 2 --
+ drivers/gpu/drm/udl/udl_gem.c | 6 ------
+ drivers/gpu/host1x/drm/drm.c | 2 +-
+ drivers/gpu/host1x/drm/gem.c | 6 ------
+ drivers/gpu/host1x/drm/gem.h | 2 --
+ drivers/staging/imx-drm/imx-drm-core.c | 2 +-
+ include/drm/drmP.h | 3 +++
+ include/drm/drm_gem_cma_helper.h | 8 --------
43 files changed, 32 insertions(+), 187 deletions(-)
-diff --git a/drivers/gpu/drm/ast/ast_drv.c b/drivers/gpu/drm/ast/ast_drv.c
-index df0d0a08097a..a144fb044852 100644
--- a/drivers/gpu/drm/ast/ast_drv.c
+++ b/drivers/gpu/drm/ast/ast_drv.c
@@ -216,7 +216,7 @@ static struct drm_driver driver = {
@@ -89,8 +87,6 @@ index df0d0a08097a..a144fb044852 100644
};
-diff --git a/drivers/gpu/drm/ast/ast_drv.h b/drivers/gpu/drm/ast/ast_drv.h
-index b6b7d70f2832..68e1d324005a 100644
--- a/drivers/gpu/drm/ast/ast_drv.h
+++ b/drivers/gpu/drm/ast/ast_drv.h
@@ -322,9 +322,6 @@ ast_bo(struct ttm_buffer_object *bo)
@@ -103,11 +99,9 @@ index b6b7d70f2832..68e1d324005a 100644
extern int ast_gem_init_object(struct drm_gem_object *obj);
extern void ast_gem_free_object(struct drm_gem_object *obj);
-diff --git a/drivers/gpu/drm/ast/ast_main.c b/drivers/gpu/drm/ast/ast_main.c
-index c195dc2abc09..7f6152d374ca 100644
--- a/drivers/gpu/drm/ast/ast_main.c
+++ b/drivers/gpu/drm/ast/ast_main.c
-@@ -449,13 +449,6 @@ int ast_dumb_create(struct drm_file *file,
+@@ -449,13 +449,6 @@ int ast_dumb_create(struct drm_file *fil
return 0;
}
@@ -121,8 +115,6 @@ index c195dc2abc09..7f6152d374ca 100644
int ast_gem_init_object(struct drm_gem_object *obj)
{
BUG();
-diff --git a/drivers/gpu/drm/cirrus/cirrus_drv.c b/drivers/gpu/drm/cirrus/cirrus_drv.c
-index 8ecb601152ef..d35d99c15f84 100644
--- a/drivers/gpu/drm/cirrus/cirrus_drv.c
+++ b/drivers/gpu/drm/cirrus/cirrus_drv.c
@@ -102,7 +102,7 @@ static struct drm_driver driver = {
@@ -134,11 +126,9 @@ index 8ecb601152ef..d35d99c15f84 100644
};
static struct pci_driver cirrus_pci_driver = {
-diff --git a/drivers/gpu/drm/cirrus/cirrus_drv.h b/drivers/gpu/drm/cirrus/cirrus_drv.h
-index 7ca059596887..33a0f991b0fc 100644
--- a/drivers/gpu/drm/cirrus/cirrus_drv.h
+++ b/drivers/gpu/drm/cirrus/cirrus_drv.h
-@@ -203,9 +203,6 @@ int cirrus_gem_create(struct drm_device *dev,
+@@ -203,9 +203,6 @@ int cirrus_gem_create(struct drm_device
int cirrus_dumb_create(struct drm_file *file,
struct drm_device *dev,
struct drm_mode_create_dumb *args);
@@ -148,11 +138,9 @@ index 7ca059596887..33a0f991b0fc 100644
int cirrus_framebuffer_init(struct drm_device *dev,
struct cirrus_framebuffer *gfb,
-diff --git a/drivers/gpu/drm/cirrus/cirrus_main.c b/drivers/gpu/drm/cirrus/cirrus_main.c
-index 3a7a0efe3675..f130a533a512 100644
--- a/drivers/gpu/drm/cirrus/cirrus_main.c
+++ b/drivers/gpu/drm/cirrus/cirrus_main.c
-@@ -255,13 +255,6 @@ int cirrus_dumb_create(struct drm_file *file,
+@@ -255,13 +255,6 @@ int cirrus_dumb_create(struct drm_file *
return 0;
}
@@ -166,16 +154,14 @@ index 3a7a0efe3675..f130a533a512 100644
int cirrus_gem_init_object(struct drm_gem_object *obj)
{
BUG();
-diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c
-index 2688795172f9..ee9ddc856710 100644
--- a/drivers/gpu/drm/drm_gem.c
+++ b/drivers/gpu/drm/drm_gem.c
-@@ -244,6 +244,20 @@ drm_gem_handle_delete(struct drm_file *filp, u32 handle)
+@@ -244,6 +244,20 @@ drm_gem_handle_delete(struct drm_file *f
EXPORT_SYMBOL(drm_gem_handle_delete);
/**
+ * drm_gem_dumb_destroy - dumb fb callback helper for gem based drivers
-+ *
++ *
+ * This implements the ->dumb_destroy kms driver callback for drivers which use
+ * gem to manage their backing storage.
+ */
@@ -191,11 +177,9 @@ index 2688795172f9..ee9ddc856710 100644
* Create a handle for this object. This adds a handle reference
* to the object, which includes a regular reference count. Callers
* will likely want to dereference the object afterwards.
-diff --git a/drivers/gpu/drm/drm_gem_cma_helper.c b/drivers/gpu/drm/drm_gem_cma_helper.c
-index 11b616ef9dc2..3ec218376734 100644
--- a/drivers/gpu/drm/drm_gem_cma_helper.c
+++ b/drivers/gpu/drm/drm_gem_cma_helper.c
-@@ -235,16 +235,6 @@ int drm_gem_cma_mmap(struct file *filp, struct vm_area_struct *vma)
+@@ -284,16 +284,6 @@ int drm_gem_cma_mmap(struct file *filp,
}
EXPORT_SYMBOL_GPL(drm_gem_cma_mmap);
@@ -212,11 +196,9 @@ index 11b616ef9dc2..3ec218376734 100644
#ifdef CONFIG_DEBUG_FS
void drm_gem_cma_describe(struct drm_gem_cma_object *cma_obj, struct seq_file *m)
{
-diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c b/drivers/gpu/drm/exynos/exynos_drm_drv.c
-index ba6d995e4375..1ff89aca1fed 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_drv.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c
-@@ -276,7 +276,7 @@ static struct drm_driver exynos_drm_driver = {
+@@ -276,7 +276,7 @@ static struct drm_driver exynos_drm_driv
.gem_vm_ops = &exynos_drm_gem_vm_ops,
.dumb_create = exynos_drm_gem_dumb_create,
.dumb_map_offset = exynos_drm_gem_dumb_map_offset,
@@ -225,8 +207,6 @@ index ba6d995e4375..1ff89aca1fed 100644
.prime_handle_to_fd = drm_gem_prime_handle_to_fd,
.prime_fd_to_handle = drm_gem_prime_fd_to_handle,
.gem_prime_export = exynos_dmabuf_prime_export,
-diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.c b/drivers/gpu/drm/exynos/exynos_drm_gem.c
-index 408b71f4c95e..e83930fdf6c7 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_gem.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_gem.c
@@ -735,28 +735,6 @@ unlock:
@@ -258,11 +238,9 @@ index 408b71f4c95e..e83930fdf6c7 100644
int exynos_drm_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
{
struct drm_gem_object *obj = vma->vm_private_data;
-diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.h b/drivers/gpu/drm/exynos/exynos_drm_gem.h
-index 468766bee450..09555afdfe9c 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_gem.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_gem.h
-@@ -151,15 +151,6 @@ int exynos_drm_gem_dumb_map_offset(struct drm_file *file_priv,
+@@ -151,15 +151,6 @@ int exynos_drm_gem_dumb_map_offset(struc
struct drm_device *dev, uint32_t handle,
uint64_t *offset);
@@ -278,11 +256,9 @@ index 468766bee450..09555afdfe9c 100644
/* page fault handler and mmap fault address(virtual) to physical memory. */
int exynos_drm_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf);
-diff --git a/drivers/gpu/drm/gma500/gem.c b/drivers/gpu/drm/gma500/gem.c
-index 2f77bea30b11..10ae8c52d06f 100644
--- a/drivers/gpu/drm/gma500/gem.c
+++ b/drivers/gpu/drm/gma500/gem.c
-@@ -162,23 +162,6 @@ int psb_gem_dumb_create(struct drm_file *file, struct drm_device *dev,
+@@ -162,23 +162,6 @@ int psb_gem_dumb_create(struct drm_file
}
/**
@@ -306,8 +282,6 @@ index 2f77bea30b11..10ae8c52d06f 100644
* psb_gem_fault - pagefault handler for GEM objects
* @vma: the VMA of the GEM object
* @vmf: fault detail
-diff --git a/drivers/gpu/drm/gma500/psb_drv.c b/drivers/gpu/drm/gma500/psb_drv.c
-index bddea5807442..ed06d5ce3757 100644
--- a/drivers/gpu/drm/gma500/psb_drv.c
+++ b/drivers/gpu/drm/gma500/psb_drv.c
@@ -652,7 +652,7 @@ static struct drm_driver driver = {
@@ -319,11 +293,9 @@ index bddea5807442..ed06d5ce3757 100644
.fops = &psb_gem_fops,
.name = DRIVER_NAME,
.desc = DRIVER_DESC,
-diff --git a/drivers/gpu/drm/gma500/psb_drv.h b/drivers/gpu/drm/gma500/psb_drv.h
-index 6053b8abcd12..984cacfcbaf2 100644
--- a/drivers/gpu/drm/gma500/psb_drv.h
+++ b/drivers/gpu/drm/gma500/psb_drv.h
-@@ -838,8 +838,6 @@ extern int psb_gem_get_aperture(struct drm_device *dev, void *data,
+@@ -838,8 +838,6 @@ extern int psb_gem_get_aperture(struct d
struct drm_file *file);
extern int psb_gem_dumb_create(struct drm_file *file, struct drm_device *dev,
struct drm_mode_create_dumb *args);
@@ -332,8 +304,6 @@ index 6053b8abcd12..984cacfcbaf2 100644
extern int psb_gem_dumb_map_gtt(struct drm_file *file, struct drm_device *dev,
uint32_t handle, uint64_t *offset);
extern int psb_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf);
-diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
-index 01d63a0435fb..13457e3e9cad 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -1038,7 +1038,7 @@ static struct drm_driver driver = {
@@ -345,11 +315,9 @@ index 01d63a0435fb..13457e3e9cad 100644
.ioctls = i915_ioctls,
.fops = &i915_driver_fops,
.name = DRIVER_NAME,
-diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
-index 62ec760782f5..06c31752fcb2 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
-@@ -1775,8 +1775,6 @@ int i915_gem_dumb_create(struct drm_file *file_priv,
+@@ -1775,8 +1775,6 @@ int i915_gem_dumb_create(struct drm_file
struct drm_mode_create_dumb *args);
int i915_gem_mmap_gtt(struct drm_file *file_priv, struct drm_device *dev,
uint32_t handle, uint64_t *offset);
@@ -358,11 +326,9 @@ index 62ec760782f5..06c31752fcb2 100644
/**
* Returns true if seq1 is later than seq2.
*/
-diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
-index d31e15dd173c..967fe650fa8b 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
-@@ -245,13 +245,6 @@ i915_gem_dumb_create(struct drm_file *file,
+@@ -245,13 +245,6 @@ i915_gem_dumb_create(struct drm_file *fi
args->size, &args->handle);
}
@@ -376,8 +342,6 @@ index d31e15dd173c..967fe650fa8b 100644
/**
* Creates a new mm object and returns a handle to it.
*/
-diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.c b/drivers/gpu/drm/mgag200/mgag200_drv.c
-index 122b571ccc7c..bd9196478735 100644
--- a/drivers/gpu/drm/mgag200/mgag200_drv.c
+++ b/drivers/gpu/drm/mgag200/mgag200_drv.c
@@ -104,7 +104,7 @@ static struct drm_driver driver = {
@@ -389,11 +353,9 @@ index 122b571ccc7c..bd9196478735 100644
};
static struct pci_driver mgag200_pci_driver = {
-diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.h b/drivers/gpu/drm/mgag200/mgag200_drv.h
-index 988911afcc8b..e61ce34910d6 100644
--- a/drivers/gpu/drm/mgag200/mgag200_drv.h
+++ b/drivers/gpu/drm/mgag200/mgag200_drv.h
-@@ -248,9 +248,6 @@ int mgag200_gem_init_object(struct drm_gem_object *obj);
+@@ -248,9 +248,6 @@ int mgag200_gem_init_object(struct drm_g
int mgag200_dumb_create(struct drm_file *file,
struct drm_device *dev,
struct drm_mode_create_dumb *args);
@@ -403,11 +365,9 @@ index 988911afcc8b..e61ce34910d6 100644
void mgag200_gem_free_object(struct drm_gem_object *obj);
int
mgag200_dumb_mmap_offset(struct drm_file *file,
-diff --git a/drivers/gpu/drm/mgag200/mgag200_main.c b/drivers/gpu/drm/mgag200/mgag200_main.c
-index 2d56e28d2b21..4529d4dd12c2 100644
--- a/drivers/gpu/drm/mgag200/mgag200_main.c
+++ b/drivers/gpu/drm/mgag200/mgag200_main.c
-@@ -291,13 +291,6 @@ int mgag200_dumb_create(struct drm_file *file,
+@@ -291,13 +291,6 @@ int mgag200_dumb_create(struct drm_file
return 0;
}
@@ -421,11 +381,9 @@ index 2d56e28d2b21..4529d4dd12c2 100644
int mgag200_gem_init_object(struct drm_gem_object *obj)
{
BUG();
-diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c b/drivers/gpu/drm/nouveau/nouveau_display.c
-index 52498de87a3b..05ae27277543 100644
--- a/drivers/gpu/drm/nouveau/nouveau_display.c
+++ b/drivers/gpu/drm/nouveau/nouveau_display.c
-@@ -689,13 +689,6 @@ nouveau_display_dumb_create(struct drm_file *file_priv, struct drm_device *dev,
+@@ -689,13 +689,6 @@ nouveau_display_dumb_create(struct drm_f
}
int
@@ -439,11 +397,9 @@ index 52498de87a3b..05ae27277543 100644
nouveau_display_dumb_map_offset(struct drm_file *file_priv,
struct drm_device *dev,
uint32_t handle, uint64_t *poffset)
-diff --git a/drivers/gpu/drm/nouveau/nouveau_display.h b/drivers/gpu/drm/nouveau/nouveau_display.h
-index 1ea3e4734b62..185e74132a6d 100644
--- a/drivers/gpu/drm/nouveau/nouveau_display.h
+++ b/drivers/gpu/drm/nouveau/nouveau_display.h
-@@ -68,8 +68,6 @@ int nouveau_display_dumb_create(struct drm_file *, struct drm_device *,
+@@ -68,8 +68,6 @@ int nouveau_display_dumb_create(struct
struct drm_mode_create_dumb *args);
int nouveau_display_dumb_map_offset(struct drm_file *, struct drm_device *,
u32 handle, u64 *offset);
@@ -452,8 +408,6 @@ index 1ea3e4734b62..185e74132a6d 100644
void nouveau_hdmi_mode_set(struct drm_encoder *, struct drm_display_mode *);
-diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c
-index 383f4e6ea9d1..b77bcb9237e0 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drm.c
+++ b/drivers/gpu/drm/nouveau/nouveau_drm.c
@@ -714,7 +714,7 @@ driver = {
@@ -465,11 +419,9 @@ index 383f4e6ea9d1..b77bcb9237e0 100644
.name = DRIVER_NAME,
.desc = DRIVER_DESC,
-diff --git a/drivers/gpu/drm/omapdrm/omap_drv.c b/drivers/gpu/drm/omapdrm/omap_drv.c
-index 826586ffbe83..75886a3bf639 100644
--- a/drivers/gpu/drm/omapdrm/omap_drv.c
+++ b/drivers/gpu/drm/omapdrm/omap_drv.c
-@@ -618,7 +618,7 @@ static struct drm_driver omap_drm_driver = {
+@@ -618,7 +618,7 @@ static struct drm_driver omap_drm_driver
.gem_vm_ops = &omap_gem_vm_ops,
.dumb_create = omap_gem_dumb_create,
.dumb_map_offset = omap_gem_dumb_map_offset,
@@ -478,11 +430,9 @@ index 826586ffbe83..75886a3bf639 100644
.ioctls = ioctls,
.num_ioctls = DRM_OMAP_NUM_IOCTLS,
.fops = &omapdriver_fops,
-diff --git a/drivers/gpu/drm/omapdrm/omap_drv.h b/drivers/gpu/drm/omapdrm/omap_drv.h
-index 215a20dd340c..fd13601ff6fb 100644
--- a/drivers/gpu/drm/omapdrm/omap_drv.h
+++ b/drivers/gpu/drm/omapdrm/omap_drv.h
-@@ -224,8 +224,6 @@ int omap_gem_init_object(struct drm_gem_object *obj);
+@@ -224,8 +224,6 @@ int omap_gem_init_object(struct drm_gem_
void *omap_gem_vaddr(struct drm_gem_object *obj);
int omap_gem_dumb_map_offset(struct drm_file *file, struct drm_device *dev,
uint32_t handle, uint64_t *offset);
@@ -491,11 +441,9 @@ index 215a20dd340c..fd13601ff6fb 100644
int omap_gem_dumb_create(struct drm_file *file, struct drm_device *dev,
struct drm_mode_create_dumb *args);
int omap_gem_mmap(struct file *filp, struct vm_area_struct *vma);
-diff --git a/drivers/gpu/drm/omapdrm/omap_gem.c b/drivers/gpu/drm/omapdrm/omap_gem.c
-index f90531fc00c9..b1f19702550f 100644
--- a/drivers/gpu/drm/omapdrm/omap_gem.c
+++ b/drivers/gpu/drm/omapdrm/omap_gem.c
-@@ -629,21 +629,6 @@ int omap_gem_dumb_create(struct drm_file *file, struct drm_device *dev,
+@@ -629,21 +629,6 @@ int omap_gem_dumb_create(struct drm_file
}
/**
@@ -517,8 +465,6 @@ index f90531fc00c9..b1f19702550f 100644
* omap_gem_dumb_map - buffer mapping for dumb interface
* @file: our drm client file
* @dev: drm device
-diff --git a/drivers/gpu/drm/qxl/qxl_drv.c b/drivers/gpu/drm/qxl/qxl_drv.c
-index aa291d8a98a2..60cb159c4f7d 100644
--- a/drivers/gpu/drm/qxl/qxl_drv.c
+++ b/drivers/gpu/drm/qxl/qxl_drv.c
@@ -99,7 +99,7 @@ static struct drm_driver qxl_driver = {
@@ -530,11 +476,9 @@ index aa291d8a98a2..60cb159c4f7d 100644
#if defined(CONFIG_DEBUG_FS)
.debugfs_init = qxl_debugfs_init,
.debugfs_cleanup = qxl_debugfs_takedown,
-diff --git a/drivers/gpu/drm/qxl/qxl_drv.h b/drivers/gpu/drm/qxl/qxl_drv.h
-index 43d06ab28a21..089fd42802dd 100644
--- a/drivers/gpu/drm/qxl/qxl_drv.h
+++ b/drivers/gpu/drm/qxl/qxl_drv.h
-@@ -409,9 +409,6 @@ int qxl_bo_kmap(struct qxl_bo *bo, void **ptr);
+@@ -409,9 +409,6 @@ int qxl_bo_kmap(struct qxl_bo *bo, void
int qxl_mode_dumb_create(struct drm_file *file_priv,
struct drm_device *dev,
struct drm_mode_create_dumb *args);
@@ -544,11 +488,9 @@ index 43d06ab28a21..089fd42802dd 100644
int qxl_mode_dumb_mmap(struct drm_file *filp,
struct drm_device *dev,
uint32_t handle, uint64_t *offset_p);
-diff --git a/drivers/gpu/drm/qxl/qxl_dumb.c b/drivers/gpu/drm/qxl/qxl_dumb.c
-index 847c4ee798f7..d34bb4130ff0 100644
--- a/drivers/gpu/drm/qxl/qxl_dumb.c
+++ b/drivers/gpu/drm/qxl/qxl_dumb.c
-@@ -68,13 +68,6 @@ int qxl_mode_dumb_create(struct drm_file *file_priv,
+@@ -68,13 +68,6 @@ int qxl_mode_dumb_create(struct drm_file
return 0;
}
@@ -562,11 +504,9 @@ index 847c4ee798f7..d34bb4130ff0 100644
int qxl_mode_dumb_mmap(struct drm_file *file_priv,
struct drm_device *dev,
uint32_t handle, uint64_t *offset_p)
-diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
-index d4ff48ce1d8b..0fbc44e468da 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
-@@ -444,9 +444,6 @@ int radeon_mode_dumb_create(struct drm_file *file_priv,
+@@ -444,9 +444,6 @@ int radeon_mode_dumb_create(struct drm_f
int radeon_mode_dumb_mmap(struct drm_file *filp,
struct drm_device *dev,
uint32_t handle, uint64_t *offset_p);
@@ -576,11 +516,9 @@ index d4ff48ce1d8b..0fbc44e468da 100644
/*
* Semaphores.
-diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c
-index 094e7e5ea39e..bef72931ea08 100644
--- a/drivers/gpu/drm/radeon/radeon_drv.c
+++ b/drivers/gpu/drm/radeon/radeon_drv.c
-@@ -119,9 +119,6 @@ int radeon_mode_dumb_mmap(struct drm_file *filp,
+@@ -119,9 +119,6 @@ int radeon_mode_dumb_mmap(struct drm_fil
int radeon_mode_dumb_create(struct drm_file *file_priv,
struct drm_device *dev,
struct drm_mode_create_dumb *args);
@@ -599,11 +537,9 @@ index 094e7e5ea39e..bef72931ea08 100644
.fops = &radeon_driver_kms_fops,
.prime_handle_to_fd = drm_gem_prime_handle_to_fd,
-diff --git a/drivers/gpu/drm/radeon/radeon_gem.c b/drivers/gpu/drm/radeon/radeon_gem.c
-index aa796031ab65..dce99c8a5835 100644
--- a/drivers/gpu/drm/radeon/radeon_gem.c
+++ b/drivers/gpu/drm/radeon/radeon_gem.c
-@@ -570,13 +570,6 @@ int radeon_mode_dumb_create(struct drm_file *file_priv,
+@@ -570,13 +570,6 @@ int radeon_mode_dumb_create(struct drm_f
return 0;
}
@@ -617,11 +553,9 @@ index aa796031ab65..dce99c8a5835 100644
#if defined(CONFIG_DEBUG_FS)
static int radeon_debugfs_gem_info(struct seq_file *m, void *data)
{
-diff --git a/drivers/gpu/drm/shmobile/shmob_drm_drv.c b/drivers/gpu/drm/shmobile/shmob_drm_drv.c
-index f6e0b5395051..946bd28bf5da 100644
--- a/drivers/gpu/drm/shmobile/shmob_drm_drv.c
+++ b/drivers/gpu/drm/shmobile/shmob_drm_drv.c
-@@ -285,7 +285,7 @@ static struct drm_driver shmob_drm_driver = {
+@@ -285,7 +285,7 @@ static struct drm_driver shmob_drm_drive
.gem_vm_ops = &drm_gem_cma_vm_ops,
.dumb_create = drm_gem_cma_dumb_create,
.dumb_map_offset = drm_gem_cma_dumb_map_offset,
@@ -630,11 +564,9 @@ index f6e0b5395051..946bd28bf5da 100644
.fops = &shmob_drm_fops,
.name = "shmob-drm",
.desc = "Renesas SH Mobile DRM",
-diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.c b/drivers/gpu/drm/tilcdc/tilcdc_drv.c
-index 2b5461bcd9fb..bba8daf9230c 100644
--- a/drivers/gpu/drm/tilcdc/tilcdc_drv.c
+++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.c
-@@ -490,7 +490,7 @@ static struct drm_driver tilcdc_driver = {
+@@ -490,7 +490,7 @@ static struct drm_driver tilcdc_driver =
.gem_vm_ops = &drm_gem_cma_vm_ops,
.dumb_create = drm_gem_cma_dumb_create,
.dumb_map_offset = drm_gem_cma_dumb_map_offset,
@@ -643,8 +575,6 @@ index 2b5461bcd9fb..bba8daf9230c 100644
#ifdef CONFIG_DEBUG_FS
.debugfs_init = tilcdc_debugfs_init,
.debugfs_cleanup = tilcdc_debugfs_cleanup,
-diff --git a/drivers/gpu/drm/udl/udl_drv.c b/drivers/gpu/drm/udl/udl_drv.c
-index c0770dbba74a..bb0af58c769a 100644
--- a/drivers/gpu/drm/udl/udl_drv.c
+++ b/drivers/gpu/drm/udl/udl_drv.c
@@ -84,7 +84,7 @@ static struct drm_driver driver = {
@@ -656,11 +586,9 @@ index c0770dbba74a..bb0af58c769a 100644
.fops = &udl_driver_fops,
.prime_fd_to_handle = drm_gem_prime_fd_to_handle,
-diff --git a/drivers/gpu/drm/udl/udl_drv.h b/drivers/gpu/drm/udl/udl_drv.h
-index cc6d90f28c71..56aec9409fa3 100644
--- a/drivers/gpu/drm/udl/udl_drv.h
+++ b/drivers/gpu/drm/udl/udl_drv.h
-@@ -114,8 +114,6 @@ int udl_dumb_create(struct drm_file *file_priv,
+@@ -114,8 +114,6 @@ int udl_dumb_create(struct drm_file *fil
struct drm_mode_create_dumb *args);
int udl_gem_mmap(struct drm_file *file_priv, struct drm_device *dev,
uint32_t handle, uint64_t *offset);
@@ -669,11 +597,9 @@ index cc6d90f28c71..56aec9409fa3 100644
int udl_gem_init_object(struct drm_gem_object *obj);
void udl_gem_free_object(struct drm_gem_object *gem_obj);
-diff --git a/drivers/gpu/drm/udl/udl_gem.c b/drivers/gpu/drm/udl/udl_gem.c
-index 2a4cb2f83b36..b5e3b8038253 100644
--- a/drivers/gpu/drm/udl/udl_gem.c
+++ b/drivers/gpu/drm/udl/udl_gem.c
-@@ -66,12 +66,6 @@ int udl_dumb_create(struct drm_file *file,
+@@ -66,12 +66,6 @@ int udl_dumb_create(struct drm_file *fil
args->size, &args->handle);
}
@@ -686,8 +612,6 @@ index 2a4cb2f83b36..b5e3b8038253 100644
int udl_drm_gem_mmap(struct file *filp, struct vm_area_struct *vma)
{
int ret;
-diff --git a/drivers/gpu/host1x/drm/drm.c b/drivers/gpu/host1x/drm/drm.c
-index 2b561c9118c6..da15a6291bb9 100644
--- a/drivers/gpu/host1x/drm/drm.c
+++ b/drivers/gpu/host1x/drm/drm.c
@@ -625,7 +625,7 @@ struct drm_driver tegra_drm_driver = {
@@ -699,11 +623,9 @@ index 2b561c9118c6..da15a6291bb9 100644
.ioctls = tegra_drm_ioctls,
.num_ioctls = ARRAY_SIZE(tegra_drm_ioctls),
-diff --git a/drivers/gpu/host1x/drm/gem.c b/drivers/gpu/host1x/drm/gem.c
-index bc323b3dbe4d..3c35622c9f15 100644
--- a/drivers/gpu/host1x/drm/gem.c
+++ b/drivers/gpu/host1x/drm/gem.c
-@@ -261,9 +261,3 @@ int tegra_drm_mmap(struct file *file, struct vm_area_struct *vma)
+@@ -261,9 +261,3 @@ int tegra_drm_mmap(struct file *file, st
return ret;
}
@@ -713,11 +635,9 @@ index bc323b3dbe4d..3c35622c9f15 100644
-{
- return drm_gem_handle_delete(file, handle);
-}
-diff --git a/drivers/gpu/host1x/drm/gem.h b/drivers/gpu/host1x/drm/gem.h
-index 34de2b486eb7..2e93b0379da8 100644
--- a/drivers/gpu/host1x/drm/gem.h
+++ b/drivers/gpu/host1x/drm/gem.h
-@@ -49,8 +49,6 @@ int tegra_bo_dumb_create(struct drm_file *file, struct drm_device *drm,
+@@ -49,8 +49,6 @@ int tegra_bo_dumb_create(struct drm_file
struct drm_mode_create_dumb *args);
int tegra_bo_dumb_map_offset(struct drm_file *file, struct drm_device *drm,
uint32_t handle, uint64_t *offset);
@@ -726,11 +646,9 @@ index 34de2b486eb7..2e93b0379da8 100644
int tegra_drm_mmap(struct file *file, struct vm_area_struct *vma);
-diff --git a/drivers/staging/imx-drm/imx-drm-core.c b/drivers/staging/imx-drm/imx-drm-core.c
-index a532ca568526..a18622570812 100644
--- a/drivers/staging/imx-drm/imx-drm-core.c
+++ b/drivers/staging/imx-drm/imx-drm-core.c
-@@ -801,7 +801,7 @@ static struct drm_driver imx_drm_driver = {
+@@ -801,7 +801,7 @@ static struct drm_driver imx_drm_driver
.gem_vm_ops = &drm_gem_cma_vm_ops,
.dumb_create = drm_gem_cma_dumb_create,
.dumb_map_offset = drm_gem_cma_dumb_map_offset,
@@ -739,11 +657,9 @@ index a532ca568526..a18622570812 100644
.get_vblank_counter = drm_vblank_count,
.enable_vblank = imx_drm_enable_vblank,
-diff --git a/include/drm/drmP.h b/include/drm/drmP.h
-index bf677c0b4cae..9a8ea57e3b94 100644
--- a/include/drm/drmP.h
+++ b/include/drm/drmP.h
-@@ -1589,6 +1589,9 @@ extern int drm_prime_sg_to_page_addr_arrays(struct sg_table *sgt, struct page **
+@@ -1589,6 +1589,9 @@ extern int drm_prime_sg_to_page_addr_arr
extern struct sg_table *drm_prime_pages_to_sg(struct page **pages, int nr_pages);
extern void drm_prime_gem_destroy(struct drm_gem_object *obj, struct sg_table *sg);
@@ -753,11 +669,9 @@ index bf677c0b4cae..9a8ea57e3b94 100644
void drm_prime_init_file_private(struct drm_prime_file_private *prime_fpriv);
void drm_prime_destroy_file_private(struct drm_prime_file_private *prime_fpriv);
-diff --git a/include/drm/drm_gem_cma_helper.h b/include/drm/drm_gem_cma_helper.h
-index 63397ced9254..632a6c50fab7 100644
--- a/include/drm/drm_gem_cma_helper.h
+++ b/include/drm/drm_gem_cma_helper.h
-@@ -27,14 +27,6 @@ int drm_gem_cma_dumb_map_offset(struct drm_file *file_priv,
+@@ -30,14 +30,6 @@ int drm_gem_cma_dumb_map_offset(struct d
/* set vm_flags and we can change the vm attribute to other one at here. */
int drm_gem_cma_mmap(struct file *filp, struct vm_area_struct *vma);
@@ -772,6 +686,3 @@ index 63397ced9254..632a6c50fab7 100644
/* allocate physical memory. */
struct drm_gem_cma_object *drm_gem_cma_create(struct drm_device *drm,
unsigned int size);
---
-1.8.5.rc3
-
diff --git a/patches.baytrail/1123-drivers-i2c-busses-don-t-check-resource-with-devm_io.patch b/patches.baytrail/1123-drivers-i2c-busses-don-t-check-resource-with-devm_io.patch
index 211975ee833..4921e23ef0a 100644
--- a/patches.baytrail/1123-drivers-i2c-busses-don-t-check-resource-with-devm_io.patch
+++ b/patches.baytrail/1123-drivers-i2c-busses-don-t-check-resource-with-devm_io.patch
@@ -10,18 +10,16 @@ Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
(cherry picked from commit 3cc2d009bc210516c61536273b304c4f6ccd797c)
Signed-off-by: Darren Hart <dvhart@linux.intel.com>
---
- drivers/i2c/busses/i2c-davinci.c | 8 +-------
- drivers/i2c/busses/i2c-designware-platdrv.c | 8 +-------
- drivers/i2c/busses/i2c-imx.c | 6 +-----
- drivers/i2c/busses/i2c-omap.c | 8 +-------
- drivers/i2c/busses/i2c-rcar.c | 7 +------
+ drivers/i2c/busses/i2c-davinci.c | 8 +-------
+ drivers/i2c/busses/i2c-designware-platdrv.c | 8 +-------
+ drivers/i2c/busses/i2c-imx.c | 6 +-----
+ drivers/i2c/busses/i2c-omap.c | 8 +-------
+ drivers/i2c/busses/i2c-rcar.c | 7 +------
5 files changed, 5 insertions(+), 32 deletions(-)
-diff --git a/drivers/i2c/busses/i2c-davinci.c b/drivers/i2c/busses/i2c-davinci.c
-index cf20e06a88e1..fa556057d224 100644
--- a/drivers/i2c/busses/i2c-davinci.c
+++ b/drivers/i2c/busses/i2c-davinci.c
-@@ -646,13 +646,6 @@ static int davinci_i2c_probe(struct platform_device *pdev)
+@@ -646,13 +646,6 @@ static int davinci_i2c_probe(struct plat
struct resource *mem, *irq;
int r;
@@ -35,7 +33,7 @@ index cf20e06a88e1..fa556057d224 100644
irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
if (!irq) {
dev_err(&pdev->dev, "no irq resource?\n");
-@@ -697,6 +690,7 @@ static int davinci_i2c_probe(struct platform_device *pdev)
+@@ -697,6 +690,7 @@ static int davinci_i2c_probe(struct plat
return -ENODEV;
clk_prepare_enable(dev->clk);
@@ -43,11 +41,9 @@ index cf20e06a88e1..fa556057d224 100644
dev->base = devm_ioremap_resource(&pdev->dev, mem);
if (IS_ERR(dev->base)) {
r = PTR_ERR(dev->base);
-diff --git a/drivers/i2c/busses/i2c-designware-platdrv.c b/drivers/i2c/busses/i2c-designware-platdrv.c
-index 35b70a1edf57..ee46c92d7e3c 100644
--- a/drivers/i2c/busses/i2c-designware-platdrv.c
+++ b/drivers/i2c/busses/i2c-designware-platdrv.c
-@@ -87,13 +87,6 @@ static int dw_i2c_probe(struct platform_device *pdev)
+@@ -87,13 +87,6 @@ static int dw_i2c_probe(struct platform_
struct resource *mem;
int irq, r;
@@ -61,7 +57,7 @@ index 35b70a1edf57..ee46c92d7e3c 100644
irq = platform_get_irq(pdev, 0);
if (irq < 0) {
dev_err(&pdev->dev, "no irq resource?\n");
-@@ -104,6 +97,7 @@ static int dw_i2c_probe(struct platform_device *pdev)
+@@ -104,6 +97,7 @@ static int dw_i2c_probe(struct platform_
if (!dev)
return -ENOMEM;
@@ -69,11 +65,9 @@ index 35b70a1edf57..ee46c92d7e3c 100644
dev->base = devm_ioremap_resource(&pdev->dev, mem);
if (IS_ERR(dev->base))
return PTR_ERR(dev->base);
-diff --git a/drivers/i2c/busses/i2c-imx.c b/drivers/i2c/busses/i2c-imx.c
-index 8c7526ca912e..6406aa960f2a 100644
--- a/drivers/i2c/busses/i2c-imx.c
+++ b/drivers/i2c/busses/i2c-imx.c
-@@ -498,17 +498,13 @@ static int __init i2c_imx_probe(struct platform_device *pdev)
+@@ -498,17 +498,13 @@ static int __init i2c_imx_probe(struct p
dev_dbg(&pdev->dev, "<%s>\n", __func__);
@@ -92,11 +86,9 @@ index 8c7526ca912e..6406aa960f2a 100644
base = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(base))
return PTR_ERR(base);
-diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
-index b06be8e3bb76..aa77626f8315 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
-@@ -1087,13 +1087,6 @@ omap_i2c_probe(struct platform_device *pdev)
+@@ -1087,13 +1087,6 @@ omap_i2c_probe(struct platform_device *p
u32 rev;
u16 minor, major, scheme;
@@ -110,7 +102,7 @@ index b06be8e3bb76..aa77626f8315 100644
irq = platform_get_irq(pdev, 0);
if (irq < 0) {
dev_err(&pdev->dev, "no irq resource?\n");
-@@ -1106,6 +1099,7 @@ omap_i2c_probe(struct platform_device *pdev)
+@@ -1106,6 +1099,7 @@ omap_i2c_probe(struct platform_device *p
return -ENOMEM;
}
@@ -118,11 +110,9 @@ index b06be8e3bb76..aa77626f8315 100644
dev->base = devm_ioremap_resource(&pdev->dev, mem);
if (IS_ERR(dev->base))
return PTR_ERR(dev->base);
-diff --git a/drivers/i2c/busses/i2c-rcar.c b/drivers/i2c/busses/i2c-rcar.c
-index 4ba4a95b6b26..0fc585861610 100644
--- a/drivers/i2c/busses/i2c-rcar.c
+++ b/drivers/i2c/busses/i2c-rcar.c
-@@ -623,12 +623,6 @@ static int rcar_i2c_probe(struct platform_device *pdev)
+@@ -658,12 +658,6 @@ static int rcar_i2c_probe(struct platfor
u32 bus_speed;
int ret;
@@ -135,7 +125,7 @@ index 4ba4a95b6b26..0fc585861610 100644
priv = devm_kzalloc(dev, sizeof(struct rcar_i2c_priv), GFP_KERNEL);
if (!priv) {
dev_err(dev, "no mem for private data\n");
-@@ -642,6 +636,7 @@ static int rcar_i2c_probe(struct platform_device *pdev)
+@@ -685,6 +679,7 @@ static int rcar_i2c_probe(struct platfor
if (ret < 0)
return ret;
@@ -143,6 +133,3 @@ index 4ba4a95b6b26..0fc585861610 100644
priv->io = devm_ioremap_resource(dev, res);
if (IS_ERR(priv->io))
return PTR_ERR(priv->io);
---
-1.8.5.rc3
-
diff --git a/patches.baytrail/1137-dma-move-dw_dmac-driver-to-an-own-directory.patch b/patches.baytrail/1137-dma-move-dw_dmac-driver-to-an-own-directory.patch
index 2038b356f83..a08d341a208 100644
--- a/patches.baytrail/1137-dma-move-dw_dmac-driver-to-an-own-directory.patch
+++ b/patches.baytrail/1137-dma-move-dw_dmac-driver-to-an-own-directory.patch
@@ -20,17 +20,24 @@ Signed-off-by: Darren Hart <dvhart@linux.intel.com>
drivers/dma/dw/Makefile | 1 +
drivers/dma/{ => dw}/dw_dmac.c | 2 +-
drivers/dma/{ => dw}/dw_dmac_regs.h | 0
- 7 files changed, 28 insertions(+), 23 deletions(-)
+ MAINTAINERS | 3
+ drivers/dma/Kconfig | 20
+ drivers/dma/Makefile | 2
+ drivers/dma/dw/Kconfig | 23
+ drivers/dma/dw/Makefile | 1
+ drivers/dma/dw/dw_dmac.c | 1969 ++++++++++++++++++++++++++++++++++++++++++
+ drivers/dma/dw/dw_dmac_regs.h | 311 ++++++
+ drivers/dma/dw_dmac.c | 1969 ------------------------------------------
+ drivers/dma/dw_dmac_regs.h | 311 ------
+ 9 files changed, 2307 insertions(+), 2302 deletions(-)
create mode 100644 drivers/dma/dw/Kconfig
create mode 100644 drivers/dma/dw/Makefile
rename drivers/dma/{ => dw}/dw_dmac.c (99%)
rename drivers/dma/{ => dw}/dw_dmac_regs.h (100%)
-diff --git a/MAINTAINERS b/MAINTAINERS
-index 30287b8a223a..124d32cae616 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
-@@ -6991,8 +6991,7 @@ SYNOPSYS DESIGNWARE DMAC DRIVER
+@@ -6998,8 +6998,7 @@ SYNOPSYS DESIGNWARE DMAC DRIVER
M: Viresh Kumar <viresh.linux@gmail.com>
S: Maintained
F: include/linux/dw_dmac.h
@@ -40,8 +47,6 @@ index 30287b8a223a..124d32cae616 100644
SYNOPSYS DESIGNWARE MMC/SD/SDIO DRIVER
M: Seungwon Jeon <tgih.jun@samsung.com>
-diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
-index e9924898043a..146a1d864a71 100644
--- a/drivers/dma/Kconfig
+++ b/drivers/dma/Kconfig
@@ -79,25 +79,7 @@ config INTEL_IOP_ADMA
@@ -71,8 +76,6 @@ index e9924898043a..146a1d864a71 100644
config AT_HDMAC
tristate "Atmel AHB DMA support"
-diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile
-index a2b0df591f95..ac44ca0d468a 100644
--- a/drivers/dma/Makefile
+++ b/drivers/dma/Makefile
@@ -15,7 +15,7 @@ obj-$(CONFIG_FSL_DMA) += fsldma.o
@@ -84,9 +87,6 @@ index a2b0df591f95..ac44ca0d468a 100644
obj-$(CONFIG_AT_HDMAC) += at_hdmac.o
obj-$(CONFIG_MX3_IPU) += ipu/
obj-$(CONFIG_TXX9_DMAC) += txx9dmac.o
-diff --git a/drivers/dma/dw/Kconfig b/drivers/dma/dw/Kconfig
-new file mode 100644
-index 000000000000..38a215af5ccc
--- /dev/null
+++ b/drivers/dma/dw/Kconfig
@@ -0,0 +1,23 @@
@@ -113,34 +113,4579 @@ index 000000000000..38a215af5ccc
+ like the Atmel AVR32 architecture.
+
+ If unsure, use the default setting.
-diff --git a/drivers/dma/dw/Makefile b/drivers/dma/dw/Makefile
-new file mode 100644
-index 000000000000..dd8d9936beef
--- /dev/null
+++ b/drivers/dma/dw/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_DW_DMAC) += dw_dmac.o
-diff --git a/drivers/dma/dw_dmac.c b/drivers/dma/dw/dw_dmac.c
-similarity index 99%
-rename from drivers/dma/dw_dmac.c
-rename to drivers/dma/dw/dw_dmac.c
-index 2b65ba614e60..15f3f4f79c10 100644
---- a/drivers/dma/dw_dmac.c
+--- /dev/null
+++ b/drivers/dma/dw/dw_dmac.c
-@@ -28,8 +28,8 @@
- #include <linux/acpi.h>
- #include <linux/acpi_dma.h>
-
+@@ -0,0 +1,1969 @@
++/*
++ * Core driver for the Synopsys DesignWare DMA Controller
++ *
++ * Copyright (C) 2007-2008 Atmel Corporation
++ * Copyright (C) 2010-2011 ST Microelectronics
++ *
++ * 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/bitops.h>
++#include <linux/clk.h>
++#include <linux/delay.h>
++#include <linux/dmaengine.h>
++#include <linux/dma-mapping.h>
++#include <linux/dmapool.h>
++#include <linux/err.h>
++#include <linux/init.h>
++#include <linux/interrupt.h>
++#include <linux/io.h>
++#include <linux/of.h>
++#include <linux/of_dma.h>
++#include <linux/mm.h>
++#include <linux/module.h>
++#include <linux/platform_device.h>
++#include <linux/slab.h>
++#include <linux/acpi.h>
++#include <linux/acpi_dma.h>
++
+#include "../dmaengine.h"
- #include "dw_dmac_regs.h"
++#include "dw_dmac_regs.h"
++
++/*
++ * This supports the Synopsys "DesignWare AHB Central DMA Controller",
++ * (DW_ahb_dmac) which is used with various AMBA 2.0 systems (not all
++ * of which use ARM any more). See the "Databook" from Synopsys for
++ * information beyond what licensees probably provide.
++ *
++ * The driver has currently been tested only with the Atmel AT32AP7000,
++ * which does not support descriptor writeback.
++ */
++
++static inline unsigned int dwc_get_dms(struct dw_dma_slave *slave)
++{
++ return slave ? slave->dst_master : 0;
++}
++
++static inline unsigned int dwc_get_sms(struct dw_dma_slave *slave)
++{
++ return slave ? slave->src_master : 1;
++}
++
++static inline void dwc_set_masters(struct dw_dma_chan *dwc)
++{
++ struct dw_dma *dw = to_dw_dma(dwc->chan.device);
++ struct dw_dma_slave *dws = dwc->chan.private;
++ unsigned char mmax = dw->nr_masters - 1;
++
++ if (dwc->request_line == ~0) {
++ dwc->src_master = min_t(unsigned char, mmax, dwc_get_sms(dws));
++ dwc->dst_master = min_t(unsigned char, mmax, dwc_get_dms(dws));
++ }
++}
++
++#define DWC_DEFAULT_CTLLO(_chan) ({ \
++ struct dw_dma_chan *_dwc = to_dw_dma_chan(_chan); \
++ struct dma_slave_config *_sconfig = &_dwc->dma_sconfig; \
++ bool _is_slave = is_slave_direction(_dwc->direction); \
++ u8 _smsize = _is_slave ? _sconfig->src_maxburst : \
++ DW_DMA_MSIZE_16; \
++ u8 _dmsize = _is_slave ? _sconfig->dst_maxburst : \
++ DW_DMA_MSIZE_16; \
++ \
++ (DWC_CTLL_DST_MSIZE(_dmsize) \
++ | DWC_CTLL_SRC_MSIZE(_smsize) \
++ | DWC_CTLL_LLP_D_EN \
++ | DWC_CTLL_LLP_S_EN \
++ | DWC_CTLL_DMS(_dwc->dst_master) \
++ | DWC_CTLL_SMS(_dwc->src_master)); \
++ })
++
++/*
++ * Number of descriptors to allocate for each channel. This should be
++ * made configurable somehow; preferably, the clients (at least the
++ * ones using slave transfers) should be able to give us a hint.
++ */
++#define NR_DESCS_PER_CHANNEL 64
++
++/*----------------------------------------------------------------------*/
++
++static struct device *chan2dev(struct dma_chan *chan)
++{
++ return &chan->dev->device;
++}
++static struct device *chan2parent(struct dma_chan *chan)
++{
++ return chan->dev->device.parent;
++}
++
++static struct dw_desc *dwc_first_active(struct dw_dma_chan *dwc)
++{
++ return to_dw_desc(dwc->active_list.next);
++}
++
++static struct dw_desc *dwc_desc_get(struct dw_dma_chan *dwc)
++{
++ struct dw_desc *desc, *_desc;
++ struct dw_desc *ret = NULL;
++ unsigned int i = 0;
++ unsigned long flags;
++
++ spin_lock_irqsave(&dwc->lock, flags);
++ list_for_each_entry_safe(desc, _desc, &dwc->free_list, desc_node) {
++ i++;
++ if (async_tx_test_ack(&desc->txd)) {
++ list_del(&desc->desc_node);
++ ret = desc;
++ break;
++ }
++ dev_dbg(chan2dev(&dwc->chan), "desc %p not ACKed\n", desc);
++ }
++ spin_unlock_irqrestore(&dwc->lock, flags);
++
++ dev_vdbg(chan2dev(&dwc->chan), "scanned %u descriptors on freelist\n", i);
++
++ return ret;
++}
++
++/*
++ * Move a descriptor, including any children, to the free list.
++ * `desc' must not be on any lists.
++ */
++static void dwc_desc_put(struct dw_dma_chan *dwc, struct dw_desc *desc)
++{
++ unsigned long flags;
++
++ if (desc) {
++ struct dw_desc *child;
++
++ spin_lock_irqsave(&dwc->lock, flags);
++ list_for_each_entry(child, &desc->tx_list, desc_node)
++ dev_vdbg(chan2dev(&dwc->chan),
++ "moving child desc %p to freelist\n",
++ child);
++ list_splice_init(&desc->tx_list, &dwc->free_list);
++ dev_vdbg(chan2dev(&dwc->chan), "moving desc %p to freelist\n", desc);
++ list_add(&desc->desc_node, &dwc->free_list);
++ spin_unlock_irqrestore(&dwc->lock, flags);
++ }
++}
++
++static void dwc_initialize(struct dw_dma_chan *dwc)
++{
++ struct dw_dma *dw = to_dw_dma(dwc->chan.device);
++ struct dw_dma_slave *dws = dwc->chan.private;
++ u32 cfghi = DWC_CFGH_FIFO_MODE;
++ u32 cfglo = DWC_CFGL_CH_PRIOR(dwc->priority);
++
++ if (dwc->initialized == true)
++ return;
++
++ if (dws) {
++ /*
++ * We need controller-specific data to set up slave
++ * transfers.
++ */
++ BUG_ON(!dws->dma_dev || dws->dma_dev != dw->dma.dev);
++
++ cfghi = dws->cfg_hi;
++ cfglo |= dws->cfg_lo & ~DWC_CFGL_CH_PRIOR_MASK;
++ } else {
++ if (dwc->direction == DMA_MEM_TO_DEV)
++ cfghi = DWC_CFGH_DST_PER(dwc->request_line);
++ else if (dwc->direction == DMA_DEV_TO_MEM)
++ cfghi = DWC_CFGH_SRC_PER(dwc->request_line);
++ }
++
++ channel_writel(dwc, CFG_LO, cfglo);
++ channel_writel(dwc, CFG_HI, cfghi);
++
++ /* Enable interrupts */
++ channel_set_bit(dw, MASK.XFER, dwc->mask);
++ channel_set_bit(dw, MASK.ERROR, dwc->mask);
++
++ dwc->initialized = true;
++}
++
++/*----------------------------------------------------------------------*/
++
++static inline unsigned int dwc_fast_fls(unsigned long long v)
++{
++ /*
++ * We can be a lot more clever here, but this should take care
++ * of the most common optimization.
++ */
++ if (!(v & 7))
++ return 3;
++ else if (!(v & 3))
++ return 2;
++ else if (!(v & 1))
++ return 1;
++ return 0;
++}
++
++static inline void dwc_dump_chan_regs(struct dw_dma_chan *dwc)
++{
++ dev_err(chan2dev(&dwc->chan),
++ " SAR: 0x%x DAR: 0x%x LLP: 0x%x CTL: 0x%x:%08x\n",
++ channel_readl(dwc, SAR),
++ channel_readl(dwc, DAR),
++ channel_readl(dwc, LLP),
++ channel_readl(dwc, CTL_HI),
++ channel_readl(dwc, CTL_LO));
++}
++
++static inline void dwc_chan_disable(struct dw_dma *dw, struct dw_dma_chan *dwc)
++{
++ channel_clear_bit(dw, CH_EN, dwc->mask);
++ while (dma_readl(dw, CH_EN) & dwc->mask)
++ cpu_relax();
++}
++
++/*----------------------------------------------------------------------*/
++
++/* Perform single block transfer */
++static inline void dwc_do_single_block(struct dw_dma_chan *dwc,
++ struct dw_desc *desc)
++{
++ struct dw_dma *dw = to_dw_dma(dwc->chan.device);
++ u32 ctllo;
++
++ /* Software emulation of LLP mode relies on interrupts to continue
++ * multi block transfer. */
++ ctllo = desc->lli.ctllo | DWC_CTLL_INT_EN;
++
++ channel_writel(dwc, SAR, desc->lli.sar);
++ channel_writel(dwc, DAR, desc->lli.dar);
++ channel_writel(dwc, CTL_LO, ctllo);
++ channel_writel(dwc, CTL_HI, desc->lli.ctlhi);
++ channel_set_bit(dw, CH_EN, dwc->mask);
++
++ /* Move pointer to next descriptor */
++ dwc->tx_node_active = dwc->tx_node_active->next;
++}
++
++/* Called with dwc->lock held and bh disabled */
++static void dwc_dostart(struct dw_dma_chan *dwc, struct dw_desc *first)
++{
++ struct dw_dma *dw = to_dw_dma(dwc->chan.device);
++ unsigned long was_soft_llp;
++
++ /* ASSERT: channel is idle */
++ if (dma_readl(dw, CH_EN) & dwc->mask) {
++ dev_err(chan2dev(&dwc->chan),
++ "BUG: Attempted to start non-idle channel\n");
++ dwc_dump_chan_regs(dwc);
++
++ /* The tasklet will hopefully advance the queue... */
++ return;
++ }
++
++ if (dwc->nollp) {
++ was_soft_llp = test_and_set_bit(DW_DMA_IS_SOFT_LLP,
++ &dwc->flags);
++ if (was_soft_llp) {
++ dev_err(chan2dev(&dwc->chan),
++ "BUG: Attempted to start new LLP transfer "
++ "inside ongoing one\n");
++ return;
++ }
++
++ dwc_initialize(dwc);
++
++ dwc->residue = first->total_len;
++ dwc->tx_node_active = &first->tx_list;
++
++ /* Submit first block */
++ dwc_do_single_block(dwc, first);
++
++ return;
++ }
++
++ dwc_initialize(dwc);
++
++ channel_writel(dwc, LLP, first->txd.phys);
++ channel_writel(dwc, CTL_LO,
++ DWC_CTLL_LLP_D_EN | DWC_CTLL_LLP_S_EN);
++ channel_writel(dwc, CTL_HI, 0);
++ channel_set_bit(dw, CH_EN, dwc->mask);
++}
++
++/*----------------------------------------------------------------------*/
++
++static void
++dwc_descriptor_complete(struct dw_dma_chan *dwc, struct dw_desc *desc,
++ bool callback_required)
++{
++ dma_async_tx_callback callback = NULL;
++ void *param = NULL;
++ struct dma_async_tx_descriptor *txd = &desc->txd;
++ struct dw_desc *child;
++ unsigned long flags;
++
++ dev_vdbg(chan2dev(&dwc->chan), "descriptor %u complete\n", txd->cookie);
++
++ spin_lock_irqsave(&dwc->lock, flags);
++ dma_cookie_complete(txd);
++ if (callback_required) {
++ callback = txd->callback;
++ param = txd->callback_param;
++ }
++
++ /* async_tx_ack */
++ list_for_each_entry(child, &desc->tx_list, desc_node)
++ async_tx_ack(&child->txd);
++ async_tx_ack(&desc->txd);
++
++ list_splice_init(&desc->tx_list, &dwc->free_list);
++ list_move(&desc->desc_node, &dwc->free_list);
++
++ if (!is_slave_direction(dwc->direction)) {
++ struct device *parent = chan2parent(&dwc->chan);
++ if (!(txd->flags & DMA_COMPL_SKIP_DEST_UNMAP)) {
++ if (txd->flags & DMA_COMPL_DEST_UNMAP_SINGLE)
++ dma_unmap_single(parent, desc->lli.dar,
++ desc->total_len, DMA_FROM_DEVICE);
++ else
++ dma_unmap_page(parent, desc->lli.dar,
++ desc->total_len, DMA_FROM_DEVICE);
++ }
++ if (!(txd->flags & DMA_COMPL_SKIP_SRC_UNMAP)) {
++ if (txd->flags & DMA_COMPL_SRC_UNMAP_SINGLE)
++ dma_unmap_single(parent, desc->lli.sar,
++ desc->total_len, DMA_TO_DEVICE);
++ else
++ dma_unmap_page(parent, desc->lli.sar,
++ desc->total_len, DMA_TO_DEVICE);
++ }
++ }
++
++ spin_unlock_irqrestore(&dwc->lock, flags);
++
++ if (callback)
++ callback(param);
++}
++
++static void dwc_complete_all(struct dw_dma *dw, struct dw_dma_chan *dwc)
++{
++ struct dw_desc *desc, *_desc;
++ LIST_HEAD(list);
++ unsigned long flags;
++
++ spin_lock_irqsave(&dwc->lock, flags);
++ if (dma_readl(dw, CH_EN) & dwc->mask) {
++ dev_err(chan2dev(&dwc->chan),
++ "BUG: XFER bit set, but channel not idle!\n");
++
++ /* Try to continue after resetting the channel... */
++ dwc_chan_disable(dw, dwc);
++ }
++
++ /*
++ * Submit queued descriptors ASAP, i.e. before we go through
++ * the completed ones.
++ */
++ list_splice_init(&dwc->active_list, &list);
++ if (!list_empty(&dwc->queue)) {
++ list_move(dwc->queue.next, &dwc->active_list);
++ dwc_dostart(dwc, dwc_first_active(dwc));
++ }
++
++ spin_unlock_irqrestore(&dwc->lock, flags);
++
++ list_for_each_entry_safe(desc, _desc, &list, desc_node)
++ dwc_descriptor_complete(dwc, desc, true);
++}
++
++/* Returns how many bytes were already received from source */
++static inline u32 dwc_get_sent(struct dw_dma_chan *dwc)
++{
++ u32 ctlhi = channel_readl(dwc, CTL_HI);
++ u32 ctllo = channel_readl(dwc, CTL_LO);
++
++ return (ctlhi & DWC_CTLH_BLOCK_TS_MASK) * (1 << (ctllo >> 4 & 7));
++}
++
++static void dwc_scan_descriptors(struct dw_dma *dw, struct dw_dma_chan *dwc)
++{
++ dma_addr_t llp;
++ struct dw_desc *desc, *_desc;
++ struct dw_desc *child;
++ u32 status_xfer;
++ unsigned long flags;
++
++ spin_lock_irqsave(&dwc->lock, flags);
++ llp = channel_readl(dwc, LLP);
++ status_xfer = dma_readl(dw, RAW.XFER);
++
++ if (status_xfer & dwc->mask) {
++ /* Everything we've submitted is done */
++ dma_writel(dw, CLEAR.XFER, dwc->mask);
++
++ if (test_bit(DW_DMA_IS_SOFT_LLP, &dwc->flags)) {
++ struct list_head *head, *active = dwc->tx_node_active;
++
++ /*
++ * We are inside first active descriptor.
++ * Otherwise something is really wrong.
++ */
++ desc = dwc_first_active(dwc);
++
++ head = &desc->tx_list;
++ if (active != head) {
++ /* Update desc to reflect last sent one */
++ if (active != head->next)
++ desc = to_dw_desc(active->prev);
++
++ dwc->residue -= desc->len;
++
++ child = to_dw_desc(active);
++
++ /* Submit next block */
++ dwc_do_single_block(dwc, child);
++
++ spin_unlock_irqrestore(&dwc->lock, flags);
++ return;
++ }
++
++ /* We are done here */
++ clear_bit(DW_DMA_IS_SOFT_LLP, &dwc->flags);
++ }
++
++ dwc->residue = 0;
++
++ spin_unlock_irqrestore(&dwc->lock, flags);
++
++ dwc_complete_all(dw, dwc);
++ return;
++ }
++
++ if (list_empty(&dwc->active_list)) {
++ dwc->residue = 0;
++ spin_unlock_irqrestore(&dwc->lock, flags);
++ return;
++ }
++
++ if (test_bit(DW_DMA_IS_SOFT_LLP, &dwc->flags)) {
++ dev_vdbg(chan2dev(&dwc->chan), "%s: soft LLP mode\n", __func__);
++ spin_unlock_irqrestore(&dwc->lock, flags);
++ return;
++ }
++
++ dev_vdbg(chan2dev(&dwc->chan), "%s: llp=0x%llx\n", __func__,
++ (unsigned long long)llp);
++
++ list_for_each_entry_safe(desc, _desc, &dwc->active_list, desc_node) {
++ /* Initial residue value */
++ dwc->residue = desc->total_len;
++
++ /* Check first descriptors addr */
++ if (desc->txd.phys == llp) {
++ spin_unlock_irqrestore(&dwc->lock, flags);
++ return;
++ }
++
++ /* Check first descriptors llp */
++ if (desc->lli.llp == llp) {
++ /* This one is currently in progress */
++ dwc->residue -= dwc_get_sent(dwc);
++ spin_unlock_irqrestore(&dwc->lock, flags);
++ return;
++ }
++
++ dwc->residue -= desc->len;
++ list_for_each_entry(child, &desc->tx_list, desc_node) {
++ if (child->lli.llp == llp) {
++ /* Currently in progress */
++ dwc->residue -= dwc_get_sent(dwc);
++ spin_unlock_irqrestore(&dwc->lock, flags);
++ return;
++ }
++ dwc->residue -= child->len;
++ }
++
++ /*
++ * No descriptors so far seem to be in progress, i.e.
++ * this one must be done.
++ */
++ spin_unlock_irqrestore(&dwc->lock, flags);
++ dwc_descriptor_complete(dwc, desc, true);
++ spin_lock_irqsave(&dwc->lock, flags);
++ }
++
++ dev_err(chan2dev(&dwc->chan),
++ "BUG: All descriptors done, but channel not idle!\n");
++
++ /* Try to continue after resetting the channel... */
++ dwc_chan_disable(dw, dwc);
++
++ if (!list_empty(&dwc->queue)) {
++ list_move(dwc->queue.next, &dwc->active_list);
++ dwc_dostart(dwc, dwc_first_active(dwc));
++ }
++ spin_unlock_irqrestore(&dwc->lock, flags);
++}
++
++static inline void dwc_dump_lli(struct dw_dma_chan *dwc, struct dw_lli *lli)
++{
++ dev_crit(chan2dev(&dwc->chan), " desc: s0x%x d0x%x l0x%x c0x%x:%x\n",
++ lli->sar, lli->dar, lli->llp, lli->ctlhi, lli->ctllo);
++}
++
++static void dwc_handle_error(struct dw_dma *dw, struct dw_dma_chan *dwc)
++{
++ struct dw_desc *bad_desc;
++ struct dw_desc *child;
++ unsigned long flags;
++
++ dwc_scan_descriptors(dw, dwc);
++
++ spin_lock_irqsave(&dwc->lock, flags);
++
++ /*
++ * The descriptor currently at the head of the active list is
++ * borked. Since we don't have any way to report errors, we'll
++ * just have to scream loudly and try to carry on.
++ */
++ bad_desc = dwc_first_active(dwc);
++ list_del_init(&bad_desc->desc_node);
++ list_move(dwc->queue.next, dwc->active_list.prev);
++
++ /* Clear the error flag and try to restart the controller */
++ dma_writel(dw, CLEAR.ERROR, dwc->mask);
++ if (!list_empty(&dwc->active_list))
++ dwc_dostart(dwc, dwc_first_active(dwc));
++
++ /*
++ * WARN may seem harsh, but since this only happens
++ * when someone submits a bad physical address in a
++ * descriptor, we should consider ourselves lucky that the
++ * controller flagged an error instead of scribbling over
++ * random memory locations.
++ */
++ dev_WARN(chan2dev(&dwc->chan), "Bad descriptor submitted for DMA!\n"
++ " cookie: %d\n", bad_desc->txd.cookie);
++ dwc_dump_lli(dwc, &bad_desc->lli);
++ list_for_each_entry(child, &bad_desc->tx_list, desc_node)
++ dwc_dump_lli(dwc, &child->lli);
++
++ spin_unlock_irqrestore(&dwc->lock, flags);
++
++ /* Pretend the descriptor completed successfully */
++ dwc_descriptor_complete(dwc, bad_desc, true);
++}
++
++/* --------------------- Cyclic DMA API extensions -------------------- */
++
++dma_addr_t dw_dma_get_src_addr(struct dma_chan *chan)
++{
++ struct dw_dma_chan *dwc = to_dw_dma_chan(chan);
++ return channel_readl(dwc, SAR);
++}
++EXPORT_SYMBOL(dw_dma_get_src_addr);
++
++dma_addr_t dw_dma_get_dst_addr(struct dma_chan *chan)
++{
++ struct dw_dma_chan *dwc = to_dw_dma_chan(chan);
++ return channel_readl(dwc, DAR);
++}
++EXPORT_SYMBOL(dw_dma_get_dst_addr);
++
++/* Called with dwc->lock held and all DMAC interrupts disabled */
++static void dwc_handle_cyclic(struct dw_dma *dw, struct dw_dma_chan *dwc,
++ u32 status_err, u32 status_xfer)
++{
++ unsigned long flags;
++
++ if (dwc->mask) {
++ void (*callback)(void *param);
++ void *callback_param;
++
++ dev_vdbg(chan2dev(&dwc->chan), "new cyclic period llp 0x%08x\n",
++ channel_readl(dwc, LLP));
++
++ callback = dwc->cdesc->period_callback;
++ callback_param = dwc->cdesc->period_callback_param;
++
++ if (callback)
++ callback(callback_param);
++ }
++
++ /*
++ * Error and transfer complete are highly unlikely, and will most
++ * likely be due to a configuration error by the user.
++ */
++ if (unlikely(status_err & dwc->mask) ||
++ unlikely(status_xfer & dwc->mask)) {
++ int i;
++
++ dev_err(chan2dev(&dwc->chan), "cyclic DMA unexpected %s "
++ "interrupt, stopping DMA transfer\n",
++ status_xfer ? "xfer" : "error");
++
++ spin_lock_irqsave(&dwc->lock, flags);
++
++ dwc_dump_chan_regs(dwc);
++
++ dwc_chan_disable(dw, dwc);
++
++ /* Make sure DMA does not restart by loading a new list */
++ channel_writel(dwc, LLP, 0);
++ channel_writel(dwc, CTL_LO, 0);
++ channel_writel(dwc, CTL_HI, 0);
++
++ dma_writel(dw, CLEAR.ERROR, dwc->mask);
++ dma_writel(dw, CLEAR.XFER, dwc->mask);
++
++ for (i = 0; i < dwc->cdesc->periods; i++)
++ dwc_dump_lli(dwc, &dwc->cdesc->desc[i]->lli);
++
++ spin_unlock_irqrestore(&dwc->lock, flags);
++ }
++}
++
++/* ------------------------------------------------------------------------- */
++
++static void dw_dma_tasklet(unsigned long data)
++{
++ struct dw_dma *dw = (struct dw_dma *)data;
++ struct dw_dma_chan *dwc;
++ u32 status_xfer;
++ u32 status_err;
++ int i;
++
++ status_xfer = dma_readl(dw, RAW.XFER);
++ status_err = dma_readl(dw, RAW.ERROR);
++
++ dev_vdbg(dw->dma.dev, "%s: status_err=%x\n", __func__, status_err);
++
++ for (i = 0; i < dw->dma.chancnt; i++) {
++ dwc = &dw->chan[i];
++ if (test_bit(DW_DMA_IS_CYCLIC, &dwc->flags))
++ dwc_handle_cyclic(dw, dwc, status_err, status_xfer);
++ else if (status_err & (1 << i))
++ dwc_handle_error(dw, dwc);
++ else if (status_xfer & (1 << i))
++ dwc_scan_descriptors(dw, dwc);
++ }
++
++ /*
++ * Re-enable interrupts.
++ */
++ channel_set_bit(dw, MASK.XFER, dw->all_chan_mask);
++ channel_set_bit(dw, MASK.ERROR, dw->all_chan_mask);
++}
++
++static irqreturn_t dw_dma_interrupt(int irq, void *dev_id)
++{
++ struct dw_dma *dw = dev_id;
++ u32 status;
++
++ dev_vdbg(dw->dma.dev, "%s: status=0x%x\n", __func__,
++ dma_readl(dw, STATUS_INT));
++
++ /*
++ * Just disable the interrupts. We'll turn them back on in the
++ * softirq handler.
++ */
++ channel_clear_bit(dw, MASK.XFER, dw->all_chan_mask);
++ channel_clear_bit(dw, MASK.ERROR, dw->all_chan_mask);
++
++ status = dma_readl(dw, STATUS_INT);
++ if (status) {
++ dev_err(dw->dma.dev,
++ "BUG: Unexpected interrupts pending: 0x%x\n",
++ status);
++
++ /* Try to recover */
++ channel_clear_bit(dw, MASK.XFER, (1 << 8) - 1);
++ channel_clear_bit(dw, MASK.SRC_TRAN, (1 << 8) - 1);
++ channel_clear_bit(dw, MASK.DST_TRAN, (1 << 8) - 1);
++ channel_clear_bit(dw, MASK.ERROR, (1 << 8) - 1);
++ }
++
++ tasklet_schedule(&dw->tasklet);
++
++ return IRQ_HANDLED;
++}
++
++/*----------------------------------------------------------------------*/
++
++static dma_cookie_t dwc_tx_submit(struct dma_async_tx_descriptor *tx)
++{
++ struct dw_desc *desc = txd_to_dw_desc(tx);
++ struct dw_dma_chan *dwc = to_dw_dma_chan(tx->chan);
++ dma_cookie_t cookie;
++ unsigned long flags;
++
++ spin_lock_irqsave(&dwc->lock, flags);
++ cookie = dma_cookie_assign(tx);
++
++ /*
++ * REVISIT: We should attempt to chain as many descriptors as
++ * possible, perhaps even appending to those already submitted
++ * for DMA. But this is hard to do in a race-free manner.
++ */
++ if (list_empty(&dwc->active_list)) {
++ dev_vdbg(chan2dev(tx->chan), "%s: started %u\n", __func__,
++ desc->txd.cookie);
++ list_add_tail(&desc->desc_node, &dwc->active_list);
++ dwc_dostart(dwc, dwc_first_active(dwc));
++ } else {
++ dev_vdbg(chan2dev(tx->chan), "%s: queued %u\n", __func__,
++ desc->txd.cookie);
++
++ list_add_tail(&desc->desc_node, &dwc->queue);
++ }
++
++ spin_unlock_irqrestore(&dwc->lock, flags);
++
++ return cookie;
++}
++
++static struct dma_async_tx_descriptor *
++dwc_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dest, dma_addr_t src,
++ size_t len, unsigned long flags)
++{
++ struct dw_dma_chan *dwc = to_dw_dma_chan(chan);
++ struct dw_dma *dw = to_dw_dma(chan->device);
++ struct dw_desc *desc;
++ struct dw_desc *first;
++ struct dw_desc *prev;
++ size_t xfer_count;
++ size_t offset;
++ unsigned int src_width;
++ unsigned int dst_width;
++ unsigned int data_width;
++ u32 ctllo;
++
++ dev_vdbg(chan2dev(chan),
++ "%s: d0x%llx s0x%llx l0x%zx f0x%lx\n", __func__,
++ (unsigned long long)dest, (unsigned long long)src,
++ len, flags);
++
++ if (unlikely(!len)) {
++ dev_dbg(chan2dev(chan), "%s: length is zero!\n", __func__);
++ return NULL;
++ }
++
++ dwc->direction = DMA_MEM_TO_MEM;
++
++ data_width = min_t(unsigned int, dw->data_width[dwc->src_master],
++ dw->data_width[dwc->dst_master]);
++
++ src_width = dst_width = min_t(unsigned int, data_width,
++ dwc_fast_fls(src | dest | len));
++
++ ctllo = DWC_DEFAULT_CTLLO(chan)
++ | DWC_CTLL_DST_WIDTH(dst_width)
++ | DWC_CTLL_SRC_WIDTH(src_width)
++ | DWC_CTLL_DST_INC
++ | DWC_CTLL_SRC_INC
++ | DWC_CTLL_FC_M2M;
++ prev = first = NULL;
++
++ for (offset = 0; offset < len; offset += xfer_count << src_width) {
++ xfer_count = min_t(size_t, (len - offset) >> src_width,
++ dwc->block_size);
++
++ desc = dwc_desc_get(dwc);
++ if (!desc)
++ goto err_desc_get;
++
++ desc->lli.sar = src + offset;
++ desc->lli.dar = dest + offset;
++ desc->lli.ctllo = ctllo;
++ desc->lli.ctlhi = xfer_count;
++ desc->len = xfer_count << src_width;
++
++ if (!first) {
++ first = desc;
++ } else {
++ prev->lli.llp = desc->txd.phys;
++ list_add_tail(&desc->desc_node,
++ &first->tx_list);
++ }
++ prev = desc;
++ }
++
++ if (flags & DMA_PREP_INTERRUPT)
++ /* Trigger interrupt after last block */
++ prev->lli.ctllo |= DWC_CTLL_INT_EN;
++
++ prev->lli.llp = 0;
++ first->txd.flags = flags;
++ first->total_len = len;
++
++ return &first->txd;
++
++err_desc_get:
++ dwc_desc_put(dwc, first);
++ return NULL;
++}
++
++static struct dma_async_tx_descriptor *
++dwc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
++ unsigned int sg_len, enum dma_transfer_direction direction,
++ unsigned long flags, void *context)
++{
++ struct dw_dma_chan *dwc = to_dw_dma_chan(chan);
++ struct dw_dma *dw = to_dw_dma(chan->device);
++ struct dma_slave_config *sconfig = &dwc->dma_sconfig;
++ struct dw_desc *prev;
++ struct dw_desc *first;
++ u32 ctllo;
++ dma_addr_t reg;
++ unsigned int reg_width;
++ unsigned int mem_width;
++ unsigned int data_width;
++ unsigned int i;
++ struct scatterlist *sg;
++ size_t total_len = 0;
++
++ dev_vdbg(chan2dev(chan), "%s\n", __func__);
++
++ if (unlikely(!is_slave_direction(direction) || !sg_len))
++ return NULL;
++
++ dwc->direction = direction;
++
++ prev = first = NULL;
++
++ switch (direction) {
++ case DMA_MEM_TO_DEV:
++ reg_width = __fls(sconfig->dst_addr_width);
++ reg = sconfig->dst_addr;
++ ctllo = (DWC_DEFAULT_CTLLO(chan)
++ | DWC_CTLL_DST_WIDTH(reg_width)
++ | DWC_CTLL_DST_FIX
++ | DWC_CTLL_SRC_INC);
++
++ ctllo |= sconfig->device_fc ? DWC_CTLL_FC(DW_DMA_FC_P_M2P) :
++ DWC_CTLL_FC(DW_DMA_FC_D_M2P);
++
++ data_width = dw->data_width[dwc->src_master];
++
++ for_each_sg(sgl, sg, sg_len, i) {
++ struct dw_desc *desc;
++ u32 len, dlen, mem;
++
++ mem = sg_dma_address(sg);
++ len = sg_dma_len(sg);
++
++ mem_width = min_t(unsigned int,
++ data_width, dwc_fast_fls(mem | len));
++
++slave_sg_todev_fill_desc:
++ desc = dwc_desc_get(dwc);
++ if (!desc) {
++ dev_err(chan2dev(chan),
++ "not enough descriptors available\n");
++ goto err_desc_get;
++ }
++
++ desc->lli.sar = mem;
++ desc->lli.dar = reg;
++ desc->lli.ctllo = ctllo | DWC_CTLL_SRC_WIDTH(mem_width);
++ if ((len >> mem_width) > dwc->block_size) {
++ dlen = dwc->block_size << mem_width;
++ mem += dlen;
++ len -= dlen;
++ } else {
++ dlen = len;
++ len = 0;
++ }
++
++ desc->lli.ctlhi = dlen >> mem_width;
++ desc->len = dlen;
++
++ if (!first) {
++ first = desc;
++ } else {
++ prev->lli.llp = desc->txd.phys;
++ list_add_tail(&desc->desc_node,
++ &first->tx_list);
++ }
++ prev = desc;
++ total_len += dlen;
++
++ if (len)
++ goto slave_sg_todev_fill_desc;
++ }
++ break;
++ case DMA_DEV_TO_MEM:
++ reg_width = __fls(sconfig->src_addr_width);
++ reg = sconfig->src_addr;
++ ctllo = (DWC_DEFAULT_CTLLO(chan)
++ | DWC_CTLL_SRC_WIDTH(reg_width)
++ | DWC_CTLL_DST_INC
++ | DWC_CTLL_SRC_FIX);
++
++ ctllo |= sconfig->device_fc ? DWC_CTLL_FC(DW_DMA_FC_P_P2M) :
++ DWC_CTLL_FC(DW_DMA_FC_D_P2M);
++
++ data_width = dw->data_width[dwc->dst_master];
++
++ for_each_sg(sgl, sg, sg_len, i) {
++ struct dw_desc *desc;
++ u32 len, dlen, mem;
++
++ mem = sg_dma_address(sg);
++ len = sg_dma_len(sg);
++
++ mem_width = min_t(unsigned int,
++ data_width, dwc_fast_fls(mem | len));
++
++slave_sg_fromdev_fill_desc:
++ desc = dwc_desc_get(dwc);
++ if (!desc) {
++ dev_err(chan2dev(chan),
++ "not enough descriptors available\n");
++ goto err_desc_get;
++ }
++
++ desc->lli.sar = reg;
++ desc->lli.dar = mem;
++ desc->lli.ctllo = ctllo | DWC_CTLL_DST_WIDTH(mem_width);
++ if ((len >> reg_width) > dwc->block_size) {
++ dlen = dwc->block_size << reg_width;
++ mem += dlen;
++ len -= dlen;
++ } else {
++ dlen = len;
++ len = 0;
++ }
++ desc->lli.ctlhi = dlen >> reg_width;
++ desc->len = dlen;
++
++ if (!first) {
++ first = desc;
++ } else {
++ prev->lli.llp = desc->txd.phys;
++ list_add_tail(&desc->desc_node,
++ &first->tx_list);
++ }
++ prev = desc;
++ total_len += dlen;
++
++ if (len)
++ goto slave_sg_fromdev_fill_desc;
++ }
++ break;
++ default:
++ return NULL;
++ }
++
++ if (flags & DMA_PREP_INTERRUPT)
++ /* Trigger interrupt after last block */
++ prev->lli.ctllo |= DWC_CTLL_INT_EN;
++
++ prev->lli.llp = 0;
++ first->total_len = total_len;
++
++ return &first->txd;
++
++err_desc_get:
++ dwc_desc_put(dwc, first);
++ return NULL;
++}
++
++/*
++ * Fix sconfig's burst size according to dw_dmac. We need to convert them as:
++ * 1 -> 0, 4 -> 1, 8 -> 2, 16 -> 3.
++ *
++ * NOTE: burst size 2 is not supported by controller.
++ *
++ * This can be done by finding least significant bit set: n & (n - 1)
++ */
++static inline void convert_burst(u32 *maxburst)
++{
++ if (*maxburst > 1)
++ *maxburst = fls(*maxburst) - 2;
++ else
++ *maxburst = 0;
++}
++
++static int
++set_runtime_config(struct dma_chan *chan, struct dma_slave_config *sconfig)
++{
++ struct dw_dma_chan *dwc = to_dw_dma_chan(chan);
++
++ /* Check if chan will be configured for slave transfers */
++ if (!is_slave_direction(sconfig->direction))
++ return -EINVAL;
++
++ memcpy(&dwc->dma_sconfig, sconfig, sizeof(*sconfig));
++ dwc->direction = sconfig->direction;
++
++ /* Take the request line from slave_id member */
++ if (dwc->request_line == ~0)
++ dwc->request_line = sconfig->slave_id;
++
++ convert_burst(&dwc->dma_sconfig.src_maxburst);
++ convert_burst(&dwc->dma_sconfig.dst_maxburst);
++
++ return 0;
++}
++
++static inline void dwc_chan_pause(struct dw_dma_chan *dwc)
++{
++ u32 cfglo = channel_readl(dwc, CFG_LO);
++ unsigned int count = 20; /* timeout iterations */
++
++ channel_writel(dwc, CFG_LO, cfglo | DWC_CFGL_CH_SUSP);
++ while (!(channel_readl(dwc, CFG_LO) & DWC_CFGL_FIFO_EMPTY) && count--)
++ udelay(2);
++
++ dwc->paused = true;
++}
++
++static inline void dwc_chan_resume(struct dw_dma_chan *dwc)
++{
++ u32 cfglo = channel_readl(dwc, CFG_LO);
++
++ channel_writel(dwc, CFG_LO, cfglo & ~DWC_CFGL_CH_SUSP);
++
++ dwc->paused = false;
++}
++
++static int dwc_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
++ unsigned long arg)
++{
++ struct dw_dma_chan *dwc = to_dw_dma_chan(chan);
++ struct dw_dma *dw = to_dw_dma(chan->device);
++ struct dw_desc *desc, *_desc;
++ unsigned long flags;
++ LIST_HEAD(list);
++
++ if (cmd == DMA_PAUSE) {
++ spin_lock_irqsave(&dwc->lock, flags);
++
++ dwc_chan_pause(dwc);
++
++ spin_unlock_irqrestore(&dwc->lock, flags);
++ } else if (cmd == DMA_RESUME) {
++ if (!dwc->paused)
++ return 0;
++
++ spin_lock_irqsave(&dwc->lock, flags);
++
++ dwc_chan_resume(dwc);
++
++ spin_unlock_irqrestore(&dwc->lock, flags);
++ } else if (cmd == DMA_TERMINATE_ALL) {
++ spin_lock_irqsave(&dwc->lock, flags);
++
++ clear_bit(DW_DMA_IS_SOFT_LLP, &dwc->flags);
++
++ dwc_chan_disable(dw, dwc);
++
++ dwc_chan_resume(dwc);
++
++ /* active_list entries will end up before queued entries */
++ list_splice_init(&dwc->queue, &list);
++ list_splice_init(&dwc->active_list, &list);
++
++ spin_unlock_irqrestore(&dwc->lock, flags);
++
++ /* Flush all pending and queued descriptors */
++ list_for_each_entry_safe(desc, _desc, &list, desc_node)
++ dwc_descriptor_complete(dwc, desc, false);
++ } else if (cmd == DMA_SLAVE_CONFIG) {
++ return set_runtime_config(chan, (struct dma_slave_config *)arg);
++ } else {
++ return -ENXIO;
++ }
++
++ return 0;
++}
++
++static inline u32 dwc_get_residue(struct dw_dma_chan *dwc)
++{
++ unsigned long flags;
++ u32 residue;
++
++ spin_lock_irqsave(&dwc->lock, flags);
++
++ residue = dwc->residue;
++ if (test_bit(DW_DMA_IS_SOFT_LLP, &dwc->flags) && residue)
++ residue -= dwc_get_sent(dwc);
++
++ spin_unlock_irqrestore(&dwc->lock, flags);
++ return residue;
++}
++
++static enum dma_status
++dwc_tx_status(struct dma_chan *chan,
++ dma_cookie_t cookie,
++ struct dma_tx_state *txstate)
++{
++ struct dw_dma_chan *dwc = to_dw_dma_chan(chan);
++ enum dma_status ret;
++
++ ret = dma_cookie_status(chan, cookie, txstate);
++ if (ret != DMA_SUCCESS) {
++ dwc_scan_descriptors(to_dw_dma(chan->device), dwc);
++
++ ret = dma_cookie_status(chan, cookie, txstate);
++ }
++
++ if (ret != DMA_SUCCESS)
++ dma_set_residue(txstate, dwc_get_residue(dwc));
++
++ if (dwc->paused)
++ return DMA_PAUSED;
++
++ return ret;
++}
++
++static void dwc_issue_pending(struct dma_chan *chan)
++{
++ struct dw_dma_chan *dwc = to_dw_dma_chan(chan);
++
++ if (!list_empty(&dwc->queue))
++ dwc_scan_descriptors(to_dw_dma(chan->device), dwc);
++}
++
++static int dwc_alloc_chan_resources(struct dma_chan *chan)
++{
++ struct dw_dma_chan *dwc = to_dw_dma_chan(chan);
++ struct dw_dma *dw = to_dw_dma(chan->device);
++ struct dw_desc *desc;
++ int i;
++ unsigned long flags;
++
++ dev_vdbg(chan2dev(chan), "%s\n", __func__);
++
++ /* ASSERT: channel is idle */
++ if (dma_readl(dw, CH_EN) & dwc->mask) {
++ dev_dbg(chan2dev(chan), "DMA channel not idle?\n");
++ return -EIO;
++ }
++
++ dma_cookie_init(chan);
++
++ /*
++ * NOTE: some controllers may have additional features that we
++ * need to initialize here, like "scatter-gather" (which
++ * doesn't mean what you think it means), and status writeback.
++ */
++
++ dwc_set_masters(dwc);
++
++ spin_lock_irqsave(&dwc->lock, flags);
++ i = dwc->descs_allocated;
++ while (dwc->descs_allocated < NR_DESCS_PER_CHANNEL) {
++ dma_addr_t phys;
++
++ spin_unlock_irqrestore(&dwc->lock, flags);
++
++ desc = dma_pool_alloc(dw->desc_pool, GFP_ATOMIC, &phys);
++ if (!desc)
++ goto err_desc_alloc;
++
++ memset(desc, 0, sizeof(struct dw_desc));
++
++ INIT_LIST_HEAD(&desc->tx_list);
++ dma_async_tx_descriptor_init(&desc->txd, chan);
++ desc->txd.tx_submit = dwc_tx_submit;
++ desc->txd.flags = DMA_CTRL_ACK;
++ desc->txd.phys = phys;
++
++ dwc_desc_put(dwc, desc);
++
++ spin_lock_irqsave(&dwc->lock, flags);
++ i = ++dwc->descs_allocated;
++ }
++
++ spin_unlock_irqrestore(&dwc->lock, flags);
++
++ dev_dbg(chan2dev(chan), "%s: allocated %d descriptors\n", __func__, i);
++
++ return i;
++
++err_desc_alloc:
++ dev_info(chan2dev(chan), "only allocated %d descriptors\n", i);
++
++ return i;
++}
++
++static void dwc_free_chan_resources(struct dma_chan *chan)
++{
++ struct dw_dma_chan *dwc = to_dw_dma_chan(chan);
++ struct dw_dma *dw = to_dw_dma(chan->device);
++ struct dw_desc *desc, *_desc;
++ unsigned long flags;
++ LIST_HEAD(list);
++
++ dev_dbg(chan2dev(chan), "%s: descs allocated=%u\n", __func__,
++ dwc->descs_allocated);
++
++ /* ASSERT: channel is idle */
++ BUG_ON(!list_empty(&dwc->active_list));
++ BUG_ON(!list_empty(&dwc->queue));
++ BUG_ON(dma_readl(to_dw_dma(chan->device), CH_EN) & dwc->mask);
++
++ spin_lock_irqsave(&dwc->lock, flags);
++ list_splice_init(&dwc->free_list, &list);
++ dwc->descs_allocated = 0;
++ dwc->initialized = false;
++ dwc->request_line = ~0;
++
++ /* Disable interrupts */
++ channel_clear_bit(dw, MASK.XFER, dwc->mask);
++ channel_clear_bit(dw, MASK.ERROR, dwc->mask);
++
++ spin_unlock_irqrestore(&dwc->lock, flags);
++
++ list_for_each_entry_safe(desc, _desc, &list, desc_node) {
++ dev_vdbg(chan2dev(chan), " freeing descriptor %p\n", desc);
++ dma_pool_free(dw->desc_pool, desc, desc->txd.phys);
++ }
++
++ dev_vdbg(chan2dev(chan), "%s: done\n", __func__);
++}
++
++/*----------------------------------------------------------------------*/
++
++struct dw_dma_of_filter_args {
++ struct dw_dma *dw;
++ unsigned int req;
++ unsigned int src;
++ unsigned int dst;
++};
++
++static bool dw_dma_of_filter(struct dma_chan *chan, void *param)
++{
++ struct dw_dma_chan *dwc = to_dw_dma_chan(chan);
++ struct dw_dma_of_filter_args *fargs = param;
++
++ /* Ensure the device matches our channel */
++ if (chan->device != &fargs->dw->dma)
++ return false;
++
++ dwc->request_line = fargs->req;
++ dwc->src_master = fargs->src;
++ dwc->dst_master = fargs->dst;
++
++ return true;
++}
++
++static struct dma_chan *dw_dma_of_xlate(struct of_phandle_args *dma_spec,
++ struct of_dma *ofdma)
++{
++ struct dw_dma *dw = ofdma->of_dma_data;
++ struct dw_dma_of_filter_args fargs = {
++ .dw = dw,
++ };
++ dma_cap_mask_t cap;
++
++ if (dma_spec->args_count != 3)
++ return NULL;
++
++ fargs.req = dma_spec->args[0];
++ fargs.src = dma_spec->args[1];
++ fargs.dst = dma_spec->args[2];
++
++ if (WARN_ON(fargs.req >= DW_DMA_MAX_NR_REQUESTS ||
++ fargs.src >= dw->nr_masters ||
++ fargs.dst >= dw->nr_masters))
++ return NULL;
++
++ dma_cap_zero(cap);
++ dma_cap_set(DMA_SLAVE, cap);
++
++ /* TODO: there should be a simpler way to do this */
++ return dma_request_channel(cap, dw_dma_of_filter, &fargs);
++}
++
++#ifdef CONFIG_ACPI
++static bool dw_dma_acpi_filter(struct dma_chan *chan, void *param)
++{
++ struct dw_dma_chan *dwc = to_dw_dma_chan(chan);
++ struct acpi_dma_spec *dma_spec = param;
++
++ if (chan->device->dev != dma_spec->dev ||
++ chan->chan_id != dma_spec->chan_id)
++ return false;
++
++ dwc->request_line = dma_spec->slave_id;
++ dwc->src_master = dwc_get_sms(NULL);
++ dwc->dst_master = dwc_get_dms(NULL);
++
++ return true;
++}
++
++static void dw_dma_acpi_controller_register(struct dw_dma *dw)
++{
++ struct device *dev = dw->dma.dev;
++ struct acpi_dma_filter_info *info;
++ int ret;
++
++ info = devm_kzalloc(dev, sizeof(*info), GFP_KERNEL);
++ if (!info)
++ return;
++
++ dma_cap_zero(info->dma_cap);
++ dma_cap_set(DMA_SLAVE, info->dma_cap);
++ info->filter_fn = dw_dma_acpi_filter;
++
++ ret = devm_acpi_dma_controller_register(dev, acpi_dma_simple_xlate,
++ info);
++ if (ret)
++ dev_err(dev, "could not register acpi_dma_controller\n");
++}
++#else /* !CONFIG_ACPI */
++static inline void dw_dma_acpi_controller_register(struct dw_dma *dw) {}
++#endif /* !CONFIG_ACPI */
++
++/* --------------------- Cyclic DMA API extensions -------------------- */
++
++/**
++ * dw_dma_cyclic_start - start the cyclic DMA transfer
++ * @chan: the DMA channel to start
++ *
++ * Must be called with soft interrupts disabled. Returns zero on success or
++ * -errno on failure.
++ */
++int dw_dma_cyclic_start(struct dma_chan *chan)
++{
++ struct dw_dma_chan *dwc = to_dw_dma_chan(chan);
++ struct dw_dma *dw = to_dw_dma(dwc->chan.device);
++ unsigned long flags;
++
++ if (!test_bit(DW_DMA_IS_CYCLIC, &dwc->flags)) {
++ dev_err(chan2dev(&dwc->chan), "missing prep for cyclic DMA\n");
++ return -ENODEV;
++ }
++
++ spin_lock_irqsave(&dwc->lock, flags);
++
++ /* Assert channel is idle */
++ if (dma_readl(dw, CH_EN) & dwc->mask) {
++ dev_err(chan2dev(&dwc->chan),
++ "BUG: Attempted to start non-idle channel\n");
++ dwc_dump_chan_regs(dwc);
++ spin_unlock_irqrestore(&dwc->lock, flags);
++ return -EBUSY;
++ }
++
++ dma_writel(dw, CLEAR.ERROR, dwc->mask);
++ dma_writel(dw, CLEAR.XFER, dwc->mask);
++
++ /* Setup DMAC channel registers */
++ channel_writel(dwc, LLP, dwc->cdesc->desc[0]->txd.phys);
++ channel_writel(dwc, CTL_LO, DWC_CTLL_LLP_D_EN | DWC_CTLL_LLP_S_EN);
++ channel_writel(dwc, CTL_HI, 0);
++
++ channel_set_bit(dw, CH_EN, dwc->mask);
++
++ spin_unlock_irqrestore(&dwc->lock, flags);
++
++ return 0;
++}
++EXPORT_SYMBOL(dw_dma_cyclic_start);
++
++/**
++ * dw_dma_cyclic_stop - stop the cyclic DMA transfer
++ * @chan: the DMA channel to stop
++ *
++ * Must be called with soft interrupts disabled.
++ */
++void dw_dma_cyclic_stop(struct dma_chan *chan)
++{
++ struct dw_dma_chan *dwc = to_dw_dma_chan(chan);
++ struct dw_dma *dw = to_dw_dma(dwc->chan.device);
++ unsigned long flags;
++
++ spin_lock_irqsave(&dwc->lock, flags);
++
++ dwc_chan_disable(dw, dwc);
++
++ spin_unlock_irqrestore(&dwc->lock, flags);
++}
++EXPORT_SYMBOL(dw_dma_cyclic_stop);
++
++/**
++ * dw_dma_cyclic_prep - prepare the cyclic DMA transfer
++ * @chan: the DMA channel to prepare
++ * @buf_addr: physical DMA address where the buffer starts
++ * @buf_len: total number of bytes for the entire buffer
++ * @period_len: number of bytes for each period
++ * @direction: transfer direction, to or from device
++ *
++ * Must be called before trying to start the transfer. Returns a valid struct
++ * dw_cyclic_desc if successful or an ERR_PTR(-errno) if not successful.
++ */
++struct dw_cyclic_desc *dw_dma_cyclic_prep(struct dma_chan *chan,
++ dma_addr_t buf_addr, size_t buf_len, size_t period_len,
++ enum dma_transfer_direction direction)
++{
++ struct dw_dma_chan *dwc = to_dw_dma_chan(chan);
++ struct dma_slave_config *sconfig = &dwc->dma_sconfig;
++ struct dw_cyclic_desc *cdesc;
++ struct dw_cyclic_desc *retval = NULL;
++ struct dw_desc *desc;
++ struct dw_desc *last = NULL;
++ unsigned long was_cyclic;
++ unsigned int reg_width;
++ unsigned int periods;
++ unsigned int i;
++ unsigned long flags;
++
++ spin_lock_irqsave(&dwc->lock, flags);
++ if (dwc->nollp) {
++ spin_unlock_irqrestore(&dwc->lock, flags);
++ dev_dbg(chan2dev(&dwc->chan),
++ "channel doesn't support LLP transfers\n");
++ return ERR_PTR(-EINVAL);
++ }
++
++ if (!list_empty(&dwc->queue) || !list_empty(&dwc->active_list)) {
++ spin_unlock_irqrestore(&dwc->lock, flags);
++ dev_dbg(chan2dev(&dwc->chan),
++ "queue and/or active list are not empty\n");
++ return ERR_PTR(-EBUSY);
++ }
++
++ was_cyclic = test_and_set_bit(DW_DMA_IS_CYCLIC, &dwc->flags);
++ spin_unlock_irqrestore(&dwc->lock, flags);
++ if (was_cyclic) {
++ dev_dbg(chan2dev(&dwc->chan),
++ "channel already prepared for cyclic DMA\n");
++ return ERR_PTR(-EBUSY);
++ }
++
++ retval = ERR_PTR(-EINVAL);
++
++ if (unlikely(!is_slave_direction(direction)))
++ goto out_err;
++
++ dwc->direction = direction;
++
++ if (direction == DMA_MEM_TO_DEV)
++ reg_width = __ffs(sconfig->dst_addr_width);
++ else
++ reg_width = __ffs(sconfig->src_addr_width);
++
++ periods = buf_len / period_len;
++
++ /* Check for too big/unaligned periods and unaligned DMA buffer. */
++ if (period_len > (dwc->block_size << reg_width))
++ goto out_err;
++ if (unlikely(period_len & ((1 << reg_width) - 1)))
++ goto out_err;
++ if (unlikely(buf_addr & ((1 << reg_width) - 1)))
++ goto out_err;
++
++ retval = ERR_PTR(-ENOMEM);
++
++ if (periods > NR_DESCS_PER_CHANNEL)
++ goto out_err;
++
++ cdesc = kzalloc(sizeof(struct dw_cyclic_desc), GFP_KERNEL);
++ if (!cdesc)
++ goto out_err;
++
++ cdesc->desc = kzalloc(sizeof(struct dw_desc *) * periods, GFP_KERNEL);
++ if (!cdesc->desc)
++ goto out_err_alloc;
++
++ for (i = 0; i < periods; i++) {
++ desc = dwc_desc_get(dwc);
++ if (!desc)
++ goto out_err_desc_get;
++
++ switch (direction) {
++ case DMA_MEM_TO_DEV:
++ desc->lli.dar = sconfig->dst_addr;
++ desc->lli.sar = buf_addr + (period_len * i);
++ desc->lli.ctllo = (DWC_DEFAULT_CTLLO(chan)
++ | DWC_CTLL_DST_WIDTH(reg_width)
++ | DWC_CTLL_SRC_WIDTH(reg_width)
++ | DWC_CTLL_DST_FIX
++ | DWC_CTLL_SRC_INC
++ | DWC_CTLL_INT_EN);
++
++ desc->lli.ctllo |= sconfig->device_fc ?
++ DWC_CTLL_FC(DW_DMA_FC_P_M2P) :
++ DWC_CTLL_FC(DW_DMA_FC_D_M2P);
++
++ break;
++ case DMA_DEV_TO_MEM:
++ desc->lli.dar = buf_addr + (period_len * i);
++ desc->lli.sar = sconfig->src_addr;
++ desc->lli.ctllo = (DWC_DEFAULT_CTLLO(chan)
++ | DWC_CTLL_SRC_WIDTH(reg_width)
++ | DWC_CTLL_DST_WIDTH(reg_width)
++ | DWC_CTLL_DST_INC
++ | DWC_CTLL_SRC_FIX
++ | DWC_CTLL_INT_EN);
++
++ desc->lli.ctllo |= sconfig->device_fc ?
++ DWC_CTLL_FC(DW_DMA_FC_P_P2M) :
++ DWC_CTLL_FC(DW_DMA_FC_D_P2M);
++
++ break;
++ default:
++ break;
++ }
++
++ desc->lli.ctlhi = (period_len >> reg_width);
++ cdesc->desc[i] = desc;
++
++ if (last)
++ last->lli.llp = desc->txd.phys;
++
++ last = desc;
++ }
++
++ /* Let's make a cyclic list */
++ last->lli.llp = cdesc->desc[0]->txd.phys;
++
++ dev_dbg(chan2dev(&dwc->chan), "cyclic prepared buf 0x%llx len %zu "
++ "period %zu periods %d\n", (unsigned long long)buf_addr,
++ buf_len, period_len, periods);
++
++ cdesc->periods = periods;
++ dwc->cdesc = cdesc;
++
++ return cdesc;
++
++out_err_desc_get:
++ while (i--)
++ dwc_desc_put(dwc, cdesc->desc[i]);
++out_err_alloc:
++ kfree(cdesc);
++out_err:
++ clear_bit(DW_DMA_IS_CYCLIC, &dwc->flags);
++ return (struct dw_cyclic_desc *)retval;
++}
++EXPORT_SYMBOL(dw_dma_cyclic_prep);
++
++/**
++ * dw_dma_cyclic_free - free a prepared cyclic DMA transfer
++ * @chan: the DMA channel to free
++ */
++void dw_dma_cyclic_free(struct dma_chan *chan)
++{
++ struct dw_dma_chan *dwc = to_dw_dma_chan(chan);
++ struct dw_dma *dw = to_dw_dma(dwc->chan.device);
++ struct dw_cyclic_desc *cdesc = dwc->cdesc;
++ int i;
++ unsigned long flags;
++
++ dev_dbg(chan2dev(&dwc->chan), "%s\n", __func__);
++
++ if (!cdesc)
++ return;
++
++ spin_lock_irqsave(&dwc->lock, flags);
++
++ dwc_chan_disable(dw, dwc);
++
++ dma_writel(dw, CLEAR.ERROR, dwc->mask);
++ dma_writel(dw, CLEAR.XFER, dwc->mask);
++
++ spin_unlock_irqrestore(&dwc->lock, flags);
++
++ for (i = 0; i < cdesc->periods; i++)
++ dwc_desc_put(dwc, cdesc->desc[i]);
++
++ kfree(cdesc->desc);
++ kfree(cdesc);
++
++ clear_bit(DW_DMA_IS_CYCLIC, &dwc->flags);
++}
++EXPORT_SYMBOL(dw_dma_cyclic_free);
++
++/*----------------------------------------------------------------------*/
++
++static void dw_dma_off(struct dw_dma *dw)
++{
++ int i;
++
++ dma_writel(dw, CFG, 0);
++
++ channel_clear_bit(dw, MASK.XFER, dw->all_chan_mask);
++ channel_clear_bit(dw, MASK.SRC_TRAN, dw->all_chan_mask);
++ channel_clear_bit(dw, MASK.DST_TRAN, dw->all_chan_mask);
++ channel_clear_bit(dw, MASK.ERROR, dw->all_chan_mask);
++
++ while (dma_readl(dw, CFG) & DW_CFG_DMA_EN)
++ cpu_relax();
++
++ for (i = 0; i < dw->dma.chancnt; i++)
++ dw->chan[i].initialized = false;
++}
++
++#ifdef CONFIG_OF
++static struct dw_dma_platform_data *
++dw_dma_parse_dt(struct platform_device *pdev)
++{
++ struct device_node *np = pdev->dev.of_node;
++ struct dw_dma_platform_data *pdata;
++ u32 tmp, arr[4];
++
++ if (!np) {
++ dev_err(&pdev->dev, "Missing DT data\n");
++ return NULL;
++ }
++
++ pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
++ if (!pdata)
++ return NULL;
++
++ if (of_property_read_u32(np, "dma-channels", &pdata->nr_channels))
++ return NULL;
++
++ if (of_property_read_bool(np, "is_private"))
++ pdata->is_private = true;
++
++ if (!of_property_read_u32(np, "chan_allocation_order", &tmp))
++ pdata->chan_allocation_order = (unsigned char)tmp;
++
++ if (!of_property_read_u32(np, "chan_priority", &tmp))
++ pdata->chan_priority = tmp;
++
++ if (!of_property_read_u32(np, "block_size", &tmp))
++ pdata->block_size = tmp;
++
++ if (!of_property_read_u32(np, "dma-masters", &tmp)) {
++ if (tmp > 4)
++ return NULL;
++
++ pdata->nr_masters = tmp;
++ }
++
++ if (!of_property_read_u32_array(np, "data_width", arr,
++ pdata->nr_masters))
++ for (tmp = 0; tmp < pdata->nr_masters; tmp++)
++ pdata->data_width[tmp] = arr[tmp];
++
++ return pdata;
++}
++#else
++static inline struct dw_dma_platform_data *
++dw_dma_parse_dt(struct platform_device *pdev)
++{
++ return NULL;
++}
++#endif
++
++static int dw_probe(struct platform_device *pdev)
++{
++ struct dw_dma_platform_data *pdata;
++ struct resource *io;
++ struct dw_dma *dw;
++ size_t size;
++ void __iomem *regs;
++ bool autocfg;
++ unsigned int dw_params;
++ unsigned int nr_channels;
++ unsigned int max_blk_size = 0;
++ int irq;
++ int err;
++ int i;
++
++ irq = platform_get_irq(pdev, 0);
++ if (irq < 0)
++ return irq;
++
++ io = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++ regs = devm_ioremap_resource(&pdev->dev, io);
++ if (IS_ERR(regs))
++ return PTR_ERR(regs);
++
++ /* Apply default dma_mask if needed */
++ if (!pdev->dev.dma_mask) {
++ pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask;
++ pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
++ }
++
++ dw_params = dma_read_byaddr(regs, DW_PARAMS);
++ autocfg = dw_params >> DW_PARAMS_EN & 0x1;
++
++ dev_dbg(&pdev->dev, "DW_PARAMS: 0x%08x\n", dw_params);
++
++ pdata = dev_get_platdata(&pdev->dev);
++ if (!pdata)
++ pdata = dw_dma_parse_dt(pdev);
++
++ if (!pdata && autocfg) {
++ pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
++ if (!pdata)
++ return -ENOMEM;
++
++ /* Fill platform data with the default values */
++ pdata->is_private = true;
++ pdata->chan_allocation_order = CHAN_ALLOCATION_ASCENDING;
++ pdata->chan_priority = CHAN_PRIORITY_ASCENDING;
++ } else if (!pdata || pdata->nr_channels > DW_DMA_MAX_NR_CHANNELS)
++ return -EINVAL;
++
++ if (autocfg)
++ nr_channels = (dw_params >> DW_PARAMS_NR_CHAN & 0x7) + 1;
++ else
++ nr_channels = pdata->nr_channels;
++
++ size = sizeof(struct dw_dma) + nr_channels * sizeof(struct dw_dma_chan);
++ dw = devm_kzalloc(&pdev->dev, size, GFP_KERNEL);
++ if (!dw)
++ return -ENOMEM;
++
++ dw->clk = devm_clk_get(&pdev->dev, "hclk");
++ if (IS_ERR(dw->clk))
++ return PTR_ERR(dw->clk);
++ clk_prepare_enable(dw->clk);
++
++ dw->regs = regs;
++
++ /* Get hardware configuration parameters */
++ if (autocfg) {
++ max_blk_size = dma_readl(dw, MAX_BLK_SIZE);
++
++ dw->nr_masters = (dw_params >> DW_PARAMS_NR_MASTER & 3) + 1;
++ for (i = 0; i < dw->nr_masters; i++) {
++ dw->data_width[i] =
++ (dw_params >> DW_PARAMS_DATA_WIDTH(i) & 3) + 2;
++ }
++ } else {
++ dw->nr_masters = pdata->nr_masters;
++ memcpy(dw->data_width, pdata->data_width, 4);
++ }
++
++ /* Calculate all channel mask before DMA setup */
++ dw->all_chan_mask = (1 << nr_channels) - 1;
++
++ /* Force dma off, just in case */
++ dw_dma_off(dw);
++
++ /* Disable BLOCK interrupts as well */
++ channel_clear_bit(dw, MASK.BLOCK, dw->all_chan_mask);
++
++ err = devm_request_irq(&pdev->dev, irq, dw_dma_interrupt, 0,
++ "dw_dmac", dw);
++ if (err)
++ return err;
++
++ platform_set_drvdata(pdev, dw);
++
++ /* Create a pool of consistent memory blocks for hardware descriptors */
++ dw->desc_pool = dmam_pool_create("dw_dmac_desc_pool", &pdev->dev,
++ sizeof(struct dw_desc), 4, 0);
++ if (!dw->desc_pool) {
++ dev_err(&pdev->dev, "No memory for descriptors dma pool\n");
++ return -ENOMEM;
++ }
++
++ tasklet_init(&dw->tasklet, dw_dma_tasklet, (unsigned long)dw);
++
++ INIT_LIST_HEAD(&dw->dma.channels);
++ for (i = 0; i < nr_channels; i++) {
++ struct dw_dma_chan *dwc = &dw->chan[i];
++ int r = nr_channels - i - 1;
++
++ dwc->chan.device = &dw->dma;
++ dma_cookie_init(&dwc->chan);
++ if (pdata->chan_allocation_order == CHAN_ALLOCATION_ASCENDING)
++ list_add_tail(&dwc->chan.device_node,
++ &dw->dma.channels);
++ else
++ list_add(&dwc->chan.device_node, &dw->dma.channels);
++
++ /* 7 is highest priority & 0 is lowest. */
++ if (pdata->chan_priority == CHAN_PRIORITY_ASCENDING)
++ dwc->priority = r;
++ else
++ dwc->priority = i;
++
++ dwc->ch_regs = &__dw_regs(dw)->CHAN[i];
++ spin_lock_init(&dwc->lock);
++ dwc->mask = 1 << i;
++
++ INIT_LIST_HEAD(&dwc->active_list);
++ INIT_LIST_HEAD(&dwc->queue);
++ INIT_LIST_HEAD(&dwc->free_list);
++
++ channel_clear_bit(dw, CH_EN, dwc->mask);
++
++ dwc->direction = DMA_TRANS_NONE;
++ dwc->request_line = ~0;
++
++ /* Hardware configuration */
++ if (autocfg) {
++ unsigned int dwc_params;
++
++ dwc_params = dma_read_byaddr(regs + r * sizeof(u32),
++ DWC_PARAMS);
++
++ dev_dbg(&pdev->dev, "DWC_PARAMS[%d]: 0x%08x\n", i,
++ dwc_params);
++
++ /* Decode maximum block size for given channel. The
++ * stored 4 bit value represents blocks from 0x00 for 3
++ * up to 0x0a for 4095. */
++ dwc->block_size =
++ (4 << ((max_blk_size >> 4 * i) & 0xf)) - 1;
++ dwc->nollp =
++ (dwc_params >> DWC_PARAMS_MBLK_EN & 0x1) == 0;
++ } else {
++ dwc->block_size = pdata->block_size;
++
++ /* Check if channel supports multi block transfer */
++ channel_writel(dwc, LLP, 0xfffffffc);
++ dwc->nollp =
++ (channel_readl(dwc, LLP) & 0xfffffffc) == 0;
++ channel_writel(dwc, LLP, 0);
++ }
++ }
++
++ /* Clear all interrupts on all channels. */
++ dma_writel(dw, CLEAR.XFER, dw->all_chan_mask);
++ dma_writel(dw, CLEAR.BLOCK, dw->all_chan_mask);
++ dma_writel(dw, CLEAR.SRC_TRAN, dw->all_chan_mask);
++ dma_writel(dw, CLEAR.DST_TRAN, dw->all_chan_mask);
++ dma_writel(dw, CLEAR.ERROR, dw->all_chan_mask);
++
++ dma_cap_set(DMA_MEMCPY, dw->dma.cap_mask);
++ dma_cap_set(DMA_SLAVE, dw->dma.cap_mask);
++ if (pdata->is_private)
++ dma_cap_set(DMA_PRIVATE, dw->dma.cap_mask);
++ dw->dma.dev = &pdev->dev;
++ dw->dma.device_alloc_chan_resources = dwc_alloc_chan_resources;
++ dw->dma.device_free_chan_resources = dwc_free_chan_resources;
++
++ dw->dma.device_prep_dma_memcpy = dwc_prep_dma_memcpy;
++
++ dw->dma.device_prep_slave_sg = dwc_prep_slave_sg;
++ dw->dma.device_control = dwc_control;
++
++ dw->dma.device_tx_status = dwc_tx_status;
++ dw->dma.device_issue_pending = dwc_issue_pending;
++
++ dma_writel(dw, CFG, DW_CFG_DMA_EN);
++
++ dev_info(&pdev->dev, "DesignWare DMA Controller, %d channels\n",
++ nr_channels);
++
++ dma_async_device_register(&dw->dma);
++
++ if (pdev->dev.of_node) {
++ err = of_dma_controller_register(pdev->dev.of_node,
++ dw_dma_of_xlate, dw);
++ if (err)
++ dev_err(&pdev->dev,
++ "could not register of_dma_controller\n");
++ }
++
++ if (ACPI_HANDLE(&pdev->dev))
++ dw_dma_acpi_controller_register(dw);
++
++ return 0;
++}
++
++static int dw_remove(struct platform_device *pdev)
++{
++ struct dw_dma *dw = platform_get_drvdata(pdev);
++ struct dw_dma_chan *dwc, *_dwc;
++
++ if (pdev->dev.of_node)
++ of_dma_controller_free(pdev->dev.of_node);
++ dw_dma_off(dw);
++ dma_async_device_unregister(&dw->dma);
++
++ tasklet_kill(&dw->tasklet);
++
++ list_for_each_entry_safe(dwc, _dwc, &dw->dma.channels,
++ chan.device_node) {
++ list_del(&dwc->chan.device_node);
++ channel_clear_bit(dw, CH_EN, dwc->mask);
++ }
++
++ return 0;
++}
++
++static void dw_shutdown(struct platform_device *pdev)
++{
++ struct dw_dma *dw = platform_get_drvdata(pdev);
++
++ dw_dma_off(dw);
++ clk_disable_unprepare(dw->clk);
++}
++
++static int dw_suspend_noirq(struct device *dev)
++{
++ struct platform_device *pdev = to_platform_device(dev);
++ struct dw_dma *dw = platform_get_drvdata(pdev);
++
++ dw_dma_off(dw);
++ clk_disable_unprepare(dw->clk);
++
++ return 0;
++}
++
++static int dw_resume_noirq(struct device *dev)
++{
++ struct platform_device *pdev = to_platform_device(dev);
++ struct dw_dma *dw = platform_get_drvdata(pdev);
++
++ clk_prepare_enable(dw->clk);
++ dma_writel(dw, CFG, DW_CFG_DMA_EN);
++
++ return 0;
++}
++
++static const struct dev_pm_ops dw_dev_pm_ops = {
++ .suspend_noirq = dw_suspend_noirq,
++ .resume_noirq = dw_resume_noirq,
++ .freeze_noirq = dw_suspend_noirq,
++ .thaw_noirq = dw_resume_noirq,
++ .restore_noirq = dw_resume_noirq,
++ .poweroff_noirq = dw_suspend_noirq,
++};
++
++#ifdef CONFIG_OF
++static const struct of_device_id dw_dma_of_id_table[] = {
++ { .compatible = "snps,dma-spear1340" },
++ {}
++};
++MODULE_DEVICE_TABLE(of, dw_dma_of_id_table);
++#endif
++
++#ifdef CONFIG_ACPI
++static const struct acpi_device_id dw_dma_acpi_id_table[] = {
++ { "INTL9C60", 0 },
++ { }
++};
++#endif
++
++static struct platform_driver dw_driver = {
++ .probe = dw_probe,
++ .remove = dw_remove,
++ .shutdown = dw_shutdown,
++ .driver = {
++ .name = "dw_dmac",
++ .pm = &dw_dev_pm_ops,
++ .of_match_table = of_match_ptr(dw_dma_of_id_table),
++ .acpi_match_table = ACPI_PTR(dw_dma_acpi_id_table),
++ },
++};
++
++static int __init dw_init(void)
++{
++ return platform_driver_register(&dw_driver);
++}
++subsys_initcall(dw_init);
++
++static void __exit dw_exit(void)
++{
++ platform_driver_unregister(&dw_driver);
++}
++module_exit(dw_exit);
++
++MODULE_LICENSE("GPL v2");
++MODULE_DESCRIPTION("Synopsys DesignWare DMA Controller driver");
++MODULE_AUTHOR("Haavard Skinnemoen (Atmel)");
++MODULE_AUTHOR("Viresh Kumar <viresh.linux@gmail.com>");
+--- /dev/null
++++ b/drivers/dma/dw/dw_dmac_regs.h
+@@ -0,0 +1,311 @@
++/*
++ * Driver for the Synopsys DesignWare AHB DMA Controller
++ *
++ * Copyright (C) 2005-2007 Atmel Corporation
++ * Copyright (C) 2010-2011 ST Microelectronics
++ *
++ * 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/dw_dmac.h>
++
++#define DW_DMA_MAX_NR_CHANNELS 8
++#define DW_DMA_MAX_NR_REQUESTS 16
++
++/* flow controller */
++enum dw_dma_fc {
++ DW_DMA_FC_D_M2M,
++ DW_DMA_FC_D_M2P,
++ DW_DMA_FC_D_P2M,
++ DW_DMA_FC_D_P2P,
++ DW_DMA_FC_P_P2M,
++ DW_DMA_FC_SP_P2P,
++ DW_DMA_FC_P_M2P,
++ DW_DMA_FC_DP_P2P,
++};
++
++/*
++ * Redefine this macro to handle differences between 32- and 64-bit
++ * addressing, big vs. little endian, etc.
++ */
++#define DW_REG(name) u32 name; u32 __pad_##name
++
++/* Hardware register definitions. */
++struct dw_dma_chan_regs {
++ DW_REG(SAR); /* Source Address Register */
++ DW_REG(DAR); /* Destination Address Register */
++ DW_REG(LLP); /* Linked List Pointer */
++ u32 CTL_LO; /* Control Register Low */
++ u32 CTL_HI; /* Control Register High */
++ DW_REG(SSTAT);
++ DW_REG(DSTAT);
++ DW_REG(SSTATAR);
++ DW_REG(DSTATAR);
++ u32 CFG_LO; /* Configuration Register Low */
++ u32 CFG_HI; /* Configuration Register High */
++ DW_REG(SGR);
++ DW_REG(DSR);
++};
++
++struct dw_dma_irq_regs {
++ DW_REG(XFER);
++ DW_REG(BLOCK);
++ DW_REG(SRC_TRAN);
++ DW_REG(DST_TRAN);
++ DW_REG(ERROR);
++};
++
++struct dw_dma_regs {
++ /* per-channel registers */
++ struct dw_dma_chan_regs CHAN[DW_DMA_MAX_NR_CHANNELS];
++
++ /* irq handling */
++ struct dw_dma_irq_regs RAW; /* r */
++ struct dw_dma_irq_regs STATUS; /* r (raw & mask) */
++ struct dw_dma_irq_regs MASK; /* rw (set = irq enabled) */
++ struct dw_dma_irq_regs CLEAR; /* w (ack, affects "raw") */
++
++ DW_REG(STATUS_INT); /* r */
++
++ /* software handshaking */
++ DW_REG(REQ_SRC);
++ DW_REG(REQ_DST);
++ DW_REG(SGL_REQ_SRC);
++ DW_REG(SGL_REQ_DST);
++ DW_REG(LAST_SRC);
++ DW_REG(LAST_DST);
++
++ /* miscellaneous */
++ DW_REG(CFG);
++ DW_REG(CH_EN);
++ DW_REG(ID);
++ DW_REG(TEST);
++
++ /* reserved */
++ DW_REG(__reserved0);
++ DW_REG(__reserved1);
++
++ /* optional encoded params, 0x3c8..0x3f7 */
++ u32 __reserved;
++
++ /* per-channel configuration registers */
++ u32 DWC_PARAMS[DW_DMA_MAX_NR_CHANNELS];
++ u32 MULTI_BLK_TYPE;
++ u32 MAX_BLK_SIZE;
++
++ /* top-level parameters */
++ u32 DW_PARAMS;
++};
++
++#ifdef CONFIG_DW_DMAC_BIG_ENDIAN_IO
++#define dma_readl_native ioread32be
++#define dma_writel_native iowrite32be
++#else
++#define dma_readl_native readl
++#define dma_writel_native writel
++#endif
++
++/* To access the registers in early stage of probe */
++#define dma_read_byaddr(addr, name) \
++ dma_readl_native((addr) + offsetof(struct dw_dma_regs, name))
++
++/* Bitfields in DW_PARAMS */
++#define DW_PARAMS_NR_CHAN 8 /* number of channels */
++#define DW_PARAMS_NR_MASTER 11 /* number of AHB masters */
++#define DW_PARAMS_DATA_WIDTH(n) (15 + 2 * (n))
++#define DW_PARAMS_DATA_WIDTH1 15 /* master 1 data width */
++#define DW_PARAMS_DATA_WIDTH2 17 /* master 2 data width */
++#define DW_PARAMS_DATA_WIDTH3 19 /* master 3 data width */
++#define DW_PARAMS_DATA_WIDTH4 21 /* master 4 data width */
++#define DW_PARAMS_EN 28 /* encoded parameters */
++
++/* Bitfields in DWC_PARAMS */
++#define DWC_PARAMS_MBLK_EN 11 /* multi block transfer */
++
++/* Bitfields in CTL_LO */
++#define DWC_CTLL_INT_EN (1 << 0) /* irqs enabled? */
++#define DWC_CTLL_DST_WIDTH(n) ((n)<<1) /* bytes per element */
++#define DWC_CTLL_SRC_WIDTH(n) ((n)<<4)
++#define DWC_CTLL_DST_INC (0<<7) /* DAR update/not */
++#define DWC_CTLL_DST_DEC (1<<7)
++#define DWC_CTLL_DST_FIX (2<<7)
++#define DWC_CTLL_SRC_INC (0<<7) /* SAR update/not */
++#define DWC_CTLL_SRC_DEC (1<<9)
++#define DWC_CTLL_SRC_FIX (2<<9)
++#define DWC_CTLL_DST_MSIZE(n) ((n)<<11) /* burst, #elements */
++#define DWC_CTLL_SRC_MSIZE(n) ((n)<<14)
++#define DWC_CTLL_S_GATH_EN (1 << 17) /* src gather, !FIX */
++#define DWC_CTLL_D_SCAT_EN (1 << 18) /* dst scatter, !FIX */
++#define DWC_CTLL_FC(n) ((n) << 20)
++#define DWC_CTLL_FC_M2M (0 << 20) /* mem-to-mem */
++#define DWC_CTLL_FC_M2P (1 << 20) /* mem-to-periph */
++#define DWC_CTLL_FC_P2M (2 << 20) /* periph-to-mem */
++#define DWC_CTLL_FC_P2P (3 << 20) /* periph-to-periph */
++/* plus 4 transfer types for peripheral-as-flow-controller */
++#define DWC_CTLL_DMS(n) ((n)<<23) /* dst master select */
++#define DWC_CTLL_SMS(n) ((n)<<25) /* src master select */
++#define DWC_CTLL_LLP_D_EN (1 << 27) /* dest block chain */
++#define DWC_CTLL_LLP_S_EN (1 << 28) /* src block chain */
++
++/* Bitfields in CTL_HI */
++#define DWC_CTLH_DONE 0x00001000
++#define DWC_CTLH_BLOCK_TS_MASK 0x00000fff
++
++/* Bitfields in CFG_LO. Platform-configurable bits are in <linux/dw_dmac.h> */
++#define DWC_CFGL_CH_PRIOR_MASK (0x7 << 5) /* priority mask */
++#define DWC_CFGL_CH_PRIOR(x) ((x) << 5) /* priority */
++#define DWC_CFGL_CH_SUSP (1 << 8) /* pause xfer */
++#define DWC_CFGL_FIFO_EMPTY (1 << 9) /* pause xfer */
++#define DWC_CFGL_HS_DST (1 << 10) /* handshake w/dst */
++#define DWC_CFGL_HS_SRC (1 << 11) /* handshake w/src */
++#define DWC_CFGL_MAX_BURST(x) ((x) << 20)
++#define DWC_CFGL_RELOAD_SAR (1 << 30)
++#define DWC_CFGL_RELOAD_DAR (1 << 31)
++
++/* Bitfields in CFG_HI. Platform-configurable bits are in <linux/dw_dmac.h> */
++#define DWC_CFGH_DS_UPD_EN (1 << 5)
++#define DWC_CFGH_SS_UPD_EN (1 << 6)
++
++/* Bitfields in SGR */
++#define DWC_SGR_SGI(x) ((x) << 0)
++#define DWC_SGR_SGC(x) ((x) << 20)
++
++/* Bitfields in DSR */
++#define DWC_DSR_DSI(x) ((x) << 0)
++#define DWC_DSR_DSC(x) ((x) << 20)
++
++/* Bitfields in CFG */
++#define DW_CFG_DMA_EN (1 << 0)
++
++enum dw_dmac_flags {
++ DW_DMA_IS_CYCLIC = 0,
++ DW_DMA_IS_SOFT_LLP = 1,
++};
++
++struct dw_dma_chan {
++ struct dma_chan chan;
++ void __iomem *ch_regs;
++ u8 mask;
++ u8 priority;
++ enum dma_transfer_direction direction;
++ bool paused;
++ bool initialized;
++
++ /* software emulation of the LLP transfers */
++ struct list_head *tx_node_active;
++
++ spinlock_t lock;
++
++ /* these other elements are all protected by lock */
++ unsigned long flags;
++ struct list_head active_list;
++ struct list_head queue;
++ struct list_head free_list;
++ u32 residue;
++ struct dw_cyclic_desc *cdesc;
++
++ unsigned int descs_allocated;
++
++ /* hardware configuration */
++ unsigned int block_size;
++ bool nollp;
++
++ /* custom slave configuration */
++ unsigned int request_line;
++ unsigned char src_master;
++ unsigned char dst_master;
++
++ /* configuration passed via DMA_SLAVE_CONFIG */
++ struct dma_slave_config dma_sconfig;
++};
++
++static inline struct dw_dma_chan_regs __iomem *
++__dwc_regs(struct dw_dma_chan *dwc)
++{
++ return dwc->ch_regs;
++}
++
++#define channel_readl(dwc, name) \
++ dma_readl_native(&(__dwc_regs(dwc)->name))
++#define channel_writel(dwc, name, val) \
++ dma_writel_native((val), &(__dwc_regs(dwc)->name))
++
++static inline struct dw_dma_chan *to_dw_dma_chan(struct dma_chan *chan)
++{
++ return container_of(chan, struct dw_dma_chan, chan);
++}
++
++struct dw_dma {
++ struct dma_device dma;
++ void __iomem *regs;
++ struct dma_pool *desc_pool;
++ struct tasklet_struct tasklet;
++ struct clk *clk;
++
++ u8 all_chan_mask;
++
++ /* hardware configuration */
++ unsigned char nr_masters;
++ unsigned char data_width[4];
++
++ struct dw_dma_chan chan[0];
++};
++
++static inline struct dw_dma_regs __iomem *__dw_regs(struct dw_dma *dw)
++{
++ return dw->regs;
++}
++
++#define dma_readl(dw, name) \
++ dma_readl_native(&(__dw_regs(dw)->name))
++#define dma_writel(dw, name, val) \
++ dma_writel_native((val), &(__dw_regs(dw)->name))
++
++#define channel_set_bit(dw, reg, mask) \
++ dma_writel(dw, reg, ((mask) << 8) | (mask))
++#define channel_clear_bit(dw, reg, mask) \
++ dma_writel(dw, reg, ((mask) << 8) | 0)
++
++static inline struct dw_dma *to_dw_dma(struct dma_device *ddev)
++{
++ return container_of(ddev, struct dw_dma, dma);
++}
++
++/* LLI == Linked List Item; a.k.a. DMA block descriptor */
++struct dw_lli {
++ /* values that are not changed by hardware */
++ u32 sar;
++ u32 dar;
++ u32 llp; /* chain to next lli */
++ u32 ctllo;
++ /* values that may get written back: */
++ u32 ctlhi;
++ /* sstat and dstat can snapshot peripheral register state.
++ * silicon config may discard either or both...
++ */
++ u32 sstat;
++ u32 dstat;
++};
++
++struct dw_desc {
++ /* FIRST values the hardware uses */
++ struct dw_lli lli;
++
++ /* THEN values for driver housekeeping */
++ struct list_head desc_node;
++ struct list_head tx_list;
++ struct dma_async_tx_descriptor txd;
++ size_t len;
++ size_t total_len;
++};
++
++#define to_dw_desc(h) list_entry(h, struct dw_desc, desc_node)
++
++static inline struct dw_desc *
++txd_to_dw_desc(struct dma_async_tx_descriptor *txd)
++{
++ return container_of(txd, struct dw_desc, txd);
++}
+--- a/drivers/dma/dw_dmac.c
++++ /dev/null
+@@ -1,1969 +0,0 @@
+-/*
+- * Core driver for the Synopsys DesignWare DMA Controller
+- *
+- * Copyright (C) 2007-2008 Atmel Corporation
+- * Copyright (C) 2010-2011 ST Microelectronics
+- *
+- * 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/bitops.h>
+-#include <linux/clk.h>
+-#include <linux/delay.h>
+-#include <linux/dmaengine.h>
+-#include <linux/dma-mapping.h>
+-#include <linux/dmapool.h>
+-#include <linux/err.h>
+-#include <linux/init.h>
+-#include <linux/interrupt.h>
+-#include <linux/io.h>
+-#include <linux/of.h>
+-#include <linux/of_dma.h>
+-#include <linux/mm.h>
+-#include <linux/module.h>
+-#include <linux/platform_device.h>
+-#include <linux/slab.h>
+-#include <linux/acpi.h>
+-#include <linux/acpi_dma.h>
+-
+-#include "dw_dmac_regs.h"
-#include "dmaengine.h"
-
- /*
- * This supports the Synopsys "DesignWare AHB Central DMA Controller",
-diff --git a/drivers/dma/dw_dmac_regs.h b/drivers/dma/dw/dw_dmac_regs.h
-similarity index 100%
-rename from drivers/dma/dw_dmac_regs.h
-rename to drivers/dma/dw/dw_dmac_regs.h
---
-1.8.5.rc3
-
+-
+-/*
+- * This supports the Synopsys "DesignWare AHB Central DMA Controller",
+- * (DW_ahb_dmac) which is used with various AMBA 2.0 systems (not all
+- * of which use ARM any more). See the "Databook" from Synopsys for
+- * information beyond what licensees probably provide.
+- *
+- * The driver has currently been tested only with the Atmel AT32AP7000,
+- * which does not support descriptor writeback.
+- */
+-
+-static inline unsigned int dwc_get_dms(struct dw_dma_slave *slave)
+-{
+- return slave ? slave->dst_master : 0;
+-}
+-
+-static inline unsigned int dwc_get_sms(struct dw_dma_slave *slave)
+-{
+- return slave ? slave->src_master : 1;
+-}
+-
+-static inline void dwc_set_masters(struct dw_dma_chan *dwc)
+-{
+- struct dw_dma *dw = to_dw_dma(dwc->chan.device);
+- struct dw_dma_slave *dws = dwc->chan.private;
+- unsigned char mmax = dw->nr_masters - 1;
+-
+- if (dwc->request_line == ~0) {
+- dwc->src_master = min_t(unsigned char, mmax, dwc_get_sms(dws));
+- dwc->dst_master = min_t(unsigned char, mmax, dwc_get_dms(dws));
+- }
+-}
+-
+-#define DWC_DEFAULT_CTLLO(_chan) ({ \
+- struct dw_dma_chan *_dwc = to_dw_dma_chan(_chan); \
+- struct dma_slave_config *_sconfig = &_dwc->dma_sconfig; \
+- bool _is_slave = is_slave_direction(_dwc->direction); \
+- u8 _smsize = _is_slave ? _sconfig->src_maxburst : \
+- DW_DMA_MSIZE_16; \
+- u8 _dmsize = _is_slave ? _sconfig->dst_maxburst : \
+- DW_DMA_MSIZE_16; \
+- \
+- (DWC_CTLL_DST_MSIZE(_dmsize) \
+- | DWC_CTLL_SRC_MSIZE(_smsize) \
+- | DWC_CTLL_LLP_D_EN \
+- | DWC_CTLL_LLP_S_EN \
+- | DWC_CTLL_DMS(_dwc->dst_master) \
+- | DWC_CTLL_SMS(_dwc->src_master)); \
+- })
+-
+-/*
+- * Number of descriptors to allocate for each channel. This should be
+- * made configurable somehow; preferably, the clients (at least the
+- * ones using slave transfers) should be able to give us a hint.
+- */
+-#define NR_DESCS_PER_CHANNEL 64
+-
+-/*----------------------------------------------------------------------*/
+-
+-static struct device *chan2dev(struct dma_chan *chan)
+-{
+- return &chan->dev->device;
+-}
+-static struct device *chan2parent(struct dma_chan *chan)
+-{
+- return chan->dev->device.parent;
+-}
+-
+-static struct dw_desc *dwc_first_active(struct dw_dma_chan *dwc)
+-{
+- return to_dw_desc(dwc->active_list.next);
+-}
+-
+-static struct dw_desc *dwc_desc_get(struct dw_dma_chan *dwc)
+-{
+- struct dw_desc *desc, *_desc;
+- struct dw_desc *ret = NULL;
+- unsigned int i = 0;
+- unsigned long flags;
+-
+- spin_lock_irqsave(&dwc->lock, flags);
+- list_for_each_entry_safe(desc, _desc, &dwc->free_list, desc_node) {
+- i++;
+- if (async_tx_test_ack(&desc->txd)) {
+- list_del(&desc->desc_node);
+- ret = desc;
+- break;
+- }
+- dev_dbg(chan2dev(&dwc->chan), "desc %p not ACKed\n", desc);
+- }
+- spin_unlock_irqrestore(&dwc->lock, flags);
+-
+- dev_vdbg(chan2dev(&dwc->chan), "scanned %u descriptors on freelist\n", i);
+-
+- return ret;
+-}
+-
+-/*
+- * Move a descriptor, including any children, to the free list.
+- * `desc' must not be on any lists.
+- */
+-static void dwc_desc_put(struct dw_dma_chan *dwc, struct dw_desc *desc)
+-{
+- unsigned long flags;
+-
+- if (desc) {
+- struct dw_desc *child;
+-
+- spin_lock_irqsave(&dwc->lock, flags);
+- list_for_each_entry(child, &desc->tx_list, desc_node)
+- dev_vdbg(chan2dev(&dwc->chan),
+- "moving child desc %p to freelist\n",
+- child);
+- list_splice_init(&desc->tx_list, &dwc->free_list);
+- dev_vdbg(chan2dev(&dwc->chan), "moving desc %p to freelist\n", desc);
+- list_add(&desc->desc_node, &dwc->free_list);
+- spin_unlock_irqrestore(&dwc->lock, flags);
+- }
+-}
+-
+-static void dwc_initialize(struct dw_dma_chan *dwc)
+-{
+- struct dw_dma *dw = to_dw_dma(dwc->chan.device);
+- struct dw_dma_slave *dws = dwc->chan.private;
+- u32 cfghi = DWC_CFGH_FIFO_MODE;
+- u32 cfglo = DWC_CFGL_CH_PRIOR(dwc->priority);
+-
+- if (dwc->initialized == true)
+- return;
+-
+- if (dws) {
+- /*
+- * We need controller-specific data to set up slave
+- * transfers.
+- */
+- BUG_ON(!dws->dma_dev || dws->dma_dev != dw->dma.dev);
+-
+- cfghi = dws->cfg_hi;
+- cfglo |= dws->cfg_lo & ~DWC_CFGL_CH_PRIOR_MASK;
+- } else {
+- if (dwc->direction == DMA_MEM_TO_DEV)
+- cfghi = DWC_CFGH_DST_PER(dwc->request_line);
+- else if (dwc->direction == DMA_DEV_TO_MEM)
+- cfghi = DWC_CFGH_SRC_PER(dwc->request_line);
+- }
+-
+- channel_writel(dwc, CFG_LO, cfglo);
+- channel_writel(dwc, CFG_HI, cfghi);
+-
+- /* Enable interrupts */
+- channel_set_bit(dw, MASK.XFER, dwc->mask);
+- channel_set_bit(dw, MASK.ERROR, dwc->mask);
+-
+- dwc->initialized = true;
+-}
+-
+-/*----------------------------------------------------------------------*/
+-
+-static inline unsigned int dwc_fast_fls(unsigned long long v)
+-{
+- /*
+- * We can be a lot more clever here, but this should take care
+- * of the most common optimization.
+- */
+- if (!(v & 7))
+- return 3;
+- else if (!(v & 3))
+- return 2;
+- else if (!(v & 1))
+- return 1;
+- return 0;
+-}
+-
+-static inline void dwc_dump_chan_regs(struct dw_dma_chan *dwc)
+-{
+- dev_err(chan2dev(&dwc->chan),
+- " SAR: 0x%x DAR: 0x%x LLP: 0x%x CTL: 0x%x:%08x\n",
+- channel_readl(dwc, SAR),
+- channel_readl(dwc, DAR),
+- channel_readl(dwc, LLP),
+- channel_readl(dwc, CTL_HI),
+- channel_readl(dwc, CTL_LO));
+-}
+-
+-static inline void dwc_chan_disable(struct dw_dma *dw, struct dw_dma_chan *dwc)
+-{
+- channel_clear_bit(dw, CH_EN, dwc->mask);
+- while (dma_readl(dw, CH_EN) & dwc->mask)
+- cpu_relax();
+-}
+-
+-/*----------------------------------------------------------------------*/
+-
+-/* Perform single block transfer */
+-static inline void dwc_do_single_block(struct dw_dma_chan *dwc,
+- struct dw_desc *desc)
+-{
+- struct dw_dma *dw = to_dw_dma(dwc->chan.device);
+- u32 ctllo;
+-
+- /* Software emulation of LLP mode relies on interrupts to continue
+- * multi block transfer. */
+- ctllo = desc->lli.ctllo | DWC_CTLL_INT_EN;
+-
+- channel_writel(dwc, SAR, desc->lli.sar);
+- channel_writel(dwc, DAR, desc->lli.dar);
+- channel_writel(dwc, CTL_LO, ctllo);
+- channel_writel(dwc, CTL_HI, desc->lli.ctlhi);
+- channel_set_bit(dw, CH_EN, dwc->mask);
+-
+- /* Move pointer to next descriptor */
+- dwc->tx_node_active = dwc->tx_node_active->next;
+-}
+-
+-/* Called with dwc->lock held and bh disabled */
+-static void dwc_dostart(struct dw_dma_chan *dwc, struct dw_desc *first)
+-{
+- struct dw_dma *dw = to_dw_dma(dwc->chan.device);
+- unsigned long was_soft_llp;
+-
+- /* ASSERT: channel is idle */
+- if (dma_readl(dw, CH_EN) & dwc->mask) {
+- dev_err(chan2dev(&dwc->chan),
+- "BUG: Attempted to start non-idle channel\n");
+- dwc_dump_chan_regs(dwc);
+-
+- /* The tasklet will hopefully advance the queue... */
+- return;
+- }
+-
+- if (dwc->nollp) {
+- was_soft_llp = test_and_set_bit(DW_DMA_IS_SOFT_LLP,
+- &dwc->flags);
+- if (was_soft_llp) {
+- dev_err(chan2dev(&dwc->chan),
+- "BUG: Attempted to start new LLP transfer "
+- "inside ongoing one\n");
+- return;
+- }
+-
+- dwc_initialize(dwc);
+-
+- dwc->residue = first->total_len;
+- dwc->tx_node_active = &first->tx_list;
+-
+- /* Submit first block */
+- dwc_do_single_block(dwc, first);
+-
+- return;
+- }
+-
+- dwc_initialize(dwc);
+-
+- channel_writel(dwc, LLP, first->txd.phys);
+- channel_writel(dwc, CTL_LO,
+- DWC_CTLL_LLP_D_EN | DWC_CTLL_LLP_S_EN);
+- channel_writel(dwc, CTL_HI, 0);
+- channel_set_bit(dw, CH_EN, dwc->mask);
+-}
+-
+-/*----------------------------------------------------------------------*/
+-
+-static void
+-dwc_descriptor_complete(struct dw_dma_chan *dwc, struct dw_desc *desc,
+- bool callback_required)
+-{
+- dma_async_tx_callback callback = NULL;
+- void *param = NULL;
+- struct dma_async_tx_descriptor *txd = &desc->txd;
+- struct dw_desc *child;
+- unsigned long flags;
+-
+- dev_vdbg(chan2dev(&dwc->chan), "descriptor %u complete\n", txd->cookie);
+-
+- spin_lock_irqsave(&dwc->lock, flags);
+- dma_cookie_complete(txd);
+- if (callback_required) {
+- callback = txd->callback;
+- param = txd->callback_param;
+- }
+-
+- /* async_tx_ack */
+- list_for_each_entry(child, &desc->tx_list, desc_node)
+- async_tx_ack(&child->txd);
+- async_tx_ack(&desc->txd);
+-
+- list_splice_init(&desc->tx_list, &dwc->free_list);
+- list_move(&desc->desc_node, &dwc->free_list);
+-
+- if (!is_slave_direction(dwc->direction)) {
+- struct device *parent = chan2parent(&dwc->chan);
+- if (!(txd->flags & DMA_COMPL_SKIP_DEST_UNMAP)) {
+- if (txd->flags & DMA_COMPL_DEST_UNMAP_SINGLE)
+- dma_unmap_single(parent, desc->lli.dar,
+- desc->total_len, DMA_FROM_DEVICE);
+- else
+- dma_unmap_page(parent, desc->lli.dar,
+- desc->total_len, DMA_FROM_DEVICE);
+- }
+- if (!(txd->flags & DMA_COMPL_SKIP_SRC_UNMAP)) {
+- if (txd->flags & DMA_COMPL_SRC_UNMAP_SINGLE)
+- dma_unmap_single(parent, desc->lli.sar,
+- desc->total_len, DMA_TO_DEVICE);
+- else
+- dma_unmap_page(parent, desc->lli.sar,
+- desc->total_len, DMA_TO_DEVICE);
+- }
+- }
+-
+- spin_unlock_irqrestore(&dwc->lock, flags);
+-
+- if (callback)
+- callback(param);
+-}
+-
+-static void dwc_complete_all(struct dw_dma *dw, struct dw_dma_chan *dwc)
+-{
+- struct dw_desc *desc, *_desc;
+- LIST_HEAD(list);
+- unsigned long flags;
+-
+- spin_lock_irqsave(&dwc->lock, flags);
+- if (dma_readl(dw, CH_EN) & dwc->mask) {
+- dev_err(chan2dev(&dwc->chan),
+- "BUG: XFER bit set, but channel not idle!\n");
+-
+- /* Try to continue after resetting the channel... */
+- dwc_chan_disable(dw, dwc);
+- }
+-
+- /*
+- * Submit queued descriptors ASAP, i.e. before we go through
+- * the completed ones.
+- */
+- list_splice_init(&dwc->active_list, &list);
+- if (!list_empty(&dwc->queue)) {
+- list_move(dwc->queue.next, &dwc->active_list);
+- dwc_dostart(dwc, dwc_first_active(dwc));
+- }
+-
+- spin_unlock_irqrestore(&dwc->lock, flags);
+-
+- list_for_each_entry_safe(desc, _desc, &list, desc_node)
+- dwc_descriptor_complete(dwc, desc, true);
+-}
+-
+-/* Returns how many bytes were already received from source */
+-static inline u32 dwc_get_sent(struct dw_dma_chan *dwc)
+-{
+- u32 ctlhi = channel_readl(dwc, CTL_HI);
+- u32 ctllo = channel_readl(dwc, CTL_LO);
+-
+- return (ctlhi & DWC_CTLH_BLOCK_TS_MASK) * (1 << (ctllo >> 4 & 7));
+-}
+-
+-static void dwc_scan_descriptors(struct dw_dma *dw, struct dw_dma_chan *dwc)
+-{
+- dma_addr_t llp;
+- struct dw_desc *desc, *_desc;
+- struct dw_desc *child;
+- u32 status_xfer;
+- unsigned long flags;
+-
+- spin_lock_irqsave(&dwc->lock, flags);
+- llp = channel_readl(dwc, LLP);
+- status_xfer = dma_readl(dw, RAW.XFER);
+-
+- if (status_xfer & dwc->mask) {
+- /* Everything we've submitted is done */
+- dma_writel(dw, CLEAR.XFER, dwc->mask);
+-
+- if (test_bit(DW_DMA_IS_SOFT_LLP, &dwc->flags)) {
+- struct list_head *head, *active = dwc->tx_node_active;
+-
+- /*
+- * We are inside first active descriptor.
+- * Otherwise something is really wrong.
+- */
+- desc = dwc_first_active(dwc);
+-
+- head = &desc->tx_list;
+- if (active != head) {
+- /* Update desc to reflect last sent one */
+- if (active != head->next)
+- desc = to_dw_desc(active->prev);
+-
+- dwc->residue -= desc->len;
+-
+- child = to_dw_desc(active);
+-
+- /* Submit next block */
+- dwc_do_single_block(dwc, child);
+-
+- spin_unlock_irqrestore(&dwc->lock, flags);
+- return;
+- }
+-
+- /* We are done here */
+- clear_bit(DW_DMA_IS_SOFT_LLP, &dwc->flags);
+- }
+-
+- dwc->residue = 0;
+-
+- spin_unlock_irqrestore(&dwc->lock, flags);
+-
+- dwc_complete_all(dw, dwc);
+- return;
+- }
+-
+- if (list_empty(&dwc->active_list)) {
+- dwc->residue = 0;
+- spin_unlock_irqrestore(&dwc->lock, flags);
+- return;
+- }
+-
+- if (test_bit(DW_DMA_IS_SOFT_LLP, &dwc->flags)) {
+- dev_vdbg(chan2dev(&dwc->chan), "%s: soft LLP mode\n", __func__);
+- spin_unlock_irqrestore(&dwc->lock, flags);
+- return;
+- }
+-
+- dev_vdbg(chan2dev(&dwc->chan), "%s: llp=0x%llx\n", __func__,
+- (unsigned long long)llp);
+-
+- list_for_each_entry_safe(desc, _desc, &dwc->active_list, desc_node) {
+- /* Initial residue value */
+- dwc->residue = desc->total_len;
+-
+- /* Check first descriptors addr */
+- if (desc->txd.phys == llp) {
+- spin_unlock_irqrestore(&dwc->lock, flags);
+- return;
+- }
+-
+- /* Check first descriptors llp */
+- if (desc->lli.llp == llp) {
+- /* This one is currently in progress */
+- dwc->residue -= dwc_get_sent(dwc);
+- spin_unlock_irqrestore(&dwc->lock, flags);
+- return;
+- }
+-
+- dwc->residue -= desc->len;
+- list_for_each_entry(child, &desc->tx_list, desc_node) {
+- if (child->lli.llp == llp) {
+- /* Currently in progress */
+- dwc->residue -= dwc_get_sent(dwc);
+- spin_unlock_irqrestore(&dwc->lock, flags);
+- return;
+- }
+- dwc->residue -= child->len;
+- }
+-
+- /*
+- * No descriptors so far seem to be in progress, i.e.
+- * this one must be done.
+- */
+- spin_unlock_irqrestore(&dwc->lock, flags);
+- dwc_descriptor_complete(dwc, desc, true);
+- spin_lock_irqsave(&dwc->lock, flags);
+- }
+-
+- dev_err(chan2dev(&dwc->chan),
+- "BUG: All descriptors done, but channel not idle!\n");
+-
+- /* Try to continue after resetting the channel... */
+- dwc_chan_disable(dw, dwc);
+-
+- if (!list_empty(&dwc->queue)) {
+- list_move(dwc->queue.next, &dwc->active_list);
+- dwc_dostart(dwc, dwc_first_active(dwc));
+- }
+- spin_unlock_irqrestore(&dwc->lock, flags);
+-}
+-
+-static inline void dwc_dump_lli(struct dw_dma_chan *dwc, struct dw_lli *lli)
+-{
+- dev_crit(chan2dev(&dwc->chan), " desc: s0x%x d0x%x l0x%x c0x%x:%x\n",
+- lli->sar, lli->dar, lli->llp, lli->ctlhi, lli->ctllo);
+-}
+-
+-static void dwc_handle_error(struct dw_dma *dw, struct dw_dma_chan *dwc)
+-{
+- struct dw_desc *bad_desc;
+- struct dw_desc *child;
+- unsigned long flags;
+-
+- dwc_scan_descriptors(dw, dwc);
+-
+- spin_lock_irqsave(&dwc->lock, flags);
+-
+- /*
+- * The descriptor currently at the head of the active list is
+- * borked. Since we don't have any way to report errors, we'll
+- * just have to scream loudly and try to carry on.
+- */
+- bad_desc = dwc_first_active(dwc);
+- list_del_init(&bad_desc->desc_node);
+- list_move(dwc->queue.next, dwc->active_list.prev);
+-
+- /* Clear the error flag and try to restart the controller */
+- dma_writel(dw, CLEAR.ERROR, dwc->mask);
+- if (!list_empty(&dwc->active_list))
+- dwc_dostart(dwc, dwc_first_active(dwc));
+-
+- /*
+- * WARN may seem harsh, but since this only happens
+- * when someone submits a bad physical address in a
+- * descriptor, we should consider ourselves lucky that the
+- * controller flagged an error instead of scribbling over
+- * random memory locations.
+- */
+- dev_WARN(chan2dev(&dwc->chan), "Bad descriptor submitted for DMA!\n"
+- " cookie: %d\n", bad_desc->txd.cookie);
+- dwc_dump_lli(dwc, &bad_desc->lli);
+- list_for_each_entry(child, &bad_desc->tx_list, desc_node)
+- dwc_dump_lli(dwc, &child->lli);
+-
+- spin_unlock_irqrestore(&dwc->lock, flags);
+-
+- /* Pretend the descriptor completed successfully */
+- dwc_descriptor_complete(dwc, bad_desc, true);
+-}
+-
+-/* --------------------- Cyclic DMA API extensions -------------------- */
+-
+-dma_addr_t dw_dma_get_src_addr(struct dma_chan *chan)
+-{
+- struct dw_dma_chan *dwc = to_dw_dma_chan(chan);
+- return channel_readl(dwc, SAR);
+-}
+-EXPORT_SYMBOL(dw_dma_get_src_addr);
+-
+-dma_addr_t dw_dma_get_dst_addr(struct dma_chan *chan)
+-{
+- struct dw_dma_chan *dwc = to_dw_dma_chan(chan);
+- return channel_readl(dwc, DAR);
+-}
+-EXPORT_SYMBOL(dw_dma_get_dst_addr);
+-
+-/* Called with dwc->lock held and all DMAC interrupts disabled */
+-static void dwc_handle_cyclic(struct dw_dma *dw, struct dw_dma_chan *dwc,
+- u32 status_err, u32 status_xfer)
+-{
+- unsigned long flags;
+-
+- if (dwc->mask) {
+- void (*callback)(void *param);
+- void *callback_param;
+-
+- dev_vdbg(chan2dev(&dwc->chan), "new cyclic period llp 0x%08x\n",
+- channel_readl(dwc, LLP));
+-
+- callback = dwc->cdesc->period_callback;
+- callback_param = dwc->cdesc->period_callback_param;
+-
+- if (callback)
+- callback(callback_param);
+- }
+-
+- /*
+- * Error and transfer complete are highly unlikely, and will most
+- * likely be due to a configuration error by the user.
+- */
+- if (unlikely(status_err & dwc->mask) ||
+- unlikely(status_xfer & dwc->mask)) {
+- int i;
+-
+- dev_err(chan2dev(&dwc->chan), "cyclic DMA unexpected %s "
+- "interrupt, stopping DMA transfer\n",
+- status_xfer ? "xfer" : "error");
+-
+- spin_lock_irqsave(&dwc->lock, flags);
+-
+- dwc_dump_chan_regs(dwc);
+-
+- dwc_chan_disable(dw, dwc);
+-
+- /* Make sure DMA does not restart by loading a new list */
+- channel_writel(dwc, LLP, 0);
+- channel_writel(dwc, CTL_LO, 0);
+- channel_writel(dwc, CTL_HI, 0);
+-
+- dma_writel(dw, CLEAR.ERROR, dwc->mask);
+- dma_writel(dw, CLEAR.XFER, dwc->mask);
+-
+- for (i = 0; i < dwc->cdesc->periods; i++)
+- dwc_dump_lli(dwc, &dwc->cdesc->desc[i]->lli);
+-
+- spin_unlock_irqrestore(&dwc->lock, flags);
+- }
+-}
+-
+-/* ------------------------------------------------------------------------- */
+-
+-static void dw_dma_tasklet(unsigned long data)
+-{
+- struct dw_dma *dw = (struct dw_dma *)data;
+- struct dw_dma_chan *dwc;
+- u32 status_xfer;
+- u32 status_err;
+- int i;
+-
+- status_xfer = dma_readl(dw, RAW.XFER);
+- status_err = dma_readl(dw, RAW.ERROR);
+-
+- dev_vdbg(dw->dma.dev, "%s: status_err=%x\n", __func__, status_err);
+-
+- for (i = 0; i < dw->dma.chancnt; i++) {
+- dwc = &dw->chan[i];
+- if (test_bit(DW_DMA_IS_CYCLIC, &dwc->flags))
+- dwc_handle_cyclic(dw, dwc, status_err, status_xfer);
+- else if (status_err & (1 << i))
+- dwc_handle_error(dw, dwc);
+- else if (status_xfer & (1 << i))
+- dwc_scan_descriptors(dw, dwc);
+- }
+-
+- /*
+- * Re-enable interrupts.
+- */
+- channel_set_bit(dw, MASK.XFER, dw->all_chan_mask);
+- channel_set_bit(dw, MASK.ERROR, dw->all_chan_mask);
+-}
+-
+-static irqreturn_t dw_dma_interrupt(int irq, void *dev_id)
+-{
+- struct dw_dma *dw = dev_id;
+- u32 status;
+-
+- dev_vdbg(dw->dma.dev, "%s: status=0x%x\n", __func__,
+- dma_readl(dw, STATUS_INT));
+-
+- /*
+- * Just disable the interrupts. We'll turn them back on in the
+- * softirq handler.
+- */
+- channel_clear_bit(dw, MASK.XFER, dw->all_chan_mask);
+- channel_clear_bit(dw, MASK.ERROR, dw->all_chan_mask);
+-
+- status = dma_readl(dw, STATUS_INT);
+- if (status) {
+- dev_err(dw->dma.dev,
+- "BUG: Unexpected interrupts pending: 0x%x\n",
+- status);
+-
+- /* Try to recover */
+- channel_clear_bit(dw, MASK.XFER, (1 << 8) - 1);
+- channel_clear_bit(dw, MASK.SRC_TRAN, (1 << 8) - 1);
+- channel_clear_bit(dw, MASK.DST_TRAN, (1 << 8) - 1);
+- channel_clear_bit(dw, MASK.ERROR, (1 << 8) - 1);
+- }
+-
+- tasklet_schedule(&dw->tasklet);
+-
+- return IRQ_HANDLED;
+-}
+-
+-/*----------------------------------------------------------------------*/
+-
+-static dma_cookie_t dwc_tx_submit(struct dma_async_tx_descriptor *tx)
+-{
+- struct dw_desc *desc = txd_to_dw_desc(tx);
+- struct dw_dma_chan *dwc = to_dw_dma_chan(tx->chan);
+- dma_cookie_t cookie;
+- unsigned long flags;
+-
+- spin_lock_irqsave(&dwc->lock, flags);
+- cookie = dma_cookie_assign(tx);
+-
+- /*
+- * REVISIT: We should attempt to chain as many descriptors as
+- * possible, perhaps even appending to those already submitted
+- * for DMA. But this is hard to do in a race-free manner.
+- */
+- if (list_empty(&dwc->active_list)) {
+- dev_vdbg(chan2dev(tx->chan), "%s: started %u\n", __func__,
+- desc->txd.cookie);
+- list_add_tail(&desc->desc_node, &dwc->active_list);
+- dwc_dostart(dwc, dwc_first_active(dwc));
+- } else {
+- dev_vdbg(chan2dev(tx->chan), "%s: queued %u\n", __func__,
+- desc->txd.cookie);
+-
+- list_add_tail(&desc->desc_node, &dwc->queue);
+- }
+-
+- spin_unlock_irqrestore(&dwc->lock, flags);
+-
+- return cookie;
+-}
+-
+-static struct dma_async_tx_descriptor *
+-dwc_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dest, dma_addr_t src,
+- size_t len, unsigned long flags)
+-{
+- struct dw_dma_chan *dwc = to_dw_dma_chan(chan);
+- struct dw_dma *dw = to_dw_dma(chan->device);
+- struct dw_desc *desc;
+- struct dw_desc *first;
+- struct dw_desc *prev;
+- size_t xfer_count;
+- size_t offset;
+- unsigned int src_width;
+- unsigned int dst_width;
+- unsigned int data_width;
+- u32 ctllo;
+-
+- dev_vdbg(chan2dev(chan),
+- "%s: d0x%llx s0x%llx l0x%zx f0x%lx\n", __func__,
+- (unsigned long long)dest, (unsigned long long)src,
+- len, flags);
+-
+- if (unlikely(!len)) {
+- dev_dbg(chan2dev(chan), "%s: length is zero!\n", __func__);
+- return NULL;
+- }
+-
+- dwc->direction = DMA_MEM_TO_MEM;
+-
+- data_width = min_t(unsigned int, dw->data_width[dwc->src_master],
+- dw->data_width[dwc->dst_master]);
+-
+- src_width = dst_width = min_t(unsigned int, data_width,
+- dwc_fast_fls(src | dest | len));
+-
+- ctllo = DWC_DEFAULT_CTLLO(chan)
+- | DWC_CTLL_DST_WIDTH(dst_width)
+- | DWC_CTLL_SRC_WIDTH(src_width)
+- | DWC_CTLL_DST_INC
+- | DWC_CTLL_SRC_INC
+- | DWC_CTLL_FC_M2M;
+- prev = first = NULL;
+-
+- for (offset = 0; offset < len; offset += xfer_count << src_width) {
+- xfer_count = min_t(size_t, (len - offset) >> src_width,
+- dwc->block_size);
+-
+- desc = dwc_desc_get(dwc);
+- if (!desc)
+- goto err_desc_get;
+-
+- desc->lli.sar = src + offset;
+- desc->lli.dar = dest + offset;
+- desc->lli.ctllo = ctllo;
+- desc->lli.ctlhi = xfer_count;
+- desc->len = xfer_count << src_width;
+-
+- if (!first) {
+- first = desc;
+- } else {
+- prev->lli.llp = desc->txd.phys;
+- list_add_tail(&desc->desc_node,
+- &first->tx_list);
+- }
+- prev = desc;
+- }
+-
+- if (flags & DMA_PREP_INTERRUPT)
+- /* Trigger interrupt after last block */
+- prev->lli.ctllo |= DWC_CTLL_INT_EN;
+-
+- prev->lli.llp = 0;
+- first->txd.flags = flags;
+- first->total_len = len;
+-
+- return &first->txd;
+-
+-err_desc_get:
+- dwc_desc_put(dwc, first);
+- return NULL;
+-}
+-
+-static struct dma_async_tx_descriptor *
+-dwc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
+- unsigned int sg_len, enum dma_transfer_direction direction,
+- unsigned long flags, void *context)
+-{
+- struct dw_dma_chan *dwc = to_dw_dma_chan(chan);
+- struct dw_dma *dw = to_dw_dma(chan->device);
+- struct dma_slave_config *sconfig = &dwc->dma_sconfig;
+- struct dw_desc *prev;
+- struct dw_desc *first;
+- u32 ctllo;
+- dma_addr_t reg;
+- unsigned int reg_width;
+- unsigned int mem_width;
+- unsigned int data_width;
+- unsigned int i;
+- struct scatterlist *sg;
+- size_t total_len = 0;
+-
+- dev_vdbg(chan2dev(chan), "%s\n", __func__);
+-
+- if (unlikely(!is_slave_direction(direction) || !sg_len))
+- return NULL;
+-
+- dwc->direction = direction;
+-
+- prev = first = NULL;
+-
+- switch (direction) {
+- case DMA_MEM_TO_DEV:
+- reg_width = __fls(sconfig->dst_addr_width);
+- reg = sconfig->dst_addr;
+- ctllo = (DWC_DEFAULT_CTLLO(chan)
+- | DWC_CTLL_DST_WIDTH(reg_width)
+- | DWC_CTLL_DST_FIX
+- | DWC_CTLL_SRC_INC);
+-
+- ctllo |= sconfig->device_fc ? DWC_CTLL_FC(DW_DMA_FC_P_M2P) :
+- DWC_CTLL_FC(DW_DMA_FC_D_M2P);
+-
+- data_width = dw->data_width[dwc->src_master];
+-
+- for_each_sg(sgl, sg, sg_len, i) {
+- struct dw_desc *desc;
+- u32 len, dlen, mem;
+-
+- mem = sg_dma_address(sg);
+- len = sg_dma_len(sg);
+-
+- mem_width = min_t(unsigned int,
+- data_width, dwc_fast_fls(mem | len));
+-
+-slave_sg_todev_fill_desc:
+- desc = dwc_desc_get(dwc);
+- if (!desc) {
+- dev_err(chan2dev(chan),
+- "not enough descriptors available\n");
+- goto err_desc_get;
+- }
+-
+- desc->lli.sar = mem;
+- desc->lli.dar = reg;
+- desc->lli.ctllo = ctllo | DWC_CTLL_SRC_WIDTH(mem_width);
+- if ((len >> mem_width) > dwc->block_size) {
+- dlen = dwc->block_size << mem_width;
+- mem += dlen;
+- len -= dlen;
+- } else {
+- dlen = len;
+- len = 0;
+- }
+-
+- desc->lli.ctlhi = dlen >> mem_width;
+- desc->len = dlen;
+-
+- if (!first) {
+- first = desc;
+- } else {
+- prev->lli.llp = desc->txd.phys;
+- list_add_tail(&desc->desc_node,
+- &first->tx_list);
+- }
+- prev = desc;
+- total_len += dlen;
+-
+- if (len)
+- goto slave_sg_todev_fill_desc;
+- }
+- break;
+- case DMA_DEV_TO_MEM:
+- reg_width = __fls(sconfig->src_addr_width);
+- reg = sconfig->src_addr;
+- ctllo = (DWC_DEFAULT_CTLLO(chan)
+- | DWC_CTLL_SRC_WIDTH(reg_width)
+- | DWC_CTLL_DST_INC
+- | DWC_CTLL_SRC_FIX);
+-
+- ctllo |= sconfig->device_fc ? DWC_CTLL_FC(DW_DMA_FC_P_P2M) :
+- DWC_CTLL_FC(DW_DMA_FC_D_P2M);
+-
+- data_width = dw->data_width[dwc->dst_master];
+-
+- for_each_sg(sgl, sg, sg_len, i) {
+- struct dw_desc *desc;
+- u32 len, dlen, mem;
+-
+- mem = sg_dma_address(sg);
+- len = sg_dma_len(sg);
+-
+- mem_width = min_t(unsigned int,
+- data_width, dwc_fast_fls(mem | len));
+-
+-slave_sg_fromdev_fill_desc:
+- desc = dwc_desc_get(dwc);
+- if (!desc) {
+- dev_err(chan2dev(chan),
+- "not enough descriptors available\n");
+- goto err_desc_get;
+- }
+-
+- desc->lli.sar = reg;
+- desc->lli.dar = mem;
+- desc->lli.ctllo = ctllo | DWC_CTLL_DST_WIDTH(mem_width);
+- if ((len >> reg_width) > dwc->block_size) {
+- dlen = dwc->block_size << reg_width;
+- mem += dlen;
+- len -= dlen;
+- } else {
+- dlen = len;
+- len = 0;
+- }
+- desc->lli.ctlhi = dlen >> reg_width;
+- desc->len = dlen;
+-
+- if (!first) {
+- first = desc;
+- } else {
+- prev->lli.llp = desc->txd.phys;
+- list_add_tail(&desc->desc_node,
+- &first->tx_list);
+- }
+- prev = desc;
+- total_len += dlen;
+-
+- if (len)
+- goto slave_sg_fromdev_fill_desc;
+- }
+- break;
+- default:
+- return NULL;
+- }
+-
+- if (flags & DMA_PREP_INTERRUPT)
+- /* Trigger interrupt after last block */
+- prev->lli.ctllo |= DWC_CTLL_INT_EN;
+-
+- prev->lli.llp = 0;
+- first->total_len = total_len;
+-
+- return &first->txd;
+-
+-err_desc_get:
+- dwc_desc_put(dwc, first);
+- return NULL;
+-}
+-
+-/*
+- * Fix sconfig's burst size according to dw_dmac. We need to convert them as:
+- * 1 -> 0, 4 -> 1, 8 -> 2, 16 -> 3.
+- *
+- * NOTE: burst size 2 is not supported by controller.
+- *
+- * This can be done by finding least significant bit set: n & (n - 1)
+- */
+-static inline void convert_burst(u32 *maxburst)
+-{
+- if (*maxburst > 1)
+- *maxburst = fls(*maxburst) - 2;
+- else
+- *maxburst = 0;
+-}
+-
+-static int
+-set_runtime_config(struct dma_chan *chan, struct dma_slave_config *sconfig)
+-{
+- struct dw_dma_chan *dwc = to_dw_dma_chan(chan);
+-
+- /* Check if chan will be configured for slave transfers */
+- if (!is_slave_direction(sconfig->direction))
+- return -EINVAL;
+-
+- memcpy(&dwc->dma_sconfig, sconfig, sizeof(*sconfig));
+- dwc->direction = sconfig->direction;
+-
+- /* Take the request line from slave_id member */
+- if (dwc->request_line == ~0)
+- dwc->request_line = sconfig->slave_id;
+-
+- convert_burst(&dwc->dma_sconfig.src_maxburst);
+- convert_burst(&dwc->dma_sconfig.dst_maxburst);
+-
+- return 0;
+-}
+-
+-static inline void dwc_chan_pause(struct dw_dma_chan *dwc)
+-{
+- u32 cfglo = channel_readl(dwc, CFG_LO);
+- unsigned int count = 20; /* timeout iterations */
+-
+- channel_writel(dwc, CFG_LO, cfglo | DWC_CFGL_CH_SUSP);
+- while (!(channel_readl(dwc, CFG_LO) & DWC_CFGL_FIFO_EMPTY) && count--)
+- udelay(2);
+-
+- dwc->paused = true;
+-}
+-
+-static inline void dwc_chan_resume(struct dw_dma_chan *dwc)
+-{
+- u32 cfglo = channel_readl(dwc, CFG_LO);
+-
+- channel_writel(dwc, CFG_LO, cfglo & ~DWC_CFGL_CH_SUSP);
+-
+- dwc->paused = false;
+-}
+-
+-static int dwc_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
+- unsigned long arg)
+-{
+- struct dw_dma_chan *dwc = to_dw_dma_chan(chan);
+- struct dw_dma *dw = to_dw_dma(chan->device);
+- struct dw_desc *desc, *_desc;
+- unsigned long flags;
+- LIST_HEAD(list);
+-
+- if (cmd == DMA_PAUSE) {
+- spin_lock_irqsave(&dwc->lock, flags);
+-
+- dwc_chan_pause(dwc);
+-
+- spin_unlock_irqrestore(&dwc->lock, flags);
+- } else if (cmd == DMA_RESUME) {
+- if (!dwc->paused)
+- return 0;
+-
+- spin_lock_irqsave(&dwc->lock, flags);
+-
+- dwc_chan_resume(dwc);
+-
+- spin_unlock_irqrestore(&dwc->lock, flags);
+- } else if (cmd == DMA_TERMINATE_ALL) {
+- spin_lock_irqsave(&dwc->lock, flags);
+-
+- clear_bit(DW_DMA_IS_SOFT_LLP, &dwc->flags);
+-
+- dwc_chan_disable(dw, dwc);
+-
+- dwc_chan_resume(dwc);
+-
+- /* active_list entries will end up before queued entries */
+- list_splice_init(&dwc->queue, &list);
+- list_splice_init(&dwc->active_list, &list);
+-
+- spin_unlock_irqrestore(&dwc->lock, flags);
+-
+- /* Flush all pending and queued descriptors */
+- list_for_each_entry_safe(desc, _desc, &list, desc_node)
+- dwc_descriptor_complete(dwc, desc, false);
+- } else if (cmd == DMA_SLAVE_CONFIG) {
+- return set_runtime_config(chan, (struct dma_slave_config *)arg);
+- } else {
+- return -ENXIO;
+- }
+-
+- return 0;
+-}
+-
+-static inline u32 dwc_get_residue(struct dw_dma_chan *dwc)
+-{
+- unsigned long flags;
+- u32 residue;
+-
+- spin_lock_irqsave(&dwc->lock, flags);
+-
+- residue = dwc->residue;
+- if (test_bit(DW_DMA_IS_SOFT_LLP, &dwc->flags) && residue)
+- residue -= dwc_get_sent(dwc);
+-
+- spin_unlock_irqrestore(&dwc->lock, flags);
+- return residue;
+-}
+-
+-static enum dma_status
+-dwc_tx_status(struct dma_chan *chan,
+- dma_cookie_t cookie,
+- struct dma_tx_state *txstate)
+-{
+- struct dw_dma_chan *dwc = to_dw_dma_chan(chan);
+- enum dma_status ret;
+-
+- ret = dma_cookie_status(chan, cookie, txstate);
+- if (ret != DMA_SUCCESS) {
+- dwc_scan_descriptors(to_dw_dma(chan->device), dwc);
+-
+- ret = dma_cookie_status(chan, cookie, txstate);
+- }
+-
+- if (ret != DMA_SUCCESS)
+- dma_set_residue(txstate, dwc_get_residue(dwc));
+-
+- if (dwc->paused)
+- return DMA_PAUSED;
+-
+- return ret;
+-}
+-
+-static void dwc_issue_pending(struct dma_chan *chan)
+-{
+- struct dw_dma_chan *dwc = to_dw_dma_chan(chan);
+-
+- if (!list_empty(&dwc->queue))
+- dwc_scan_descriptors(to_dw_dma(chan->device), dwc);
+-}
+-
+-static int dwc_alloc_chan_resources(struct dma_chan *chan)
+-{
+- struct dw_dma_chan *dwc = to_dw_dma_chan(chan);
+- struct dw_dma *dw = to_dw_dma(chan->device);
+- struct dw_desc *desc;
+- int i;
+- unsigned long flags;
+-
+- dev_vdbg(chan2dev(chan), "%s\n", __func__);
+-
+- /* ASSERT: channel is idle */
+- if (dma_readl(dw, CH_EN) & dwc->mask) {
+- dev_dbg(chan2dev(chan), "DMA channel not idle?\n");
+- return -EIO;
+- }
+-
+- dma_cookie_init(chan);
+-
+- /*
+- * NOTE: some controllers may have additional features that we
+- * need to initialize here, like "scatter-gather" (which
+- * doesn't mean what you think it means), and status writeback.
+- */
+-
+- dwc_set_masters(dwc);
+-
+- spin_lock_irqsave(&dwc->lock, flags);
+- i = dwc->descs_allocated;
+- while (dwc->descs_allocated < NR_DESCS_PER_CHANNEL) {
+- dma_addr_t phys;
+-
+- spin_unlock_irqrestore(&dwc->lock, flags);
+-
+- desc = dma_pool_alloc(dw->desc_pool, GFP_ATOMIC, &phys);
+- if (!desc)
+- goto err_desc_alloc;
+-
+- memset(desc, 0, sizeof(struct dw_desc));
+-
+- INIT_LIST_HEAD(&desc->tx_list);
+- dma_async_tx_descriptor_init(&desc->txd, chan);
+- desc->txd.tx_submit = dwc_tx_submit;
+- desc->txd.flags = DMA_CTRL_ACK;
+- desc->txd.phys = phys;
+-
+- dwc_desc_put(dwc, desc);
+-
+- spin_lock_irqsave(&dwc->lock, flags);
+- i = ++dwc->descs_allocated;
+- }
+-
+- spin_unlock_irqrestore(&dwc->lock, flags);
+-
+- dev_dbg(chan2dev(chan), "%s: allocated %d descriptors\n", __func__, i);
+-
+- return i;
+-
+-err_desc_alloc:
+- dev_info(chan2dev(chan), "only allocated %d descriptors\n", i);
+-
+- return i;
+-}
+-
+-static void dwc_free_chan_resources(struct dma_chan *chan)
+-{
+- struct dw_dma_chan *dwc = to_dw_dma_chan(chan);
+- struct dw_dma *dw = to_dw_dma(chan->device);
+- struct dw_desc *desc, *_desc;
+- unsigned long flags;
+- LIST_HEAD(list);
+-
+- dev_dbg(chan2dev(chan), "%s: descs allocated=%u\n", __func__,
+- dwc->descs_allocated);
+-
+- /* ASSERT: channel is idle */
+- BUG_ON(!list_empty(&dwc->active_list));
+- BUG_ON(!list_empty(&dwc->queue));
+- BUG_ON(dma_readl(to_dw_dma(chan->device), CH_EN) & dwc->mask);
+-
+- spin_lock_irqsave(&dwc->lock, flags);
+- list_splice_init(&dwc->free_list, &list);
+- dwc->descs_allocated = 0;
+- dwc->initialized = false;
+- dwc->request_line = ~0;
+-
+- /* Disable interrupts */
+- channel_clear_bit(dw, MASK.XFER, dwc->mask);
+- channel_clear_bit(dw, MASK.ERROR, dwc->mask);
+-
+- spin_unlock_irqrestore(&dwc->lock, flags);
+-
+- list_for_each_entry_safe(desc, _desc, &list, desc_node) {
+- dev_vdbg(chan2dev(chan), " freeing descriptor %p\n", desc);
+- dma_pool_free(dw->desc_pool, desc, desc->txd.phys);
+- }
+-
+- dev_vdbg(chan2dev(chan), "%s: done\n", __func__);
+-}
+-
+-/*----------------------------------------------------------------------*/
+-
+-struct dw_dma_of_filter_args {
+- struct dw_dma *dw;
+- unsigned int req;
+- unsigned int src;
+- unsigned int dst;
+-};
+-
+-static bool dw_dma_of_filter(struct dma_chan *chan, void *param)
+-{
+- struct dw_dma_chan *dwc = to_dw_dma_chan(chan);
+- struct dw_dma_of_filter_args *fargs = param;
+-
+- /* Ensure the device matches our channel */
+- if (chan->device != &fargs->dw->dma)
+- return false;
+-
+- dwc->request_line = fargs->req;
+- dwc->src_master = fargs->src;
+- dwc->dst_master = fargs->dst;
+-
+- return true;
+-}
+-
+-static struct dma_chan *dw_dma_of_xlate(struct of_phandle_args *dma_spec,
+- struct of_dma *ofdma)
+-{
+- struct dw_dma *dw = ofdma->of_dma_data;
+- struct dw_dma_of_filter_args fargs = {
+- .dw = dw,
+- };
+- dma_cap_mask_t cap;
+-
+- if (dma_spec->args_count != 3)
+- return NULL;
+-
+- fargs.req = dma_spec->args[0];
+- fargs.src = dma_spec->args[1];
+- fargs.dst = dma_spec->args[2];
+-
+- if (WARN_ON(fargs.req >= DW_DMA_MAX_NR_REQUESTS ||
+- fargs.src >= dw->nr_masters ||
+- fargs.dst >= dw->nr_masters))
+- return NULL;
+-
+- dma_cap_zero(cap);
+- dma_cap_set(DMA_SLAVE, cap);
+-
+- /* TODO: there should be a simpler way to do this */
+- return dma_request_channel(cap, dw_dma_of_filter, &fargs);
+-}
+-
+-#ifdef CONFIG_ACPI
+-static bool dw_dma_acpi_filter(struct dma_chan *chan, void *param)
+-{
+- struct dw_dma_chan *dwc = to_dw_dma_chan(chan);
+- struct acpi_dma_spec *dma_spec = param;
+-
+- if (chan->device->dev != dma_spec->dev ||
+- chan->chan_id != dma_spec->chan_id)
+- return false;
+-
+- dwc->request_line = dma_spec->slave_id;
+- dwc->src_master = dwc_get_sms(NULL);
+- dwc->dst_master = dwc_get_dms(NULL);
+-
+- return true;
+-}
+-
+-static void dw_dma_acpi_controller_register(struct dw_dma *dw)
+-{
+- struct device *dev = dw->dma.dev;
+- struct acpi_dma_filter_info *info;
+- int ret;
+-
+- info = devm_kzalloc(dev, sizeof(*info), GFP_KERNEL);
+- if (!info)
+- return;
+-
+- dma_cap_zero(info->dma_cap);
+- dma_cap_set(DMA_SLAVE, info->dma_cap);
+- info->filter_fn = dw_dma_acpi_filter;
+-
+- ret = devm_acpi_dma_controller_register(dev, acpi_dma_simple_xlate,
+- info);
+- if (ret)
+- dev_err(dev, "could not register acpi_dma_controller\n");
+-}
+-#else /* !CONFIG_ACPI */
+-static inline void dw_dma_acpi_controller_register(struct dw_dma *dw) {}
+-#endif /* !CONFIG_ACPI */
+-
+-/* --------------------- Cyclic DMA API extensions -------------------- */
+-
+-/**
+- * dw_dma_cyclic_start - start the cyclic DMA transfer
+- * @chan: the DMA channel to start
+- *
+- * Must be called with soft interrupts disabled. Returns zero on success or
+- * -errno on failure.
+- */
+-int dw_dma_cyclic_start(struct dma_chan *chan)
+-{
+- struct dw_dma_chan *dwc = to_dw_dma_chan(chan);
+- struct dw_dma *dw = to_dw_dma(dwc->chan.device);
+- unsigned long flags;
+-
+- if (!test_bit(DW_DMA_IS_CYCLIC, &dwc->flags)) {
+- dev_err(chan2dev(&dwc->chan), "missing prep for cyclic DMA\n");
+- return -ENODEV;
+- }
+-
+- spin_lock_irqsave(&dwc->lock, flags);
+-
+- /* Assert channel is idle */
+- if (dma_readl(dw, CH_EN) & dwc->mask) {
+- dev_err(chan2dev(&dwc->chan),
+- "BUG: Attempted to start non-idle channel\n");
+- dwc_dump_chan_regs(dwc);
+- spin_unlock_irqrestore(&dwc->lock, flags);
+- return -EBUSY;
+- }
+-
+- dma_writel(dw, CLEAR.ERROR, dwc->mask);
+- dma_writel(dw, CLEAR.XFER, dwc->mask);
+-
+- /* Setup DMAC channel registers */
+- channel_writel(dwc, LLP, dwc->cdesc->desc[0]->txd.phys);
+- channel_writel(dwc, CTL_LO, DWC_CTLL_LLP_D_EN | DWC_CTLL_LLP_S_EN);
+- channel_writel(dwc, CTL_HI, 0);
+-
+- channel_set_bit(dw, CH_EN, dwc->mask);
+-
+- spin_unlock_irqrestore(&dwc->lock, flags);
+-
+- return 0;
+-}
+-EXPORT_SYMBOL(dw_dma_cyclic_start);
+-
+-/**
+- * dw_dma_cyclic_stop - stop the cyclic DMA transfer
+- * @chan: the DMA channel to stop
+- *
+- * Must be called with soft interrupts disabled.
+- */
+-void dw_dma_cyclic_stop(struct dma_chan *chan)
+-{
+- struct dw_dma_chan *dwc = to_dw_dma_chan(chan);
+- struct dw_dma *dw = to_dw_dma(dwc->chan.device);
+- unsigned long flags;
+-
+- spin_lock_irqsave(&dwc->lock, flags);
+-
+- dwc_chan_disable(dw, dwc);
+-
+- spin_unlock_irqrestore(&dwc->lock, flags);
+-}
+-EXPORT_SYMBOL(dw_dma_cyclic_stop);
+-
+-/**
+- * dw_dma_cyclic_prep - prepare the cyclic DMA transfer
+- * @chan: the DMA channel to prepare
+- * @buf_addr: physical DMA address where the buffer starts
+- * @buf_len: total number of bytes for the entire buffer
+- * @period_len: number of bytes for each period
+- * @direction: transfer direction, to or from device
+- *
+- * Must be called before trying to start the transfer. Returns a valid struct
+- * dw_cyclic_desc if successful or an ERR_PTR(-errno) if not successful.
+- */
+-struct dw_cyclic_desc *dw_dma_cyclic_prep(struct dma_chan *chan,
+- dma_addr_t buf_addr, size_t buf_len, size_t period_len,
+- enum dma_transfer_direction direction)
+-{
+- struct dw_dma_chan *dwc = to_dw_dma_chan(chan);
+- struct dma_slave_config *sconfig = &dwc->dma_sconfig;
+- struct dw_cyclic_desc *cdesc;
+- struct dw_cyclic_desc *retval = NULL;
+- struct dw_desc *desc;
+- struct dw_desc *last = NULL;
+- unsigned long was_cyclic;
+- unsigned int reg_width;
+- unsigned int periods;
+- unsigned int i;
+- unsigned long flags;
+-
+- spin_lock_irqsave(&dwc->lock, flags);
+- if (dwc->nollp) {
+- spin_unlock_irqrestore(&dwc->lock, flags);
+- dev_dbg(chan2dev(&dwc->chan),
+- "channel doesn't support LLP transfers\n");
+- return ERR_PTR(-EINVAL);
+- }
+-
+- if (!list_empty(&dwc->queue) || !list_empty(&dwc->active_list)) {
+- spin_unlock_irqrestore(&dwc->lock, flags);
+- dev_dbg(chan2dev(&dwc->chan),
+- "queue and/or active list are not empty\n");
+- return ERR_PTR(-EBUSY);
+- }
+-
+- was_cyclic = test_and_set_bit(DW_DMA_IS_CYCLIC, &dwc->flags);
+- spin_unlock_irqrestore(&dwc->lock, flags);
+- if (was_cyclic) {
+- dev_dbg(chan2dev(&dwc->chan),
+- "channel already prepared for cyclic DMA\n");
+- return ERR_PTR(-EBUSY);
+- }
+-
+- retval = ERR_PTR(-EINVAL);
+-
+- if (unlikely(!is_slave_direction(direction)))
+- goto out_err;
+-
+- dwc->direction = direction;
+-
+- if (direction == DMA_MEM_TO_DEV)
+- reg_width = __ffs(sconfig->dst_addr_width);
+- else
+- reg_width = __ffs(sconfig->src_addr_width);
+-
+- periods = buf_len / period_len;
+-
+- /* Check for too big/unaligned periods and unaligned DMA buffer. */
+- if (period_len > (dwc->block_size << reg_width))
+- goto out_err;
+- if (unlikely(period_len & ((1 << reg_width) - 1)))
+- goto out_err;
+- if (unlikely(buf_addr & ((1 << reg_width) - 1)))
+- goto out_err;
+-
+- retval = ERR_PTR(-ENOMEM);
+-
+- if (periods > NR_DESCS_PER_CHANNEL)
+- goto out_err;
+-
+- cdesc = kzalloc(sizeof(struct dw_cyclic_desc), GFP_KERNEL);
+- if (!cdesc)
+- goto out_err;
+-
+- cdesc->desc = kzalloc(sizeof(struct dw_desc *) * periods, GFP_KERNEL);
+- if (!cdesc->desc)
+- goto out_err_alloc;
+-
+- for (i = 0; i < periods; i++) {
+- desc = dwc_desc_get(dwc);
+- if (!desc)
+- goto out_err_desc_get;
+-
+- switch (direction) {
+- case DMA_MEM_TO_DEV:
+- desc->lli.dar = sconfig->dst_addr;
+- desc->lli.sar = buf_addr + (period_len * i);
+- desc->lli.ctllo = (DWC_DEFAULT_CTLLO(chan)
+- | DWC_CTLL_DST_WIDTH(reg_width)
+- | DWC_CTLL_SRC_WIDTH(reg_width)
+- | DWC_CTLL_DST_FIX
+- | DWC_CTLL_SRC_INC
+- | DWC_CTLL_INT_EN);
+-
+- desc->lli.ctllo |= sconfig->device_fc ?
+- DWC_CTLL_FC(DW_DMA_FC_P_M2P) :
+- DWC_CTLL_FC(DW_DMA_FC_D_M2P);
+-
+- break;
+- case DMA_DEV_TO_MEM:
+- desc->lli.dar = buf_addr + (period_len * i);
+- desc->lli.sar = sconfig->src_addr;
+- desc->lli.ctllo = (DWC_DEFAULT_CTLLO(chan)
+- | DWC_CTLL_SRC_WIDTH(reg_width)
+- | DWC_CTLL_DST_WIDTH(reg_width)
+- | DWC_CTLL_DST_INC
+- | DWC_CTLL_SRC_FIX
+- | DWC_CTLL_INT_EN);
+-
+- desc->lli.ctllo |= sconfig->device_fc ?
+- DWC_CTLL_FC(DW_DMA_FC_P_P2M) :
+- DWC_CTLL_FC(DW_DMA_FC_D_P2M);
+-
+- break;
+- default:
+- break;
+- }
+-
+- desc->lli.ctlhi = (period_len >> reg_width);
+- cdesc->desc[i] = desc;
+-
+- if (last)
+- last->lli.llp = desc->txd.phys;
+-
+- last = desc;
+- }
+-
+- /* Let's make a cyclic list */
+- last->lli.llp = cdesc->desc[0]->txd.phys;
+-
+- dev_dbg(chan2dev(&dwc->chan), "cyclic prepared buf 0x%llx len %zu "
+- "period %zu periods %d\n", (unsigned long long)buf_addr,
+- buf_len, period_len, periods);
+-
+- cdesc->periods = periods;
+- dwc->cdesc = cdesc;
+-
+- return cdesc;
+-
+-out_err_desc_get:
+- while (i--)
+- dwc_desc_put(dwc, cdesc->desc[i]);
+-out_err_alloc:
+- kfree(cdesc);
+-out_err:
+- clear_bit(DW_DMA_IS_CYCLIC, &dwc->flags);
+- return (struct dw_cyclic_desc *)retval;
+-}
+-EXPORT_SYMBOL(dw_dma_cyclic_prep);
+-
+-/**
+- * dw_dma_cyclic_free - free a prepared cyclic DMA transfer
+- * @chan: the DMA channel to free
+- */
+-void dw_dma_cyclic_free(struct dma_chan *chan)
+-{
+- struct dw_dma_chan *dwc = to_dw_dma_chan(chan);
+- struct dw_dma *dw = to_dw_dma(dwc->chan.device);
+- struct dw_cyclic_desc *cdesc = dwc->cdesc;
+- int i;
+- unsigned long flags;
+-
+- dev_dbg(chan2dev(&dwc->chan), "%s\n", __func__);
+-
+- if (!cdesc)
+- return;
+-
+- spin_lock_irqsave(&dwc->lock, flags);
+-
+- dwc_chan_disable(dw, dwc);
+-
+- dma_writel(dw, CLEAR.ERROR, dwc->mask);
+- dma_writel(dw, CLEAR.XFER, dwc->mask);
+-
+- spin_unlock_irqrestore(&dwc->lock, flags);
+-
+- for (i = 0; i < cdesc->periods; i++)
+- dwc_desc_put(dwc, cdesc->desc[i]);
+-
+- kfree(cdesc->desc);
+- kfree(cdesc);
+-
+- clear_bit(DW_DMA_IS_CYCLIC, &dwc->flags);
+-}
+-EXPORT_SYMBOL(dw_dma_cyclic_free);
+-
+-/*----------------------------------------------------------------------*/
+-
+-static void dw_dma_off(struct dw_dma *dw)
+-{
+- int i;
+-
+- dma_writel(dw, CFG, 0);
+-
+- channel_clear_bit(dw, MASK.XFER, dw->all_chan_mask);
+- channel_clear_bit(dw, MASK.SRC_TRAN, dw->all_chan_mask);
+- channel_clear_bit(dw, MASK.DST_TRAN, dw->all_chan_mask);
+- channel_clear_bit(dw, MASK.ERROR, dw->all_chan_mask);
+-
+- while (dma_readl(dw, CFG) & DW_CFG_DMA_EN)
+- cpu_relax();
+-
+- for (i = 0; i < dw->dma.chancnt; i++)
+- dw->chan[i].initialized = false;
+-}
+-
+-#ifdef CONFIG_OF
+-static struct dw_dma_platform_data *
+-dw_dma_parse_dt(struct platform_device *pdev)
+-{
+- struct device_node *np = pdev->dev.of_node;
+- struct dw_dma_platform_data *pdata;
+- u32 tmp, arr[4];
+-
+- if (!np) {
+- dev_err(&pdev->dev, "Missing DT data\n");
+- return NULL;
+- }
+-
+- pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
+- if (!pdata)
+- return NULL;
+-
+- if (of_property_read_u32(np, "dma-channels", &pdata->nr_channels))
+- return NULL;
+-
+- if (of_property_read_bool(np, "is_private"))
+- pdata->is_private = true;
+-
+- if (!of_property_read_u32(np, "chan_allocation_order", &tmp))
+- pdata->chan_allocation_order = (unsigned char)tmp;
+-
+- if (!of_property_read_u32(np, "chan_priority", &tmp))
+- pdata->chan_priority = tmp;
+-
+- if (!of_property_read_u32(np, "block_size", &tmp))
+- pdata->block_size = tmp;
+-
+- if (!of_property_read_u32(np, "dma-masters", &tmp)) {
+- if (tmp > 4)
+- return NULL;
+-
+- pdata->nr_masters = tmp;
+- }
+-
+- if (!of_property_read_u32_array(np, "data_width", arr,
+- pdata->nr_masters))
+- for (tmp = 0; tmp < pdata->nr_masters; tmp++)
+- pdata->data_width[tmp] = arr[tmp];
+-
+- return pdata;
+-}
+-#else
+-static inline struct dw_dma_platform_data *
+-dw_dma_parse_dt(struct platform_device *pdev)
+-{
+- return NULL;
+-}
+-#endif
+-
+-static int dw_probe(struct platform_device *pdev)
+-{
+- struct dw_dma_platform_data *pdata;
+- struct resource *io;
+- struct dw_dma *dw;
+- size_t size;
+- void __iomem *regs;
+- bool autocfg;
+- unsigned int dw_params;
+- unsigned int nr_channels;
+- unsigned int max_blk_size = 0;
+- int irq;
+- int err;
+- int i;
+-
+- irq = platform_get_irq(pdev, 0);
+- if (irq < 0)
+- return irq;
+-
+- io = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+- regs = devm_ioremap_resource(&pdev->dev, io);
+- if (IS_ERR(regs))
+- return PTR_ERR(regs);
+-
+- /* Apply default dma_mask if needed */
+- if (!pdev->dev.dma_mask) {
+- pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask;
+- pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
+- }
+-
+- dw_params = dma_read_byaddr(regs, DW_PARAMS);
+- autocfg = dw_params >> DW_PARAMS_EN & 0x1;
+-
+- dev_dbg(&pdev->dev, "DW_PARAMS: 0x%08x\n", dw_params);
+-
+- pdata = dev_get_platdata(&pdev->dev);
+- if (!pdata)
+- pdata = dw_dma_parse_dt(pdev);
+-
+- if (!pdata && autocfg) {
+- pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
+- if (!pdata)
+- return -ENOMEM;
+-
+- /* Fill platform data with the default values */
+- pdata->is_private = true;
+- pdata->chan_allocation_order = CHAN_ALLOCATION_ASCENDING;
+- pdata->chan_priority = CHAN_PRIORITY_ASCENDING;
+- } else if (!pdata || pdata->nr_channels > DW_DMA_MAX_NR_CHANNELS)
+- return -EINVAL;
+-
+- if (autocfg)
+- nr_channels = (dw_params >> DW_PARAMS_NR_CHAN & 0x7) + 1;
+- else
+- nr_channels = pdata->nr_channels;
+-
+- size = sizeof(struct dw_dma) + nr_channels * sizeof(struct dw_dma_chan);
+- dw = devm_kzalloc(&pdev->dev, size, GFP_KERNEL);
+- if (!dw)
+- return -ENOMEM;
+-
+- dw->clk = devm_clk_get(&pdev->dev, "hclk");
+- if (IS_ERR(dw->clk))
+- return PTR_ERR(dw->clk);
+- clk_prepare_enable(dw->clk);
+-
+- dw->regs = regs;
+-
+- /* Get hardware configuration parameters */
+- if (autocfg) {
+- max_blk_size = dma_readl(dw, MAX_BLK_SIZE);
+-
+- dw->nr_masters = (dw_params >> DW_PARAMS_NR_MASTER & 3) + 1;
+- for (i = 0; i < dw->nr_masters; i++) {
+- dw->data_width[i] =
+- (dw_params >> DW_PARAMS_DATA_WIDTH(i) & 3) + 2;
+- }
+- } else {
+- dw->nr_masters = pdata->nr_masters;
+- memcpy(dw->data_width, pdata->data_width, 4);
+- }
+-
+- /* Calculate all channel mask before DMA setup */
+- dw->all_chan_mask = (1 << nr_channels) - 1;
+-
+- /* Force dma off, just in case */
+- dw_dma_off(dw);
+-
+- /* Disable BLOCK interrupts as well */
+- channel_clear_bit(dw, MASK.BLOCK, dw->all_chan_mask);
+-
+- err = devm_request_irq(&pdev->dev, irq, dw_dma_interrupt, 0,
+- "dw_dmac", dw);
+- if (err)
+- return err;
+-
+- platform_set_drvdata(pdev, dw);
+-
+- /* Create a pool of consistent memory blocks for hardware descriptors */
+- dw->desc_pool = dmam_pool_create("dw_dmac_desc_pool", &pdev->dev,
+- sizeof(struct dw_desc), 4, 0);
+- if (!dw->desc_pool) {
+- dev_err(&pdev->dev, "No memory for descriptors dma pool\n");
+- return -ENOMEM;
+- }
+-
+- tasklet_init(&dw->tasklet, dw_dma_tasklet, (unsigned long)dw);
+-
+- INIT_LIST_HEAD(&dw->dma.channels);
+- for (i = 0; i < nr_channels; i++) {
+- struct dw_dma_chan *dwc = &dw->chan[i];
+- int r = nr_channels - i - 1;
+-
+- dwc->chan.device = &dw->dma;
+- dma_cookie_init(&dwc->chan);
+- if (pdata->chan_allocation_order == CHAN_ALLOCATION_ASCENDING)
+- list_add_tail(&dwc->chan.device_node,
+- &dw->dma.channels);
+- else
+- list_add(&dwc->chan.device_node, &dw->dma.channels);
+-
+- /* 7 is highest priority & 0 is lowest. */
+- if (pdata->chan_priority == CHAN_PRIORITY_ASCENDING)
+- dwc->priority = r;
+- else
+- dwc->priority = i;
+-
+- dwc->ch_regs = &__dw_regs(dw)->CHAN[i];
+- spin_lock_init(&dwc->lock);
+- dwc->mask = 1 << i;
+-
+- INIT_LIST_HEAD(&dwc->active_list);
+- INIT_LIST_HEAD(&dwc->queue);
+- INIT_LIST_HEAD(&dwc->free_list);
+-
+- channel_clear_bit(dw, CH_EN, dwc->mask);
+-
+- dwc->direction = DMA_TRANS_NONE;
+- dwc->request_line = ~0;
+-
+- /* Hardware configuration */
+- if (autocfg) {
+- unsigned int dwc_params;
+-
+- dwc_params = dma_read_byaddr(regs + r * sizeof(u32),
+- DWC_PARAMS);
+-
+- dev_dbg(&pdev->dev, "DWC_PARAMS[%d]: 0x%08x\n", i,
+- dwc_params);
+-
+- /* Decode maximum block size for given channel. The
+- * stored 4 bit value represents blocks from 0x00 for 3
+- * up to 0x0a for 4095. */
+- dwc->block_size =
+- (4 << ((max_blk_size >> 4 * i) & 0xf)) - 1;
+- dwc->nollp =
+- (dwc_params >> DWC_PARAMS_MBLK_EN & 0x1) == 0;
+- } else {
+- dwc->block_size = pdata->block_size;
+-
+- /* Check if channel supports multi block transfer */
+- channel_writel(dwc, LLP, 0xfffffffc);
+- dwc->nollp =
+- (channel_readl(dwc, LLP) & 0xfffffffc) == 0;
+- channel_writel(dwc, LLP, 0);
+- }
+- }
+-
+- /* Clear all interrupts on all channels. */
+- dma_writel(dw, CLEAR.XFER, dw->all_chan_mask);
+- dma_writel(dw, CLEAR.BLOCK, dw->all_chan_mask);
+- dma_writel(dw, CLEAR.SRC_TRAN, dw->all_chan_mask);
+- dma_writel(dw, CLEAR.DST_TRAN, dw->all_chan_mask);
+- dma_writel(dw, CLEAR.ERROR, dw->all_chan_mask);
+-
+- dma_cap_set(DMA_MEMCPY, dw->dma.cap_mask);
+- dma_cap_set(DMA_SLAVE, dw->dma.cap_mask);
+- if (pdata->is_private)
+- dma_cap_set(DMA_PRIVATE, dw->dma.cap_mask);
+- dw->dma.dev = &pdev->dev;
+- dw->dma.device_alloc_chan_resources = dwc_alloc_chan_resources;
+- dw->dma.device_free_chan_resources = dwc_free_chan_resources;
+-
+- dw->dma.device_prep_dma_memcpy = dwc_prep_dma_memcpy;
+-
+- dw->dma.device_prep_slave_sg = dwc_prep_slave_sg;
+- dw->dma.device_control = dwc_control;
+-
+- dw->dma.device_tx_status = dwc_tx_status;
+- dw->dma.device_issue_pending = dwc_issue_pending;
+-
+- dma_writel(dw, CFG, DW_CFG_DMA_EN);
+-
+- dev_info(&pdev->dev, "DesignWare DMA Controller, %d channels\n",
+- nr_channels);
+-
+- dma_async_device_register(&dw->dma);
+-
+- if (pdev->dev.of_node) {
+- err = of_dma_controller_register(pdev->dev.of_node,
+- dw_dma_of_xlate, dw);
+- if (err)
+- dev_err(&pdev->dev,
+- "could not register of_dma_controller\n");
+- }
+-
+- if (ACPI_HANDLE(&pdev->dev))
+- dw_dma_acpi_controller_register(dw);
+-
+- return 0;
+-}
+-
+-static int dw_remove(struct platform_device *pdev)
+-{
+- struct dw_dma *dw = platform_get_drvdata(pdev);
+- struct dw_dma_chan *dwc, *_dwc;
+-
+- if (pdev->dev.of_node)
+- of_dma_controller_free(pdev->dev.of_node);
+- dw_dma_off(dw);
+- dma_async_device_unregister(&dw->dma);
+-
+- tasklet_kill(&dw->tasklet);
+-
+- list_for_each_entry_safe(dwc, _dwc, &dw->dma.channels,
+- chan.device_node) {
+- list_del(&dwc->chan.device_node);
+- channel_clear_bit(dw, CH_EN, dwc->mask);
+- }
+-
+- return 0;
+-}
+-
+-static void dw_shutdown(struct platform_device *pdev)
+-{
+- struct dw_dma *dw = platform_get_drvdata(pdev);
+-
+- dw_dma_off(dw);
+- clk_disable_unprepare(dw->clk);
+-}
+-
+-static int dw_suspend_noirq(struct device *dev)
+-{
+- struct platform_device *pdev = to_platform_device(dev);
+- struct dw_dma *dw = platform_get_drvdata(pdev);
+-
+- dw_dma_off(dw);
+- clk_disable_unprepare(dw->clk);
+-
+- return 0;
+-}
+-
+-static int dw_resume_noirq(struct device *dev)
+-{
+- struct platform_device *pdev = to_platform_device(dev);
+- struct dw_dma *dw = platform_get_drvdata(pdev);
+-
+- clk_prepare_enable(dw->clk);
+- dma_writel(dw, CFG, DW_CFG_DMA_EN);
+-
+- return 0;
+-}
+-
+-static const struct dev_pm_ops dw_dev_pm_ops = {
+- .suspend_noirq = dw_suspend_noirq,
+- .resume_noirq = dw_resume_noirq,
+- .freeze_noirq = dw_suspend_noirq,
+- .thaw_noirq = dw_resume_noirq,
+- .restore_noirq = dw_resume_noirq,
+- .poweroff_noirq = dw_suspend_noirq,
+-};
+-
+-#ifdef CONFIG_OF
+-static const struct of_device_id dw_dma_of_id_table[] = {
+- { .compatible = "snps,dma-spear1340" },
+- {}
+-};
+-MODULE_DEVICE_TABLE(of, dw_dma_of_id_table);
+-#endif
+-
+-#ifdef CONFIG_ACPI
+-static const struct acpi_device_id dw_dma_acpi_id_table[] = {
+- { "INTL9C60", 0 },
+- { }
+-};
+-#endif
+-
+-static struct platform_driver dw_driver = {
+- .probe = dw_probe,
+- .remove = dw_remove,
+- .shutdown = dw_shutdown,
+- .driver = {
+- .name = "dw_dmac",
+- .pm = &dw_dev_pm_ops,
+- .of_match_table = of_match_ptr(dw_dma_of_id_table),
+- .acpi_match_table = ACPI_PTR(dw_dma_acpi_id_table),
+- },
+-};
+-
+-static int __init dw_init(void)
+-{
+- return platform_driver_register(&dw_driver);
+-}
+-subsys_initcall(dw_init);
+-
+-static void __exit dw_exit(void)
+-{
+- platform_driver_unregister(&dw_driver);
+-}
+-module_exit(dw_exit);
+-
+-MODULE_LICENSE("GPL v2");
+-MODULE_DESCRIPTION("Synopsys DesignWare DMA Controller driver");
+-MODULE_AUTHOR("Haavard Skinnemoen (Atmel)");
+-MODULE_AUTHOR("Viresh Kumar <viresh.linux@gmail.com>");
+--- a/drivers/dma/dw_dmac_regs.h
++++ /dev/null
+@@ -1,311 +0,0 @@
+-/*
+- * Driver for the Synopsys DesignWare AHB DMA Controller
+- *
+- * Copyright (C) 2005-2007 Atmel Corporation
+- * Copyright (C) 2010-2011 ST Microelectronics
+- *
+- * 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/dw_dmac.h>
+-
+-#define DW_DMA_MAX_NR_CHANNELS 8
+-#define DW_DMA_MAX_NR_REQUESTS 16
+-
+-/* flow controller */
+-enum dw_dma_fc {
+- DW_DMA_FC_D_M2M,
+- DW_DMA_FC_D_M2P,
+- DW_DMA_FC_D_P2M,
+- DW_DMA_FC_D_P2P,
+- DW_DMA_FC_P_P2M,
+- DW_DMA_FC_SP_P2P,
+- DW_DMA_FC_P_M2P,
+- DW_DMA_FC_DP_P2P,
+-};
+-
+-/*
+- * Redefine this macro to handle differences between 32- and 64-bit
+- * addressing, big vs. little endian, etc.
+- */
+-#define DW_REG(name) u32 name; u32 __pad_##name
+-
+-/* Hardware register definitions. */
+-struct dw_dma_chan_regs {
+- DW_REG(SAR); /* Source Address Register */
+- DW_REG(DAR); /* Destination Address Register */
+- DW_REG(LLP); /* Linked List Pointer */
+- u32 CTL_LO; /* Control Register Low */
+- u32 CTL_HI; /* Control Register High */
+- DW_REG(SSTAT);
+- DW_REG(DSTAT);
+- DW_REG(SSTATAR);
+- DW_REG(DSTATAR);
+- u32 CFG_LO; /* Configuration Register Low */
+- u32 CFG_HI; /* Configuration Register High */
+- DW_REG(SGR);
+- DW_REG(DSR);
+-};
+-
+-struct dw_dma_irq_regs {
+- DW_REG(XFER);
+- DW_REG(BLOCK);
+- DW_REG(SRC_TRAN);
+- DW_REG(DST_TRAN);
+- DW_REG(ERROR);
+-};
+-
+-struct dw_dma_regs {
+- /* per-channel registers */
+- struct dw_dma_chan_regs CHAN[DW_DMA_MAX_NR_CHANNELS];
+-
+- /* irq handling */
+- struct dw_dma_irq_regs RAW; /* r */
+- struct dw_dma_irq_regs STATUS; /* r (raw & mask) */
+- struct dw_dma_irq_regs MASK; /* rw (set = irq enabled) */
+- struct dw_dma_irq_regs CLEAR; /* w (ack, affects "raw") */
+-
+- DW_REG(STATUS_INT); /* r */
+-
+- /* software handshaking */
+- DW_REG(REQ_SRC);
+- DW_REG(REQ_DST);
+- DW_REG(SGL_REQ_SRC);
+- DW_REG(SGL_REQ_DST);
+- DW_REG(LAST_SRC);
+- DW_REG(LAST_DST);
+-
+- /* miscellaneous */
+- DW_REG(CFG);
+- DW_REG(CH_EN);
+- DW_REG(ID);
+- DW_REG(TEST);
+-
+- /* reserved */
+- DW_REG(__reserved0);
+- DW_REG(__reserved1);
+-
+- /* optional encoded params, 0x3c8..0x3f7 */
+- u32 __reserved;
+-
+- /* per-channel configuration registers */
+- u32 DWC_PARAMS[DW_DMA_MAX_NR_CHANNELS];
+- u32 MULTI_BLK_TYPE;
+- u32 MAX_BLK_SIZE;
+-
+- /* top-level parameters */
+- u32 DW_PARAMS;
+-};
+-
+-#ifdef CONFIG_DW_DMAC_BIG_ENDIAN_IO
+-#define dma_readl_native ioread32be
+-#define dma_writel_native iowrite32be
+-#else
+-#define dma_readl_native readl
+-#define dma_writel_native writel
+-#endif
+-
+-/* To access the registers in early stage of probe */
+-#define dma_read_byaddr(addr, name) \
+- dma_readl_native((addr) + offsetof(struct dw_dma_regs, name))
+-
+-/* Bitfields in DW_PARAMS */
+-#define DW_PARAMS_NR_CHAN 8 /* number of channels */
+-#define DW_PARAMS_NR_MASTER 11 /* number of AHB masters */
+-#define DW_PARAMS_DATA_WIDTH(n) (15 + 2 * (n))
+-#define DW_PARAMS_DATA_WIDTH1 15 /* master 1 data width */
+-#define DW_PARAMS_DATA_WIDTH2 17 /* master 2 data width */
+-#define DW_PARAMS_DATA_WIDTH3 19 /* master 3 data width */
+-#define DW_PARAMS_DATA_WIDTH4 21 /* master 4 data width */
+-#define DW_PARAMS_EN 28 /* encoded parameters */
+-
+-/* Bitfields in DWC_PARAMS */
+-#define DWC_PARAMS_MBLK_EN 11 /* multi block transfer */
+-
+-/* Bitfields in CTL_LO */
+-#define DWC_CTLL_INT_EN (1 << 0) /* irqs enabled? */
+-#define DWC_CTLL_DST_WIDTH(n) ((n)<<1) /* bytes per element */
+-#define DWC_CTLL_SRC_WIDTH(n) ((n)<<4)
+-#define DWC_CTLL_DST_INC (0<<7) /* DAR update/not */
+-#define DWC_CTLL_DST_DEC (1<<7)
+-#define DWC_CTLL_DST_FIX (2<<7)
+-#define DWC_CTLL_SRC_INC (0<<7) /* SAR update/not */
+-#define DWC_CTLL_SRC_DEC (1<<9)
+-#define DWC_CTLL_SRC_FIX (2<<9)
+-#define DWC_CTLL_DST_MSIZE(n) ((n)<<11) /* burst, #elements */
+-#define DWC_CTLL_SRC_MSIZE(n) ((n)<<14)
+-#define DWC_CTLL_S_GATH_EN (1 << 17) /* src gather, !FIX */
+-#define DWC_CTLL_D_SCAT_EN (1 << 18) /* dst scatter, !FIX */
+-#define DWC_CTLL_FC(n) ((n) << 20)
+-#define DWC_CTLL_FC_M2M (0 << 20) /* mem-to-mem */
+-#define DWC_CTLL_FC_M2P (1 << 20) /* mem-to-periph */
+-#define DWC_CTLL_FC_P2M (2 << 20) /* periph-to-mem */
+-#define DWC_CTLL_FC_P2P (3 << 20) /* periph-to-periph */
+-/* plus 4 transfer types for peripheral-as-flow-controller */
+-#define DWC_CTLL_DMS(n) ((n)<<23) /* dst master select */
+-#define DWC_CTLL_SMS(n) ((n)<<25) /* src master select */
+-#define DWC_CTLL_LLP_D_EN (1 << 27) /* dest block chain */
+-#define DWC_CTLL_LLP_S_EN (1 << 28) /* src block chain */
+-
+-/* Bitfields in CTL_HI */
+-#define DWC_CTLH_DONE 0x00001000
+-#define DWC_CTLH_BLOCK_TS_MASK 0x00000fff
+-
+-/* Bitfields in CFG_LO. Platform-configurable bits are in <linux/dw_dmac.h> */
+-#define DWC_CFGL_CH_PRIOR_MASK (0x7 << 5) /* priority mask */
+-#define DWC_CFGL_CH_PRIOR(x) ((x) << 5) /* priority */
+-#define DWC_CFGL_CH_SUSP (1 << 8) /* pause xfer */
+-#define DWC_CFGL_FIFO_EMPTY (1 << 9) /* pause xfer */
+-#define DWC_CFGL_HS_DST (1 << 10) /* handshake w/dst */
+-#define DWC_CFGL_HS_SRC (1 << 11) /* handshake w/src */
+-#define DWC_CFGL_MAX_BURST(x) ((x) << 20)
+-#define DWC_CFGL_RELOAD_SAR (1 << 30)
+-#define DWC_CFGL_RELOAD_DAR (1 << 31)
+-
+-/* Bitfields in CFG_HI. Platform-configurable bits are in <linux/dw_dmac.h> */
+-#define DWC_CFGH_DS_UPD_EN (1 << 5)
+-#define DWC_CFGH_SS_UPD_EN (1 << 6)
+-
+-/* Bitfields in SGR */
+-#define DWC_SGR_SGI(x) ((x) << 0)
+-#define DWC_SGR_SGC(x) ((x) << 20)
+-
+-/* Bitfields in DSR */
+-#define DWC_DSR_DSI(x) ((x) << 0)
+-#define DWC_DSR_DSC(x) ((x) << 20)
+-
+-/* Bitfields in CFG */
+-#define DW_CFG_DMA_EN (1 << 0)
+-
+-enum dw_dmac_flags {
+- DW_DMA_IS_CYCLIC = 0,
+- DW_DMA_IS_SOFT_LLP = 1,
+-};
+-
+-struct dw_dma_chan {
+- struct dma_chan chan;
+- void __iomem *ch_regs;
+- u8 mask;
+- u8 priority;
+- enum dma_transfer_direction direction;
+- bool paused;
+- bool initialized;
+-
+- /* software emulation of the LLP transfers */
+- struct list_head *tx_node_active;
+-
+- spinlock_t lock;
+-
+- /* these other elements are all protected by lock */
+- unsigned long flags;
+- struct list_head active_list;
+- struct list_head queue;
+- struct list_head free_list;
+- u32 residue;
+- struct dw_cyclic_desc *cdesc;
+-
+- unsigned int descs_allocated;
+-
+- /* hardware configuration */
+- unsigned int block_size;
+- bool nollp;
+-
+- /* custom slave configuration */
+- unsigned int request_line;
+- unsigned char src_master;
+- unsigned char dst_master;
+-
+- /* configuration passed via DMA_SLAVE_CONFIG */
+- struct dma_slave_config dma_sconfig;
+-};
+-
+-static inline struct dw_dma_chan_regs __iomem *
+-__dwc_regs(struct dw_dma_chan *dwc)
+-{
+- return dwc->ch_regs;
+-}
+-
+-#define channel_readl(dwc, name) \
+- dma_readl_native(&(__dwc_regs(dwc)->name))
+-#define channel_writel(dwc, name, val) \
+- dma_writel_native((val), &(__dwc_regs(dwc)->name))
+-
+-static inline struct dw_dma_chan *to_dw_dma_chan(struct dma_chan *chan)
+-{
+- return container_of(chan, struct dw_dma_chan, chan);
+-}
+-
+-struct dw_dma {
+- struct dma_device dma;
+- void __iomem *regs;
+- struct dma_pool *desc_pool;
+- struct tasklet_struct tasklet;
+- struct clk *clk;
+-
+- u8 all_chan_mask;
+-
+- /* hardware configuration */
+- unsigned char nr_masters;
+- unsigned char data_width[4];
+-
+- struct dw_dma_chan chan[0];
+-};
+-
+-static inline struct dw_dma_regs __iomem *__dw_regs(struct dw_dma *dw)
+-{
+- return dw->regs;
+-}
+-
+-#define dma_readl(dw, name) \
+- dma_readl_native(&(__dw_regs(dw)->name))
+-#define dma_writel(dw, name, val) \
+- dma_writel_native((val), &(__dw_regs(dw)->name))
+-
+-#define channel_set_bit(dw, reg, mask) \
+- dma_writel(dw, reg, ((mask) << 8) | (mask))
+-#define channel_clear_bit(dw, reg, mask) \
+- dma_writel(dw, reg, ((mask) << 8) | 0)
+-
+-static inline struct dw_dma *to_dw_dma(struct dma_device *ddev)
+-{
+- return container_of(ddev, struct dw_dma, dma);
+-}
+-
+-/* LLI == Linked List Item; a.k.a. DMA block descriptor */
+-struct dw_lli {
+- /* values that are not changed by hardware */
+- u32 sar;
+- u32 dar;
+- u32 llp; /* chain to next lli */
+- u32 ctllo;
+- /* values that may get written back: */
+- u32 ctlhi;
+- /* sstat and dstat can snapshot peripheral register state.
+- * silicon config may discard either or both...
+- */
+- u32 sstat;
+- u32 dstat;
+-};
+-
+-struct dw_desc {
+- /* FIRST values the hardware uses */
+- struct dw_lli lli;
+-
+- /* THEN values for driver housekeeping */
+- struct list_head desc_node;
+- struct list_head tx_list;
+- struct dma_async_tx_descriptor txd;
+- size_t len;
+- size_t total_len;
+-};
+-
+-#define to_dw_desc(h) list_entry(h, struct dw_desc, desc_node)
+-
+-static inline struct dw_desc *
+-txd_to_dw_desc(struct dma_async_tx_descriptor *txd)
+-{
+- return container_of(txd, struct dw_desc, txd);
+-}
diff --git a/patches.baytrail/1170-i2c-use-dev_get_platdata.patch b/patches.baytrail/1170-i2c-use-dev_get_platdata.patch
index ce4ffae998d..6337ef344d4 100644
--- a/patches.baytrail/1170-i2c-use-dev_get_platdata.patch
+++ b/patches.baytrail/1170-i2c-use-dev_get_platdata.patch
@@ -11,38 +11,36 @@ Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
(cherry picked from commit 6d4028c644edc0a2e4a8c948ebf81e8f2f09726e)
Signed-off-by: Darren Hart <dvhart@linux.intel.com>
---
- drivers/i2c/busses/i2c-bfin-twi.c | 9 +++++----
- drivers/i2c/busses/i2c-cbus-gpio.c | 5 +++--
- drivers/i2c/busses/i2c-davinci.c | 2 +-
- drivers/i2c/busses/i2c-gpio.c | 6 +++---
- drivers/i2c/busses/i2c-imx.c | 2 +-
- drivers/i2c/busses/i2c-mv64xxx.c | 2 +-
- drivers/i2c/busses/i2c-nomadik.c | 2 +-
- drivers/i2c/busses/i2c-nuc900.c | 2 +-
- drivers/i2c/busses/i2c-ocores.c | 2 +-
- drivers/i2c/busses/i2c-omap.c | 2 +-
- drivers/i2c/busses/i2c-pca-platform.c | 2 +-
- drivers/i2c/busses/i2c-powermac.c | 2 +-
- drivers/i2c/busses/i2c-pxa.c | 4 ++--
- drivers/i2c/busses/i2c-rcar.c | 2 +-
- drivers/i2c/busses/i2c-s3c2410.c | 2 +-
- drivers/i2c/busses/i2c-s6000.c | 5 +++--
- drivers/i2c/busses/i2c-sh7760.c | 2 +-
- drivers/i2c/busses/i2c-sh_mobile.c | 2 +-
- drivers/i2c/busses/i2c-xiic.c | 2 +-
- drivers/i2c/i2c-smbus.c | 2 +-
- drivers/i2c/muxes/i2c-arb-gpio-challenge.c | 2 +-
- drivers/i2c/muxes/i2c-mux-gpio.c | 8 +++++---
- drivers/i2c/muxes/i2c-mux-pca9541.c | 2 +-
- drivers/i2c/muxes/i2c-mux-pca954x.c | 2 +-
- drivers/i2c/muxes/i2c-mux-pinctrl.c | 2 +-
+ drivers/i2c/busses/i2c-bfin-twi.c | 9 +++++----
+ drivers/i2c/busses/i2c-cbus-gpio.c | 5 +++--
+ drivers/i2c/busses/i2c-davinci.c | 2 +-
+ drivers/i2c/busses/i2c-gpio.c | 6 +++---
+ drivers/i2c/busses/i2c-imx.c | 2 +-
+ drivers/i2c/busses/i2c-mv64xxx.c | 2 +-
+ drivers/i2c/busses/i2c-nomadik.c | 2 +-
+ drivers/i2c/busses/i2c-nuc900.c | 2 +-
+ drivers/i2c/busses/i2c-ocores.c | 2 +-
+ drivers/i2c/busses/i2c-omap.c | 2 +-
+ drivers/i2c/busses/i2c-pca-platform.c | 2 +-
+ drivers/i2c/busses/i2c-powermac.c | 2 +-
+ drivers/i2c/busses/i2c-pxa.c | 4 ++--
+ drivers/i2c/busses/i2c-rcar.c | 2 +-
+ drivers/i2c/busses/i2c-s3c2410.c | 2 +-
+ drivers/i2c/busses/i2c-s6000.c | 5 +++--
+ drivers/i2c/busses/i2c-sh7760.c | 2 +-
+ drivers/i2c/busses/i2c-sh_mobile.c | 2 +-
+ drivers/i2c/busses/i2c-xiic.c | 2 +-
+ drivers/i2c/i2c-smbus.c | 2 +-
+ drivers/i2c/muxes/i2c-arb-gpio-challenge.c | 2 +-
+ drivers/i2c/muxes/i2c-mux-gpio.c | 8 +++++---
+ drivers/i2c/muxes/i2c-mux-pca9541.c | 2 +-
+ drivers/i2c/muxes/i2c-mux-pca954x.c | 2 +-
+ drivers/i2c/muxes/i2c-mux-pinctrl.c | 2 +-
25 files changed, 40 insertions(+), 35 deletions(-)
-diff --git a/drivers/i2c/busses/i2c-bfin-twi.c b/drivers/i2c/busses/i2c-bfin-twi.c
-index 05080c449c6b..6b0c5969b503 100644
--- a/drivers/i2c/busses/i2c-bfin-twi.c
+++ b/drivers/i2c/busses/i2c-bfin-twi.c
-@@ -662,8 +662,9 @@ static int i2c_bfin_twi_probe(struct platform_device *pdev)
+@@ -662,8 +662,9 @@ static int i2c_bfin_twi_probe(struct pla
p_adap->timeout = 5 * HZ;
p_adap->retries = 3;
@@ -63,7 +61,7 @@ index 05080c449c6b..6b0c5969b503 100644
out_error_pin_mux:
iounmap(iface->regs_base);
out_error_ioremap:
-@@ -726,7 +727,7 @@ static int i2c_bfin_twi_remove(struct platform_device *pdev)
+@@ -726,7 +727,7 @@ static int i2c_bfin_twi_remove(struct pl
i2c_del_adapter(&(iface->adap));
free_irq(iface->irq, iface);
@@ -72,11 +70,9 @@ index 05080c449c6b..6b0c5969b503 100644
iounmap(iface->regs_base);
kfree(iface);
-diff --git a/drivers/i2c/busses/i2c-cbus-gpio.c b/drivers/i2c/busses/i2c-cbus-gpio.c
-index 1be13ac11dc5..2d46f13adfdf 100644
--- a/drivers/i2c/busses/i2c-cbus-gpio.c
+++ b/drivers/i2c/busses/i2c-cbus-gpio.c
-@@ -233,8 +233,9 @@ static int cbus_i2c_probe(struct platform_device *pdev)
+@@ -233,8 +233,9 @@ static int cbus_i2c_probe(struct platfor
chost->clk_gpio = of_get_gpio(dnode, 0);
chost->dat_gpio = of_get_gpio(dnode, 1);
chost->sel_gpio = of_get_gpio(dnode, 2);
@@ -88,11 +84,9 @@ index 1be13ac11dc5..2d46f13adfdf 100644
chost->clk_gpio = pdata->clk_gpio;
chost->dat_gpio = pdata->dat_gpio;
chost->sel_gpio = pdata->sel_gpio;
-diff --git a/drivers/i2c/busses/i2c-davinci.c b/drivers/i2c/busses/i2c-davinci.c
-index fa556057d224..14c53cccdcf0 100644
--- a/drivers/i2c/busses/i2c-davinci.c
+++ b/drivers/i2c/busses/i2c-davinci.c
-@@ -665,7 +665,7 @@ static int davinci_i2c_probe(struct platform_device *pdev)
+@@ -665,7 +665,7 @@ static int davinci_i2c_probe(struct plat
#endif
dev->dev = &pdev->dev;
dev->irq = irq->start;
@@ -101,11 +95,9 @@ index fa556057d224..14c53cccdcf0 100644
platform_set_drvdata(pdev, dev);
if (!dev->pdata && pdev->dev.of_node) {
-diff --git a/drivers/i2c/busses/i2c-gpio.c b/drivers/i2c/busses/i2c-gpio.c
-index bc6e139c6e7f..8cdb4f743e19 100644
--- a/drivers/i2c/busses/i2c-gpio.c
+++ b/drivers/i2c/busses/i2c-gpio.c
-@@ -137,9 +137,9 @@ static int i2c_gpio_probe(struct platform_device *pdev)
+@@ -137,9 +137,9 @@ static int i2c_gpio_probe(struct platfor
if (ret)
return ret;
} else {
@@ -117,7 +109,7 @@ index bc6e139c6e7f..8cdb4f743e19 100644
sda_pin = pdata->sda_pin;
scl_pin = pdata->scl_pin;
}
-@@ -171,7 +171,7 @@ static int i2c_gpio_probe(struct platform_device *pdev)
+@@ -171,7 +171,7 @@ static int i2c_gpio_probe(struct platfor
pdata->scl_pin = scl_pin;
of_i2c_gpio_get_props(pdev->dev.of_node, pdata);
} else {
@@ -126,11 +118,9 @@ index bc6e139c6e7f..8cdb4f743e19 100644
}
if (pdata->sda_is_open_drain) {
-diff --git a/drivers/i2c/busses/i2c-imx.c b/drivers/i2c/busses/i2c-imx.c
-index 9c0f8bda692a..a231d2fd91ce 100644
--- a/drivers/i2c/busses/i2c-imx.c
+++ b/drivers/i2c/busses/i2c-imx.c
-@@ -596,7 +596,7 @@ static int __init i2c_imx_probe(struct platform_device *pdev)
+@@ -596,7 +596,7 @@ static int __init i2c_imx_probe(struct p
&pdev->dev);
struct imx_i2c_struct *i2c_imx;
struct resource *res;
@@ -139,8 +129,6 @@ index 9c0f8bda692a..a231d2fd91ce 100644
void __iomem *base;
int irq, ret;
u32 bitrate;
-diff --git a/drivers/i2c/busses/i2c-mv64xxx.c b/drivers/i2c/busses/i2c-mv64xxx.c
-index b1f42bf40963..9cc361d19941 100644
--- a/drivers/i2c/busses/i2c-mv64xxx.c
+++ b/drivers/i2c/busses/i2c-mv64xxx.c
@@ -618,7 +618,7 @@ static int
@@ -152,11 +140,9 @@ index b1f42bf40963..9cc361d19941 100644
struct resource *r;
int rc;
-diff --git a/drivers/i2c/busses/i2c-nomadik.c b/drivers/i2c/busses/i2c-nomadik.c
-index 650293ff4d62..9eb5852512d4 100644
--- a/drivers/i2c/busses/i2c-nomadik.c
+++ b/drivers/i2c/busses/i2c-nomadik.c
-@@ -974,7 +974,7 @@ static atomic_t adapter_id = ATOMIC_INIT(0);
+@@ -974,7 +974,7 @@ static atomic_t adapter_id = ATOMIC_INIT
static int nmk_i2c_probe(struct amba_device *adev, const struct amba_id *id)
{
int ret = 0;
@@ -165,11 +151,9 @@ index 650293ff4d62..9eb5852512d4 100644
struct device_node *np = adev->dev.of_node;
struct nmk_i2c_dev *dev;
struct i2c_adapter *adap;
-diff --git a/drivers/i2c/busses/i2c-nuc900.c b/drivers/i2c/busses/i2c-nuc900.c
-index 865ee350adb3..36394d737faf 100644
--- a/drivers/i2c/busses/i2c-nuc900.c
+++ b/drivers/i2c/busses/i2c-nuc900.c
-@@ -525,7 +525,7 @@ static int nuc900_i2c_probe(struct platform_device *pdev)
+@@ -525,7 +525,7 @@ static int nuc900_i2c_probe(struct platf
struct resource *res;
int ret;
@@ -178,11 +162,9 @@ index 865ee350adb3..36394d737faf 100644
if (!pdata) {
dev_err(&pdev->dev, "no platform data\n");
return -EINVAL;
-diff --git a/drivers/i2c/busses/i2c-ocores.c b/drivers/i2c/busses/i2c-ocores.c
-index 0e1f8245e768..289960812efc 100644
--- a/drivers/i2c/busses/i2c-ocores.c
+++ b/drivers/i2c/busses/i2c-ocores.c
-@@ -369,7 +369,7 @@ static int ocores_i2c_probe(struct platform_device *pdev)
+@@ -369,7 +369,7 @@ static int ocores_i2c_probe(struct platf
if (IS_ERR(i2c->base))
return PTR_ERR(i2c->base);
@@ -191,11 +173,9 @@ index 0e1f8245e768..289960812efc 100644
if (pdata) {
i2c->reg_shift = pdata->reg_shift;
i2c->reg_io_width = pdata->reg_io_width;
-diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
-index aa77626f8315..9a844003696b 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
-@@ -1079,7 +1079,7 @@ omap_i2c_probe(struct platform_device *pdev)
+@@ -1079,7 +1079,7 @@ omap_i2c_probe(struct platform_device *p
struct i2c_adapter *adap;
struct resource *mem;
const struct omap_i2c_bus_platform_data *pdata =
@@ -204,11 +184,9 @@ index aa77626f8315..9a844003696b 100644
struct device_node *node = pdev->dev.of_node;
const struct of_device_id *match;
int irq;
-diff --git a/drivers/i2c/busses/i2c-pca-platform.c b/drivers/i2c/busses/i2c-pca-platform.c
-index aa00df14e30b..39e2755e3f25 100644
--- a/drivers/i2c/busses/i2c-pca-platform.c
+++ b/drivers/i2c/busses/i2c-pca-platform.c
-@@ -136,7 +136,7 @@ static int i2c_pca_pf_probe(struct platform_device *pdev)
+@@ -136,7 +136,7 @@ static int i2c_pca_pf_probe(struct platf
struct i2c_pca_pf_data *i2c;
struct resource *res;
struct i2c_pca9564_pf_platform_data *platform_data =
@@ -217,11 +195,9 @@ index aa00df14e30b..39e2755e3f25 100644
int ret = 0;
int irq;
-diff --git a/drivers/i2c/busses/i2c-powermac.c b/drivers/i2c/busses/i2c-powermac.c
-index 8dc90da1e6e6..5a88364a542b 100644
--- a/drivers/i2c/busses/i2c-powermac.c
+++ b/drivers/i2c/busses/i2c-powermac.c
-@@ -398,7 +398,7 @@ static void i2c_powermac_register_devices(struct i2c_adapter *adap,
+@@ -398,7 +398,7 @@ static void i2c_powermac_register_device
static int i2c_powermac_probe(struct platform_device *dev)
{
@@ -230,11 +206,9 @@ index 8dc90da1e6e6..5a88364a542b 100644
struct device_node *parent = NULL;
struct i2c_adapter *adapter;
const char *basename;
-diff --git a/drivers/i2c/busses/i2c-pxa.c b/drivers/i2c/busses/i2c-pxa.c
-index ea6d45d1dcd6..5e8e04273b78 100644
--- a/drivers/i2c/busses/i2c-pxa.c
+++ b/drivers/i2c/busses/i2c-pxa.c
-@@ -1072,7 +1072,7 @@ static int i2c_pxa_probe_pdata(struct platform_device *pdev,
+@@ -1072,7 +1072,7 @@ static int i2c_pxa_probe_pdata(struct pl
struct pxa_i2c *i2c,
enum pxa_i2c_types *i2c_types)
{
@@ -243,7 +217,7 @@ index ea6d45d1dcd6..5e8e04273b78 100644
const struct platform_device_id *id = platform_get_device_id(pdev);
*i2c_types = id->driver_data;
-@@ -1085,7 +1085,7 @@ static int i2c_pxa_probe_pdata(struct platform_device *pdev,
+@@ -1085,7 +1085,7 @@ static int i2c_pxa_probe_pdata(struct pl
static int i2c_pxa_probe(struct platform_device *dev)
{
@@ -252,11 +226,9 @@ index ea6d45d1dcd6..5e8e04273b78 100644
enum pxa_i2c_types i2c_type;
struct pxa_i2c *i2c;
struct resource *res = NULL;
-diff --git a/drivers/i2c/busses/i2c-rcar.c b/drivers/i2c/busses/i2c-rcar.c
-index 0fc585861610..e59c3f618542 100644
--- a/drivers/i2c/busses/i2c-rcar.c
+++ b/drivers/i2c/busses/i2c-rcar.c
-@@ -615,7 +615,7 @@ static const struct i2c_algorithm rcar_i2c_algo = {
+@@ -650,7 +650,7 @@ MODULE_DEVICE_TABLE(of, rcar_i2c_dt_ids)
static int rcar_i2c_probe(struct platform_device *pdev)
{
@@ -265,11 +237,9 @@ index 0fc585861610..e59c3f618542 100644
struct rcar_i2c_priv *priv;
struct i2c_adapter *adap;
struct resource *res;
-diff --git a/drivers/i2c/busses/i2c-s3c2410.c b/drivers/i2c/busses/i2c-s3c2410.c
-index cab1c91b75a3..0a077b1ef94f 100644
--- a/drivers/i2c/busses/i2c-s3c2410.c
+++ b/drivers/i2c/busses/i2c-s3c2410.c
-@@ -1033,7 +1033,7 @@ static int s3c24xx_i2c_probe(struct platform_device *pdev)
+@@ -1033,7 +1033,7 @@ static int s3c24xx_i2c_probe(struct plat
int ret;
if (!pdev->dev.of_node) {
@@ -278,11 +248,9 @@ index cab1c91b75a3..0a077b1ef94f 100644
if (!pdata) {
dev_err(&pdev->dev, "no platform data\n");
return -EINVAL;
-diff --git a/drivers/i2c/busses/i2c-s6000.c b/drivers/i2c/busses/i2c-s6000.c
-index 7c1ca5aca088..dd186a037684 100644
--- a/drivers/i2c/busses/i2c-s6000.c
+++ b/drivers/i2c/busses/i2c-s6000.c
-@@ -290,8 +290,9 @@ static int s6i2c_probe(struct platform_device *dev)
+@@ -290,8 +290,9 @@ static int s6i2c_probe(struct platform_d
clock = 0;
bus_num = -1;
@@ -294,11 +262,9 @@ index 7c1ca5aca088..dd186a037684 100644
bus_num = pdata->bus_num;
clock = pdata->clock;
}
-diff --git a/drivers/i2c/busses/i2c-sh7760.c b/drivers/i2c/busses/i2c-sh7760.c
-index 5351a2f34912..5e8f136e233f 100644
--- a/drivers/i2c/busses/i2c-sh7760.c
+++ b/drivers/i2c/busses/i2c-sh7760.c
-@@ -437,7 +437,7 @@ static int sh7760_i2c_probe(struct platform_device *pdev)
+@@ -437,7 +437,7 @@ static int sh7760_i2c_probe(struct platf
struct cami2c *id;
int ret;
@@ -307,11 +273,9 @@ index 5351a2f34912..5e8f136e233f 100644
if (!pd) {
dev_err(&pdev->dev, "no platform_data!\n");
ret = -ENODEV;
-diff --git a/drivers/i2c/busses/i2c-sh_mobile.c b/drivers/i2c/busses/i2c-sh_mobile.c
-index debf745c0268..4e86a3190d46 100644
--- a/drivers/i2c/busses/i2c-sh_mobile.c
+++ b/drivers/i2c/busses/i2c-sh_mobile.c
-@@ -658,7 +658,7 @@ static int sh_mobile_i2c_hook_irqs(struct platform_device *dev, int hook)
+@@ -658,7 +658,7 @@ static int sh_mobile_i2c_hook_irqs(struc
static int sh_mobile_i2c_probe(struct platform_device *dev)
{
@@ -320,11 +284,9 @@ index debf745c0268..4e86a3190d46 100644
struct sh_mobile_i2c_data *pd;
struct i2c_adapter *adap;
struct resource *res;
-diff --git a/drivers/i2c/busses/i2c-xiic.c b/drivers/i2c/busses/i2c-xiic.c
-index 3d0f0520c1b4..433f377b3869 100644
--- a/drivers/i2c/busses/i2c-xiic.c
+++ b/drivers/i2c/busses/i2c-xiic.c
-@@ -703,7 +703,7 @@ static int xiic_i2c_probe(struct platform_device *pdev)
+@@ -703,7 +703,7 @@ static int xiic_i2c_probe(struct platfor
if (irq < 0)
goto resource_missing;
@@ -333,11 +295,9 @@ index 3d0f0520c1b4..433f377b3869 100644
i2c = kzalloc(sizeof(*i2c), GFP_KERNEL);
if (!i2c)
-diff --git a/drivers/i2c/i2c-smbus.c b/drivers/i2c/i2c-smbus.c
-index 92cdd2323b03..44d4c6071c15 100644
--- a/drivers/i2c/i2c-smbus.c
+++ b/drivers/i2c/i2c-smbus.c
-@@ -137,7 +137,7 @@ static irqreturn_t smbalert_irq(int irq, void *d)
+@@ -137,7 +137,7 @@ static irqreturn_t smbalert_irq(int irq,
static int smbalert_probe(struct i2c_client *ara,
const struct i2c_device_id *id)
{
@@ -346,11 +306,9 @@ index 92cdd2323b03..44d4c6071c15 100644
struct i2c_smbus_alert *alert;
struct i2c_adapter *adapter = ara->adapter;
int res;
-diff --git a/drivers/i2c/muxes/i2c-arb-gpio-challenge.c b/drivers/i2c/muxes/i2c-arb-gpio-challenge.c
-index 210b6f7b9028..f7bf24375f81 100644
--- a/drivers/i2c/muxes/i2c-arb-gpio-challenge.c
+++ b/drivers/i2c/muxes/i2c-arb-gpio-challenge.c
-@@ -131,7 +131,7 @@ static int i2c_arbitrator_probe(struct platform_device *pdev)
+@@ -131,7 +131,7 @@ static int i2c_arbitrator_probe(struct p
dev_err(dev, "Cannot find device tree node\n");
return -ENODEV;
}
@@ -359,11 +317,9 @@ index 210b6f7b9028..f7bf24375f81 100644
dev_err(dev, "Platform data is not supported\n");
return -EINVAL;
}
-diff --git a/drivers/i2c/muxes/i2c-mux-gpio.c b/drivers/i2c/muxes/i2c-mux-gpio.c
-index bb4f69f75f3c..774b9cc4601c 100644
--- a/drivers/i2c/muxes/i2c-mux-gpio.c
+++ b/drivers/i2c/muxes/i2c-mux-gpio.c
-@@ -148,12 +148,14 @@ static int i2c_mux_gpio_probe(struct platform_device *pdev)
+@@ -148,12 +148,14 @@ static int i2c_mux_gpio_probe(struct pla
platform_set_drvdata(pdev, mux);
@@ -381,11 +337,9 @@ index bb4f69f75f3c..774b9cc4601c 100644
/*
* If a GPIO chip name is provided, the GPIO pin numbers provided are
-diff --git a/drivers/i2c/muxes/i2c-mux-pca9541.c b/drivers/i2c/muxes/i2c-mux-pca9541.c
-index 966a18a5d12d..c4f08ad31183 100644
--- a/drivers/i2c/muxes/i2c-mux-pca9541.c
+++ b/drivers/i2c/muxes/i2c-mux-pca9541.c
-@@ -324,7 +324,7 @@ static int pca9541_probe(struct i2c_client *client,
+@@ -324,7 +324,7 @@ static int pca9541_probe(struct i2c_clie
const struct i2c_device_id *id)
{
struct i2c_adapter *adap = client->adapter;
@@ -394,11 +348,9 @@ index 966a18a5d12d..c4f08ad31183 100644
struct pca9541 *data;
int force;
int ret = -ENODEV;
-diff --git a/drivers/i2c/muxes/i2c-mux-pca954x.c b/drivers/i2c/muxes/i2c-mux-pca954x.c
-index a531d801dbe4..bad5b84a5985 100644
--- a/drivers/i2c/muxes/i2c-mux-pca954x.c
+++ b/drivers/i2c/muxes/i2c-mux-pca954x.c
-@@ -185,7 +185,7 @@ static int pca954x_probe(struct i2c_client *client,
+@@ -185,7 +185,7 @@ static int pca954x_probe(struct i2c_clie
const struct i2c_device_id *id)
{
struct i2c_adapter *adap = to_i2c_adapter(client->dev.parent);
@@ -407,11 +359,9 @@ index a531d801dbe4..bad5b84a5985 100644
int num, force, class;
struct pca954x *data;
int ret = -ENODEV;
-diff --git a/drivers/i2c/muxes/i2c-mux-pinctrl.c b/drivers/i2c/muxes/i2c-mux-pinctrl.c
-index a43c0ce5e3d8..0d082027c29a 100644
--- a/drivers/i2c/muxes/i2c-mux-pinctrl.c
+++ b/drivers/i2c/muxes/i2c-mux-pinctrl.c
-@@ -145,7 +145,7 @@ static int i2c_mux_pinctrl_probe(struct platform_device *pdev)
+@@ -145,7 +145,7 @@ static int i2c_mux_pinctrl_probe(struct
mux->dev = &pdev->dev;
@@ -420,6 +370,3 @@ index a43c0ce5e3d8..0d082027c29a 100644
if (!mux->pdata) {
ret = i2c_mux_pinctrl_parse_dt(mux, pdev);
if (ret < 0)
---
-1.8.5.rc3
-
diff --git a/patches.baytrail/1191-ARM-EXYNOS-Select-PINCTRL_EXYNOS-for-exynos4-5-at-ch.patch b/patches.baytrail/1191-ARM-EXYNOS-Select-PINCTRL_EXYNOS-for-exynos4-5-at-ch.patch
index c55867de3b5..7a3e4605a54 100644
--- a/patches.baytrail/1191-ARM-EXYNOS-Select-PINCTRL_EXYNOS-for-exynos4-5-at-ch.patch
+++ b/patches.baytrail/1191-ARM-EXYNOS-Select-PINCTRL_EXYNOS-for-exynos4-5-at-ch.patch
@@ -17,12 +17,10 @@ Signed-off-by: Kukjin Kim <kgene.kim@samsung.com>
(cherry picked from commit 83978253d0c3e12bf81d4b5f419a0200d5cb19a6)
Signed-off-by: Darren Hart <dvhart@linux.intel.com>
---
- arch/arm/mach-exynos/Kconfig | 9 ++++++---
- drivers/pinctrl/Kconfig | 5 +++--
+ arch/arm/mach-exynos/Kconfig | 9 ++++++---
+ drivers/pinctrl/Kconfig | 5 +++--
2 files changed, 9 insertions(+), 5 deletions(-)
-diff --git a/arch/arm/mach-exynos/Kconfig b/arch/arm/mach-exynos/Kconfig
-index ff18fc2ea46f..144fcc231074 100644
--- a/arch/arm/mach-exynos/Kconfig
+++ b/arch/arm/mach-exynos/Kconfig
@@ -17,6 +17,7 @@ config ARCH_EXYNOS4
@@ -75,7 +73,7 @@ index ff18fc2ea46f..144fcc231074 100644
select S5P_SLEEP if PM
@@ -78,7 +84,6 @@ config SOC_EXYNOS5440
select ARCH_HAS_OPP
- select ARM_ARCH_TIMER
+ select HAVE_ARM_ARCH_TIMER
select AUTO_ZRELADDR
- select PINCTRL
select PINCTRL_EXYNOS5440
@@ -90,8 +88,6 @@ index ff18fc2ea46f..144fcc231074 100644
select S5P_DEV_MFC
select USE_OF
help
-diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
-index adeb1fed04cc..6585b37bbdbc 100644
--- a/drivers/pinctrl/Kconfig
+++ b/drivers/pinctrl/Kconfig
@@ -219,12 +219,13 @@ config PINCTRL_SAMSUNG
@@ -110,6 +106,3 @@ index adeb1fed04cc..6585b37bbdbc 100644
select PINMUX
select PINCONF
---
-1.8.5.rc3
-
diff --git a/patches.zynq/0010-ARM-zynq-Add-cpuidle-support.patch b/patches.zynq/0010-ARM-zynq-Add-cpuidle-support.patch
index d099591d9c3..286cad27deb 100644
--- a/patches.zynq/0010-ARM-zynq-Add-cpuidle-support.patch
+++ b/patches.zynq/0010-ARM-zynq-Add-cpuidle-support.patch
@@ -12,18 +12,16 @@ Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Signed-off-by: Daniel Sangorrin <daniel.sangorrin@toshiba.co.jp>
Signed-off-by: Yoshitake Kobayashi <yoshitake.kobayashi@toshiba.co.jp>
---
- MAINTAINERS | 1 +
- drivers/cpuidle/Kconfig | 6 +++
- drivers/cpuidle/Makefile | 1 +
- drivers/cpuidle/cpuidle-zynq.c | 83 ++++++++++++++++++++++++++++++++++++++++++
+ MAINTAINERS | 1
+ drivers/cpuidle/Kconfig | 6 ++
+ drivers/cpuidle/Makefile | 1
+ drivers/cpuidle/cpuidle-zynq.c | 83 +++++++++++++++++++++++++++++++++++++++++
4 files changed, 91 insertions(+)
create mode 100644 drivers/cpuidle/cpuidle-zynq.c
-diff --git a/MAINTAINERS b/MAINTAINERS
-index 48c748080c96..30f6d87daadd 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
-@@ -1309,6 +1309,7 @@ W: http://wiki.xilinx.com
+@@ -1310,6 +1310,7 @@ W: http://wiki.xilinx.com
T: git git://git.xilinx.com/linux-xlnx.git
S: Supported
F: arch/arm/mach-zynq/
@@ -31,8 +29,6 @@ index 48c748080c96..30f6d87daadd 100644
ARM64 PORT (AARCH64 ARCHITECTURE)
M: Catalin Marinas <catalin.marinas@arm.com>
-diff --git a/drivers/cpuidle/Kconfig b/drivers/cpuidle/Kconfig
-index c4cc27e5c8a5..8272a08b137b 100644
--- a/drivers/cpuidle/Kconfig
+++ b/drivers/cpuidle/Kconfig
@@ -39,4 +39,10 @@ config CPU_IDLE_CALXEDA
@@ -46,18 +42,13 @@ index c4cc27e5c8a5..8272a08b137b 100644
+ Select this to enable cpuidle on Xilinx Zynq processors.
+
endif
-diff --git a/drivers/cpuidle/Makefile b/drivers/cpuidle/Makefile
-index 0d8bd55e776f..8767a7b3eb91 100644
--- a/drivers/cpuidle/Makefile
+++ b/drivers/cpuidle/Makefile
-@@ -7,3 +7,4 @@ obj-$(CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED) += coupled.o
+@@ -7,3 +7,4 @@ obj-$(CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED
obj-$(CONFIG_CPU_IDLE_CALXEDA) += cpuidle-calxeda.o
obj-$(CONFIG_ARCH_KIRKWOOD) += cpuidle-kirkwood.o
+obj-$(CONFIG_CPU_IDLE_ZYNQ) += cpuidle-zynq.o
-diff --git a/drivers/cpuidle/cpuidle-zynq.c b/drivers/cpuidle/cpuidle-zynq.c
-new file mode 100644
-index 000000000000..38e03a183591
--- /dev/null
+++ b/drivers/cpuidle/cpuidle-zynq.c
@@ -0,0 +1,83 @@
@@ -144,6 +135,3 @@ index 000000000000..38e03a183591
+}
+
+device_initcall(zynq_cpuidle_init);
---
-1.8.5.rc3
-