apm821xx: remove 4.4 kernel support
[openwrt/staging/lynxis/omap.git] / target / linux / apm821xx / patches-4.4 / 015-dmaengine-dw-fixed.patch
diff --git a/target/linux/apm821xx/patches-4.4/015-dmaengine-dw-fixed.patch b/target/linux/apm821xx/patches-4.4/015-dmaengine-dw-fixed.patch
deleted file mode 100644 (file)
index 0380088..0000000
+++ /dev/null
@@ -1,1517 +0,0 @@
-From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
-Subject: [PATCH v6 0/4] Fixes / cleanups in dw_dmac (affects on few subsystems)
-Date: Mon, 25 Apr 2016 15:35:05 +0300
-
-This patch series (v3: http://www.spinics.net/lists/kernel/msg2215303.html)
-contains a number of mostly minor fixes and cleanups for the DW DMA driver. A
-couple of them affect the DT binding so these may need to be updated to
-maintain compatibility (old format is still supported though). The rest should
-be relatively straight-forward.
-
-This version has been tested on the following bare metal platforms:
-- ATNGW100 (avr32 based platform) with dmatest
-- Sam460ex (powerpc 44x based platform) with SATA
-- Intel Braswell with UART
-- Intel Galileo (Intel Quark based platform) with UART
-
-(SATA driver and Intel Galileo UART support are based on this series and just
- published recently for a review)
-
-Vinod, there are few patch sets developed on top of this one, so, the idea is
-to keep this in an immuutable branch / tag.
-
-Changes since v5:
-- fixed an issue found by kbuildbot
-
-Changes since v4:
-- send proper set of patches
-- add changelog
-
-Changes since v3:
-- add patch 1 to check value of dma-masters property
-- drop the upstreamed patches
-- update patch 2 to keep an array for data-width property as well
-
-Changes since v2:
-- add patch 1 to fix master selection which was broken for long time
-- remove "use field-by-field initialization" patch since like Mans metioned in
-  has mostly no value and even might increase error prone
-- rebase on top of recent linux-next
-- wide testing on several platforms
-
-Changes since v1:
-- zeroing struct dw_dma_slave before use
-- fall back to old data_width property if data-width is not found
-- append tags for few patches
-- correct title of cover letter
-- rebase on top of recent linux-next
-
-Andy Shevchenko (4):
-  dmaengine: dw: platform: check nr_masters to be non-zero
-  dmaengine: dw: revisit data_width property
-  dmaengine: dw: keep entire platform data in struct dw_dma
-  dmaengine: dw: pass platform data via struct dw_dma_chip
-
- Documentation/devicetree/bindings/dma/snps-dma.txt |  6 +-
- arch/arc/boot/dts/abilis_tb10x.dtsi                |  2 +-
- arch/arm/boot/dts/spear13xx.dtsi                   |  4 +-
- drivers/ata/sata_dwc_460ex.c                       |  2 +-
- drivers/dma/dw/core.c                              | 75 ++++++++--------------
- drivers/dma/dw/pci.c                               |  5 +-
- drivers/dma/dw/platform.c                          | 32 +++++----
- drivers/dma/dw/regs.h                              |  5 +-
- include/linux/dma/dw.h                             |  5 +-
- include/linux/platform_data/dma-dw.h               |  4 +-
- sound/soc/intel/common/sst-firmware.c              |  2 +-
- 11 files changed, 64 insertions(+), 78 deletions(-)
-
---- a/drivers/dma/dw/core.c
-+++ b/drivers/dma/dw/core.c
-@@ -45,22 +45,19 @@
-                       DW_DMA_MSIZE_16;                        \
-               u8 _dmsize = _is_slave ? _sconfig->dst_maxburst :       \
-                       DW_DMA_MSIZE_16;                        \
-+              u8 _dms = (_dwc->direction == DMA_MEM_TO_DEV) ?         \
-+                      _dwc->p_master : _dwc->m_master;                \
-+              u8 _sms = (_dwc->direction == DMA_DEV_TO_MEM) ?         \
-+                      _dwc->p_master : _dwc->m_master;                \
-                                                               \
-               (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));             \
-+               | DWC_CTLL_DMS(_dms)                           \
-+               | DWC_CTLL_SMS(_sms));                         \
-       })
--/*
-- * 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
--
- /* The set of bus widths supported by the DMA controller */
- #define DW_DMA_BUSWIDTHS                        \
-       BIT(DMA_SLAVE_BUSWIDTH_UNDEFINED)       | \
-@@ -80,51 +77,65 @@ static struct dw_desc *dwc_first_active(
-       return to_dw_desc(dwc->active_list.next);
- }
--static struct dw_desc *dwc_desc_get(struct dw_dma_chan *dwc)
-+static dma_cookie_t dwc_tx_submit(struct dma_async_tx_descriptor *tx)
- {
--      struct dw_desc *desc, *_desc;
--      struct dw_desc *ret = NULL;
--      unsigned int i = 0;
--      unsigned long flags;
-+      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);
--      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);
--      }
-+      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.
-+       */
-+
-+      list_add_tail(&desc->desc_node, &dwc->queue);
-       spin_unlock_irqrestore(&dwc->lock, flags);
-+      dev_vdbg(chan2dev(tx->chan), "%s: queued %u\n",
-+               __func__, desc->txd.cookie);
--      dev_vdbg(chan2dev(&dwc->chan), "scanned %u descriptors on freelist\n", i);
-+      return cookie;
-+}
--      return ret;
-+static struct dw_desc *dwc_desc_get(struct dw_dma_chan *dwc)
-+{
-+      struct dw_dma *dw = to_dw_dma(dwc->chan.device);
-+      struct dw_desc *desc;
-+      dma_addr_t phys;
-+
-+      desc = dma_pool_zalloc(dw->desc_pool, GFP_ATOMIC, &phys);
-+      if (!desc)
-+              return NULL;
-+
-+      dwc->descs_allocated++;
-+      INIT_LIST_HEAD(&desc->tx_list);
-+      dma_async_tx_descriptor_init(&desc->txd, &dwc->chan);
-+      desc->txd.tx_submit = dwc_tx_submit;
-+      desc->txd.flags = DMA_CTRL_ACK;
-+      desc->txd.phys = phys;
-+      return desc;
- }
--/*
-- * 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;
-+      struct dw_dma *dw = to_dw_dma(dwc->chan.device);
-+      struct dw_desc *child, *_next;
--      if (desc) {
--              struct dw_desc *child;
-+      if (unlikely(!desc))
-+              return;
--              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);
-+      list_for_each_entry_safe(child, _next, &desc->tx_list, desc_node) {
-+              list_del(&child->desc_node);
-+              dma_pool_free(dw->desc_pool, child, child->txd.phys);
-+              dwc->descs_allocated--;
-       }
-+
-+      dma_pool_free(dw->desc_pool, desc, desc->txd.phys);
-+      dwc->descs_allocated--;
- }
- static void dwc_initialize(struct dw_dma_chan *dwc)
-@@ -133,7 +144,7 @@ static void dwc_initialize(struct dw_dma
-       u32 cfghi = DWC_CFGH_FIFO_MODE;
-       u32 cfglo = DWC_CFGL_CH_PRIOR(dwc->priority);
--      if (dwc->initialized == true)
-+      if (test_bit(DW_DMA_IS_INITIALIZED, &dwc->flags))
-               return;
-       cfghi |= DWC_CFGH_DST_PER(dwc->dst_id);
-@@ -146,26 +157,11 @@ static void dwc_initialize(struct dw_dma
-       channel_set_bit(dw, MASK.XFER, dwc->mask);
-       channel_set_bit(dw, MASK.ERROR, dwc->mask);
--      dwc->initialized = true;
-+      set_bit(DW_DMA_IS_INITIALIZED, &dwc->flags);
- }
- /*----------------------------------------------------------------------*/
--static inline unsigned int dwc_fast_ffs(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),
-@@ -197,12 +193,12 @@ static inline void dwc_do_single_block(s
-        * Software emulation of LLP mode relies on interrupts to continue
-        * multi block transfer.
-        */
--      ctllo = desc->lli.ctllo | DWC_CTLL_INT_EN;
-+      ctllo = lli_read(desc, ctllo) | DWC_CTLL_INT_EN;
--      channel_writel(dwc, SAR, desc->lli.sar);
--      channel_writel(dwc, DAR, desc->lli.dar);
-+      channel_writel(dwc, SAR, lli_read(desc, sar));
-+      channel_writel(dwc, DAR, lli_read(desc, dar));
-       channel_writel(dwc, CTL_LO, ctllo);
--      channel_writel(dwc, CTL_HI, desc->lli.ctlhi);
-+      channel_writel(dwc, CTL_HI, lli_read(desc, ctlhi));
-       channel_set_bit(dw, CH_EN, dwc->mask);
-       /* Move pointer to next descriptor */
-@@ -213,6 +209,7 @@ static inline void dwc_do_single_block(s
- static void dwc_dostart(struct dw_dma_chan *dwc, struct dw_desc *first)
- {
-       struct dw_dma   *dw = to_dw_dma(dwc->chan.device);
-+      u8              lms = DWC_LLP_LMS(dwc->m_master);
-       unsigned long   was_soft_llp;
-       /* ASSERT:  channel is idle */
-@@ -237,7 +234,7 @@ static void dwc_dostart(struct dw_dma_ch
-               dwc_initialize(dwc);
--              dwc->residue = first->total_len;
-+              first->residue = first->total_len;
-               dwc->tx_node_active = &first->tx_list;
-               /* Submit first block */
-@@ -248,9 +245,8 @@ static void dwc_dostart(struct dw_dma_ch
-       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, LLP, first->txd.phys | lms);
-+      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);
- }
-@@ -293,11 +289,7 @@ dwc_descriptor_complete(struct dw_dma_ch
-       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);
--
--      dma_descriptor_unmap(txd);
-+      dwc_desc_put(dwc, desc);
-       spin_unlock_irqrestore(&dwc->lock, flags);
-       if (callback)
-@@ -368,11 +360,11 @@ static void dwc_scan_descriptors(struct
-                       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;
-+                              /* Update residue to reflect last sent descriptor */
-+                              if (active == head->next)
-+                                      desc->residue -= desc->len;
-+                              else
-+                                      desc->residue -= to_dw_desc(active->prev)->len;
-                               child = to_dw_desc(active);
-@@ -387,8 +379,6 @@ static void dwc_scan_descriptors(struct
-                       clear_bit(DW_DMA_IS_SOFT_LLP, &dwc->flags);
-               }
--              dwc->residue = 0;
--
-               spin_unlock_irqrestore(&dwc->lock, flags);
-               dwc_complete_all(dw, dwc);
-@@ -396,7 +386,6 @@ static void dwc_scan_descriptors(struct
-       }
-       if (list_empty(&dwc->active_list)) {
--              dwc->residue = 0;
-               spin_unlock_irqrestore(&dwc->lock, flags);
-               return;
-       }
-@@ -411,31 +400,31 @@ static void dwc_scan_descriptors(struct
-       list_for_each_entry_safe(desc, _desc, &dwc->active_list, desc_node) {
-               /* Initial residue value */
--              dwc->residue = desc->total_len;
-+              desc->residue = desc->total_len;
-               /* Check first descriptors addr */
--              if (desc->txd.phys == llp) {
-+              if (desc->txd.phys == DWC_LLP_LOC(llp)) {
-                       spin_unlock_irqrestore(&dwc->lock, flags);
-                       return;
-               }
-               /* Check first descriptors llp */
--              if (desc->lli.llp == llp) {
-+              if (lli_read(desc, llp) == llp) {
-                       /* This one is currently in progress */
--                      dwc->residue -= dwc_get_sent(dwc);
-+                      desc->residue -= dwc_get_sent(dwc);
-                       spin_unlock_irqrestore(&dwc->lock, flags);
-                       return;
-               }
--              dwc->residue -= desc->len;
-+              desc->residue -= desc->len;
-               list_for_each_entry(child, &desc->tx_list, desc_node) {
--                      if (child->lli.llp == llp) {
-+                      if (lli_read(child, llp) == llp) {
-                               /* Currently in progress */
--                              dwc->residue -= dwc_get_sent(dwc);
-+                              desc->residue -= dwc_get_sent(dwc);
-                               spin_unlock_irqrestore(&dwc->lock, flags);
-                               return;
-                       }
--                      dwc->residue -= child->len;
-+                      desc->residue -= child->len;
-               }
-               /*
-@@ -457,10 +446,14 @@ static void dwc_scan_descriptors(struct
-       spin_unlock_irqrestore(&dwc->lock, flags);
- }
--static inline void dwc_dump_lli(struct dw_dma_chan *dwc, struct dw_lli *lli)
-+static inline void dwc_dump_lli(struct dw_dma_chan *dwc, struct dw_desc *desc)
- {
-       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);
-+               lli_read(desc, sar),
-+               lli_read(desc, dar),
-+               lli_read(desc, llp),
-+               lli_read(desc, ctlhi),
-+               lli_read(desc, ctllo));
- }
- static void dwc_handle_error(struct dw_dma *dw, struct dw_dma_chan *dwc)
-@@ -496,9 +489,9 @@ static void dwc_handle_error(struct dw_d
-        */
-       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);
-+      dwc_dump_lli(dwc, bad_desc);
-       list_for_each_entry(child, &bad_desc->tx_list, desc_node)
--              dwc_dump_lli(dwc, &child->lli);
-+              dwc_dump_lli(dwc, child);
-       spin_unlock_irqrestore(&dwc->lock, flags);
-@@ -549,7 +542,7 @@ static void dwc_handle_cyclic(struct dw_
-        */
-       if (unlikely(status_err & dwc->mask) ||
-                       unlikely(status_xfer & dwc->mask)) {
--              int i;
-+              unsigned int i;
-               dev_err(chan2dev(&dwc->chan),
-                       "cyclic DMA unexpected %s interrupt, stopping DMA transfer\n",
-@@ -571,7 +564,7 @@ static void dwc_handle_cyclic(struct dw_
-               dma_writel(dw, CLEAR.XFER, dwc->mask);
-               for (i = 0; i < dwc->cdesc->periods; i++)
--                      dwc_dump_lli(dwc, &dwc->cdesc->desc[i]->lli);
-+                      dwc_dump_lli(dwc, dwc->cdesc->desc[i]);
-               spin_unlock_irqrestore(&dwc->lock, flags);
-       }
-@@ -589,7 +582,7 @@ static void dw_dma_tasklet(unsigned long
-       u32 status_block;
-       u32 status_xfer;
-       u32 status_err;
--      int i;
-+      unsigned int i;
-       status_block = dma_readl(dw, RAW.BLOCK);
-       status_xfer = dma_readl(dw, RAW.XFER);
-@@ -616,12 +609,17 @@ static void dw_dma_tasklet(unsigned long
- static irqreturn_t dw_dma_interrupt(int irq, void *dev_id)
- {
-       struct dw_dma *dw = dev_id;
--      u32 status = dma_readl(dw, STATUS_INT);
-+      u32 status;
-+
-+      /* Check if we have any interrupt from the DMAC which is not in use */
-+      if (!dw->in_use)
-+              return IRQ_NONE;
-+      status = dma_readl(dw, STATUS_INT);
-       dev_vdbg(dw->dma.dev, "%s: status=0x%x\n", __func__, status);
-       /* Check if we have any interrupt from the DMAC */
--      if (!status || !dw->in_use)
-+      if (!status)
-               return IRQ_NONE;
-       /*
-@@ -653,30 +651,6 @@ static irqreturn_t dw_dma_interrupt(int
- /*----------------------------------------------------------------------*/
--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.
--       */
--
--      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)
-@@ -688,10 +662,12 @@ dwc_prep_dma_memcpy(struct dma_chan *cha
-       struct dw_desc          *prev;
-       size_t                  xfer_count;
-       size_t                  offset;
-+      u8                      m_master = dwc->m_master;
-       unsigned int            src_width;
-       unsigned int            dst_width;
--      unsigned int            data_width;
-+      unsigned int            data_width = dw->pdata->data_width[m_master];
-       u32                     ctllo;
-+      u8                      lms = DWC_LLP_LMS(m_master);
-       dev_vdbg(chan2dev(chan),
-                       "%s: d%pad s%pad l0x%zx f0x%lx\n", __func__,
-@@ -704,11 +680,7 @@ dwc_prep_dma_memcpy(struct dma_chan *cha
-       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_ffs(src | dest | len));
-+      src_width = dst_width = __ffs(data_width | src | dest | len);
-       ctllo = DWC_DEFAULT_CTLLO(chan)
-                       | DWC_CTLL_DST_WIDTH(dst_width)
-@@ -726,27 +698,27 @@ dwc_prep_dma_memcpy(struct dma_chan *cha
-               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;
-+              lli_write(desc, sar, src + offset);
-+              lli_write(desc, dar, dest + offset);
-+              lli_write(desc, ctllo, ctllo);
-+              lli_write(desc, 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);
-+                      lli_write(prev, llp, desc->txd.phys | lms);
-+                      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;
-+              lli_set(prev, ctllo, DWC_CTLL_INT_EN);
-       prev->lli.llp = 0;
-+      lli_clear(prev, ctllo, DWC_CTLL_LLP_D_EN | DWC_CTLL_LLP_S_EN);
-       first->txd.flags = flags;
-       first->total_len = len;
-@@ -768,10 +740,12 @@ dwc_prep_slave_sg(struct dma_chan *chan,
-       struct dw_desc          *prev;
-       struct dw_desc          *first;
-       u32                     ctllo;
-+      u8                      m_master = dwc->m_master;
-+      u8                      lms = DWC_LLP_LMS(m_master);
-       dma_addr_t              reg;
-       unsigned int            reg_width;
-       unsigned int            mem_width;
--      unsigned int            data_width;
-+      unsigned int            data_width = dw->pdata->data_width[m_master];
-       unsigned int            i;
-       struct scatterlist      *sg;
-       size_t                  total_len = 0;
-@@ -797,8 +771,6 @@ dwc_prep_slave_sg(struct dma_chan *chan,
-               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;
-@@ -806,17 +778,16 @@ dwc_prep_slave_sg(struct dma_chan *chan,
-                       mem = sg_dma_address(sg);
-                       len = sg_dma_len(sg);
--                      mem_width = min_t(unsigned int,
--                                        data_width, dwc_fast_ffs(mem | len));
-+                      mem_width = __ffs(data_width | mem | len);
- slave_sg_todev_fill_desc:
-                       desc = dwc_desc_get(dwc);
-                       if (!desc)
-                               goto err_desc_get;
--                      desc->lli.sar = mem;
--                      desc->lli.dar = reg;
--                      desc->lli.ctllo = ctllo | DWC_CTLL_SRC_WIDTH(mem_width);
-+                      lli_write(desc, sar, mem);
-+                      lli_write(desc, dar, reg);
-+                      lli_write(desc, ctllo, ctllo | DWC_CTLL_SRC_WIDTH(mem_width));
-                       if ((len >> mem_width) > dwc->block_size) {
-                               dlen = dwc->block_size << mem_width;
-                               mem += dlen;
-@@ -826,15 +797,14 @@ slave_sg_todev_fill_desc:
-                               len = 0;
-                       }
--                      desc->lli.ctlhi = dlen >> mem_width;
-+                      lli_write(desc, 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);
-+                              lli_write(prev, llp, desc->txd.phys | lms);
-+                              list_add_tail(&desc->desc_node, &first->tx_list);
-                       }
-                       prev = desc;
-                       total_len += dlen;
-@@ -854,8 +824,6 @@ slave_sg_todev_fill_desc:
-               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;
-@@ -863,17 +831,16 @@ slave_sg_todev_fill_desc:
-                       mem = sg_dma_address(sg);
-                       len = sg_dma_len(sg);
--                      mem_width = min_t(unsigned int,
--                                        data_width, dwc_fast_ffs(mem | len));
-+                      mem_width = __ffs(data_width | mem | len);
- slave_sg_fromdev_fill_desc:
-                       desc = dwc_desc_get(dwc);
-                       if (!desc)
-                               goto err_desc_get;
--                      desc->lli.sar = reg;
--                      desc->lli.dar = mem;
--                      desc->lli.ctllo = ctllo | DWC_CTLL_DST_WIDTH(mem_width);
-+                      lli_write(desc, sar, reg);
-+                      lli_write(desc, dar, mem);
-+                      lli_write(desc, ctllo, ctllo | DWC_CTLL_DST_WIDTH(mem_width));
-                       if ((len >> reg_width) > dwc->block_size) {
-                               dlen = dwc->block_size << reg_width;
-                               mem += dlen;
-@@ -882,15 +849,14 @@ slave_sg_fromdev_fill_desc:
-                               dlen = len;
-                               len = 0;
-                       }
--                      desc->lli.ctlhi = dlen >> reg_width;
-+                      lli_write(desc, 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);
-+                              lli_write(prev, llp, desc->txd.phys | lms);
-+                              list_add_tail(&desc->desc_node, &first->tx_list);
-                       }
-                       prev = desc;
-                       total_len += dlen;
-@@ -905,9 +871,10 @@ slave_sg_fromdev_fill_desc:
-       if (flags & DMA_PREP_INTERRUPT)
-               /* Trigger interrupt after last block */
--              prev->lli.ctllo |= DWC_CTLL_INT_EN;
-+              lli_set(prev, ctllo, DWC_CTLL_INT_EN);
-       prev->lli.llp = 0;
-+      lli_clear(prev, ctllo, DWC_CTLL_LLP_D_EN | DWC_CTLL_LLP_S_EN);
-       first->total_len = total_len;
-       return &first->txd;
-@@ -932,8 +899,8 @@ bool dw_dma_filter(struct dma_chan *chan
-       dwc->src_id = dws->src_id;
-       dwc->dst_id = dws->dst_id;
--      dwc->src_master = dws->src_master;
--      dwc->dst_master = dws->dst_master;
-+      dwc->m_master = dws->m_master;
-+      dwc->p_master = dws->p_master;
-       return true;
- }
-@@ -986,7 +953,7 @@ static int dwc_pause(struct dma_chan *ch
-       while (!(channel_readl(dwc, CFG_LO) & DWC_CFGL_FIFO_EMPTY) && count--)
-               udelay(2);
--      dwc->paused = true;
-+      set_bit(DW_DMA_IS_PAUSED, &dwc->flags);
-       spin_unlock_irqrestore(&dwc->lock, flags);
-@@ -999,7 +966,7 @@ static inline void dwc_chan_resume(struc
-       channel_writel(dwc, CFG_LO, cfglo & ~DWC_CFGL_CH_SUSP);
--      dwc->paused = false;
-+      clear_bit(DW_DMA_IS_PAUSED, &dwc->flags);
- }
- static int dwc_resume(struct dma_chan *chan)
-@@ -1007,12 +974,10 @@ static int dwc_resume(struct dma_chan *c
-       struct dw_dma_chan      *dwc = to_dw_dma_chan(chan);
-       unsigned long           flags;
--      if (!dwc->paused)
--              return 0;
--
-       spin_lock_irqsave(&dwc->lock, flags);
--      dwc_chan_resume(dwc);
-+      if (test_bit(DW_DMA_IS_PAUSED, &dwc->flags))
-+              dwc_chan_resume(dwc);
-       spin_unlock_irqrestore(&dwc->lock, flags);
-@@ -1048,16 +1013,37 @@ static int dwc_terminate_all(struct dma_
-       return 0;
- }
--static inline u32 dwc_get_residue(struct dw_dma_chan *dwc)
-+static struct dw_desc *dwc_find_desc(struct dw_dma_chan *dwc, dma_cookie_t c)
-+{
-+      struct dw_desc *desc;
-+
-+      list_for_each_entry(desc, &dwc->active_list, desc_node)
-+              if (desc->txd.cookie == c)
-+                      return desc;
-+
-+      return NULL;
-+}
-+
-+static u32 dwc_get_residue(struct dw_dma_chan *dwc, dma_cookie_t cookie)
- {
-+      struct dw_desc *desc;
-       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);
-+      desc = dwc_find_desc(dwc, cookie);
-+      if (desc) {
-+              if (desc == dwc_first_active(dwc)) {
-+                      residue = desc->residue;
-+                      if (test_bit(DW_DMA_IS_SOFT_LLP, &dwc->flags) && residue)
-+                              residue -= dwc_get_sent(dwc);
-+              } else {
-+                      residue = desc->total_len;
-+              }
-+      } else {
-+              residue = 0;
-+      }
-       spin_unlock_irqrestore(&dwc->lock, flags);
-       return residue;
-@@ -1078,10 +1064,12 @@ dwc_tx_status(struct dma_chan *chan,
-       dwc_scan_descriptors(to_dw_dma(chan->device), dwc);
-       ret = dma_cookie_status(chan, cookie, txstate);
--      if (ret != DMA_COMPLETE)
--              dma_set_residue(txstate, dwc_get_residue(dwc));
-+      if (ret == DMA_COMPLETE)
-+              return ret;
-+
-+      dma_set_residue(txstate, dwc_get_residue(dwc, cookie));
--      if (dwc->paused && ret == DMA_IN_PROGRESS)
-+      if (test_bit(DW_DMA_IS_PAUSED, &dwc->flags) && ret == DMA_IN_PROGRESS)
-               return DMA_PAUSED;
-       return ret;
-@@ -1102,7 +1090,7 @@ static void dwc_issue_pending(struct dma
- static void dw_dma_off(struct dw_dma *dw)
- {
--      int i;
-+      unsigned int i;
-       dma_writel(dw, CFG, 0);
-@@ -1116,7 +1104,7 @@ static void dw_dma_off(struct dw_dma *dw
-               cpu_relax();
-       for (i = 0; i < dw->dma.chancnt; i++)
--              dw->chan[i].initialized = false;
-+              clear_bit(DW_DMA_IS_INITIALIZED, &dw->chan[i].flags);
- }
- static void dw_dma_on(struct dw_dma *dw)
-@@ -1128,9 +1116,6 @@ static int dwc_alloc_chan_resources(stru
- {
-       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__);
-@@ -1161,48 +1146,13 @@ static int dwc_alloc_chan_resources(stru
-               dw_dma_on(dw);
-       dw->in_use |= dwc->mask;
--      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;
-+      return 0;
- }
- 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);
-@@ -1215,17 +1165,15 @@ static void dwc_free_chan_resources(stru
-       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;
-       /* Clear custom channel configuration */
-       dwc->src_id = 0;
-       dwc->dst_id = 0;
--      dwc->src_master = 0;
--      dwc->dst_master = 0;
-+      dwc->m_master = 0;
-+      dwc->p_master = 0;
--      dwc->initialized = false;
-+      clear_bit(DW_DMA_IS_INITIALIZED, &dwc->flags);
-       /* Disable interrupts */
-       channel_clear_bit(dw, MASK.XFER, dwc->mask);
-@@ -1239,11 +1187,6 @@ static void dwc_free_chan_resources(stru
-       if (!dw->in_use)
-               dw_dma_off(dw);
--      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__);
- }
-@@ -1321,6 +1264,7 @@ struct dw_cyclic_desc *dw_dma_cyclic_pre
-       struct dw_cyclic_desc           *retval = NULL;
-       struct dw_desc                  *desc;
-       struct dw_desc                  *last = NULL;
-+      u8                              lms = DWC_LLP_LMS(dwc->m_master);
-       unsigned long                   was_cyclic;
-       unsigned int                    reg_width;
-       unsigned int                    periods;
-@@ -1374,9 +1318,6 @@ struct dw_cyclic_desc *dw_dma_cyclic_pre
-       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;
-@@ -1392,50 +1333,50 @@ struct dw_cyclic_desc *dw_dma_cyclic_pre
-               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);
-+                      lli_write(desc, dar, sconfig->dst_addr);
-+                      lli_write(desc, sar, buf_addr + period_len * i);
-+                      lli_write(desc, 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));
-+
-+                      lli_set(desc, 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);
-+                      lli_write(desc, dar, buf_addr + period_len * i);
-+                      lli_write(desc, sar, sconfig->src_addr);
-+                      lli_write(desc, 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));
-+
-+                      lli_set(desc, 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);
-+              lli_write(desc, ctlhi, period_len >> reg_width);
-               cdesc->desc[i] = desc;
-               if (last)
--                      last->lli.llp = desc->txd.phys;
-+                      lli_write(last, llp, desc->txd.phys | lms);
-               last = desc;
-       }
-       /* Let's make a cyclic list */
--      last->lli.llp = cdesc->desc[0]->txd.phys;
-+      lli_write(last, llp, cdesc->desc[0]->txd.phys | lms);
-       dev_dbg(chan2dev(&dwc->chan),
-                       "cyclic prepared buf %pad len %zu period %zu periods %d\n",
-@@ -1466,7 +1407,7 @@ void dw_dma_cyclic_free(struct dma_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 int            i;
-       unsigned long           flags;
-       dev_dbg(chan2dev(&dwc->chan), "%s\n", __func__);
-@@ -1490,32 +1431,38 @@ void dw_dma_cyclic_free(struct dma_chan
-       kfree(cdesc->desc);
-       kfree(cdesc);
-+      dwc->cdesc = NULL;
-+
-       clear_bit(DW_DMA_IS_CYCLIC, &dwc->flags);
- }
- EXPORT_SYMBOL(dw_dma_cyclic_free);
- /*----------------------------------------------------------------------*/
--int dw_dma_probe(struct dw_dma_chip *chip, struct dw_dma_platform_data *pdata)
-+int dw_dma_probe(struct dw_dma_chip *chip)
- {
-+      struct dw_dma_platform_data *pdata;
-       struct dw_dma           *dw;
-       bool                    autocfg = false;
-       unsigned int            dw_params;
--      unsigned int            max_blk_size = 0;
-+      unsigned int            i;
-       int                     err;
--      int                     i;
-       dw = devm_kzalloc(chip->dev, sizeof(*dw), GFP_KERNEL);
-       if (!dw)
-               return -ENOMEM;
-+      dw->pdata = devm_kzalloc(chip->dev, sizeof(*dw->pdata), GFP_KERNEL);
-+      if (!dw->pdata)
-+              return -ENOMEM;
-+
-       dw->regs = chip->regs;
-       chip->dw = dw;
-       pm_runtime_get_sync(chip->dev);
--      if (!pdata) {
--              dw_params = dma_read_byaddr(chip->regs, DW_PARAMS);
-+      if (!chip->pdata) {
-+              dw_params = dma_readl(dw, DW_PARAMS);
-               dev_dbg(chip->dev, "DW_PARAMS: 0x%08x\n", dw_params);
-               autocfg = dw_params >> DW_PARAMS_EN & 1;
-@@ -1524,29 +1471,31 @@ int dw_dma_probe(struct dw_dma_chip *chi
-                       goto err_pdata;
-               }
--              pdata = devm_kzalloc(chip->dev, sizeof(*pdata), GFP_KERNEL);
--              if (!pdata) {
--                      err = -ENOMEM;
--                      goto err_pdata;
--              }
-+              /* Reassign the platform data pointer */
-+              pdata = dw->pdata;
-               /* Get hardware configuration parameters */
-               pdata->nr_channels = (dw_params >> DW_PARAMS_NR_CHAN & 7) + 1;
-               pdata->nr_masters = (dw_params >> DW_PARAMS_NR_MASTER & 3) + 1;
-               for (i = 0; i < pdata->nr_masters; i++) {
-                       pdata->data_width[i] =
--                              (dw_params >> DW_PARAMS_DATA_WIDTH(i) & 3) + 2;
-+                              4 << (dw_params >> DW_PARAMS_DATA_WIDTH(i) & 3);
-               }
--              max_blk_size = dma_readl(dw, MAX_BLK_SIZE);
-+              pdata->block_size = dma_readl(dw, MAX_BLK_SIZE);
-               /* Fill platform data with the default values */
-               pdata->is_private = true;
-               pdata->is_memcpy = true;
-               pdata->chan_allocation_order = CHAN_ALLOCATION_ASCENDING;
-               pdata->chan_priority = CHAN_PRIORITY_ASCENDING;
--      } else if (pdata->nr_channels > DW_DMA_MAX_NR_CHANNELS) {
-+      } else if (chip->pdata->nr_channels > DW_DMA_MAX_NR_CHANNELS) {
-               err = -EINVAL;
-               goto err_pdata;
-+      } else {
-+              memcpy(dw->pdata, chip->pdata, sizeof(*dw->pdata));
-+
-+              /* Reassign the platform data pointer */
-+              pdata = dw->pdata;
-       }
-       dw->chan = devm_kcalloc(chip->dev, pdata->nr_channels, sizeof(*dw->chan),
-@@ -1556,11 +1505,6 @@ int dw_dma_probe(struct dw_dma_chip *chi
-               goto err_pdata;
-       }
--      /* Get hardware configuration parameters */
--      dw->nr_masters = pdata->nr_masters;
--      for (i = 0; i < dw->nr_masters; i++)
--              dw->data_width[i] = pdata->data_width[i];
--
-       /* Calculate all channel mask before DMA setup */
-       dw->all_chan_mask = (1 << pdata->nr_channels) - 1;
-@@ -1607,7 +1551,6 @@ int dw_dma_probe(struct dw_dma_chip *chi
-               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);
-@@ -1615,11 +1558,9 @@ int dw_dma_probe(struct dw_dma_chip *chi
-               /* Hardware configuration */
-               if (autocfg) {
--                      unsigned int dwc_params;
-                       unsigned int r = DW_DMA_MAX_NR_CHANNELS - i - 1;
--                      void __iomem *addr = chip->regs + r * sizeof(u32);
--
--                      dwc_params = dma_read_byaddr(addr, DWC_PARAMS);
-+                      void __iomem *addr = &__dw_regs(dw)->DWC_PARAMS[r];
-+                      unsigned int dwc_params = dma_readl_native(addr);
-                       dev_dbg(chip->dev, "DWC_PARAMS[%d]: 0x%08x\n", i,
-                                          dwc_params);
-@@ -1630,16 +1571,15 @@ int dw_dma_probe(struct dw_dma_chip *chi
-                        * up to 0x0a for 4095.
-                        */
-                       dwc->block_size =
--                              (4 << ((max_blk_size >> 4 * i) & 0xf)) - 1;
-+                              (4 << ((pdata->block_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, DWC_LLP_LOC(0xffffffff));
-+                      dwc->nollp = DWC_LLP_LOC(channel_readl(dwc, LLP)) == 0;
-                       channel_writel(dwc, LLP, 0);
-               }
-       }
---- a/drivers/dma/dw/pci.c
-+++ b/drivers/dma/dw/pci.c
-@@ -17,8 +17,8 @@
- static int dw_pci_probe(struct pci_dev *pdev, const struct pci_device_id *pid)
- {
-+      const struct dw_dma_platform_data *pdata = (void *)pid->driver_data;
-       struct dw_dma_chip *chip;
--      struct dw_dma_platform_data *pdata = (void *)pid->driver_data;
-       int ret;
-       ret = pcim_enable_device(pdev);
-@@ -49,8 +49,9 @@ static int dw_pci_probe(struct pci_dev *
-       chip->dev = &pdev->dev;
-       chip->regs = pcim_iomap_table(pdev)[0];
-       chip->irq = pdev->irq;
-+      chip->pdata = pdata;
--      ret = dw_dma_probe(chip, pdata);
-+      ret = dw_dma_probe(chip);
-       if (ret)
-               return ret;
-@@ -108,6 +109,10 @@ static const struct pci_device_id dw_pci
-       /* Haswell */
-       { PCI_VDEVICE(INTEL, 0x9c60) },
-+
-+      /* Broadwell */
-+      { PCI_VDEVICE(INTEL, 0x9ce0) },
-+
-       { }
- };
- MODULE_DEVICE_TABLE(pci, dw_pci_id_table);
---- a/drivers/dma/dw/platform.c
-+++ b/drivers/dma/dw/platform.c
-@@ -42,13 +42,13 @@ static struct dma_chan *dw_dma_of_xlate(
-       slave.src_id = dma_spec->args[0];
-       slave.dst_id = dma_spec->args[0];
--      slave.src_master = dma_spec->args[1];
--      slave.dst_master = dma_spec->args[2];
-+      slave.m_master = dma_spec->args[1];
-+      slave.p_master = dma_spec->args[2];
-       if (WARN_ON(slave.src_id >= DW_DMA_MAX_NR_REQUESTS ||
-                   slave.dst_id >= DW_DMA_MAX_NR_REQUESTS ||
--                  slave.src_master >= dw->nr_masters ||
--                  slave.dst_master >= dw->nr_masters))
-+                  slave.m_master >= dw->pdata->nr_masters ||
-+                  slave.p_master >= dw->pdata->nr_masters))
-               return NULL;
-       dma_cap_zero(cap);
-@@ -66,8 +66,8 @@ static bool dw_dma_acpi_filter(struct dm
-               .dma_dev = dma_spec->dev,
-               .src_id = dma_spec->slave_id,
-               .dst_id = dma_spec->slave_id,
--              .src_master = 1,
--              .dst_master = 0,
-+              .m_master = 0,
-+              .p_master = 1,
-       };
-       return dw_dma_filter(chan, &slave);
-@@ -103,18 +103,28 @@ dw_dma_parse_dt(struct platform_device *
-       struct device_node *np = pdev->dev.of_node;
-       struct dw_dma_platform_data *pdata;
-       u32 tmp, arr[DW_DMA_MAX_NR_MASTERS];
-+      u32 nr_masters;
-+      u32 nr_channels;
-       if (!np) {
-               dev_err(&pdev->dev, "Missing DT data\n");
-               return NULL;
-       }
-+      if (of_property_read_u32(np, "dma-masters", &nr_masters))
-+              return NULL;
-+      if (nr_masters < 1 || nr_masters > DW_DMA_MAX_NR_MASTERS)
-+              return NULL;
-+
-+      if (of_property_read_u32(np, "dma-channels", &nr_channels))
-+              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;
-+      pdata->nr_masters = nr_masters;
-+      pdata->nr_channels = nr_channels;
-       if (of_property_read_bool(np, "is_private"))
-               pdata->is_private = true;
-@@ -128,17 +138,13 @@ dw_dma_parse_dt(struct platform_device *
-       if (!of_property_read_u32(np, "block_size", &tmp))
-               pdata->block_size = tmp;
--      if (!of_property_read_u32(np, "dma-masters", &tmp)) {
--              if (tmp > DW_DMA_MAX_NR_MASTERS)
--                      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++)
-+      if (!of_property_read_u32_array(np, "data-width", arr, nr_masters)) {
-+              for (tmp = 0; tmp < nr_masters; tmp++)
-                       pdata->data_width[tmp] = arr[tmp];
-+      } else if (!of_property_read_u32_array(np, "data_width", arr, nr_masters)) {
-+              for (tmp = 0; tmp < nr_masters; tmp++)
-+                      pdata->data_width[tmp] = BIT(arr[tmp] & 0x07);
-+      }
-       return pdata;
- }
-@@ -155,8 +161,7 @@ static int dw_probe(struct platform_devi
-       struct dw_dma_chip *chip;
-       struct device *dev = &pdev->dev;
-       struct resource *mem;
--      const struct acpi_device_id *id;
--      struct dw_dma_platform_data *pdata;
-+      const struct dw_dma_platform_data *pdata;
-       int err;
-       chip = devm_kzalloc(dev, sizeof(*chip), GFP_KERNEL);
-@@ -179,13 +184,9 @@ static int dw_probe(struct platform_devi
-       pdata = dev_get_platdata(dev);
-       if (!pdata)
-               pdata = dw_dma_parse_dt(pdev);
--      if (!pdata && has_acpi_companion(dev)) {
--              id = acpi_match_device(dev->driver->acpi_match_table, dev);
--              if (id)
--                      pdata = (struct dw_dma_platform_data *)id->driver_data;
--      }
-       chip->dev = dev;
-+      chip->pdata = pdata;
-       chip->clk = devm_clk_get(chip->dev, "hclk");
-       if (IS_ERR(chip->clk))
-@@ -196,7 +197,7 @@ static int dw_probe(struct platform_devi
-       pm_runtime_enable(&pdev->dev);
--      err = dw_dma_probe(chip, pdata);
-+      err = dw_dma_probe(chip);
-       if (err)
-               goto err_dw_dma_probe;
-@@ -239,7 +240,19 @@ static void dw_shutdown(struct platform_
- {
-       struct dw_dma_chip *chip = platform_get_drvdata(pdev);
-+      /*
-+       * We have to call dw_dma_disable() to stop any ongoing transfer. On
-+       * some platforms we can't do that since DMA device is powered off.
-+       * Moreover we have no possibility to check if the platform is affected
-+       * or not. That's why we call pm_runtime_get_sync() / pm_runtime_put()
-+       * unconditionally. On the other hand we can't use
-+       * pm_runtime_suspended() because runtime PM framework is not fully
-+       * used by the driver.
-+       */
-+      pm_runtime_get_sync(chip->dev);
-       dw_dma_disable(chip);
-+      pm_runtime_put_sync_suspend(chip->dev);
-+
-       clk_disable_unprepare(chip->clk);
- }
-@@ -252,17 +265,8 @@ MODULE_DEVICE_TABLE(of, dw_dma_of_id_tab
- #endif
- #ifdef CONFIG_ACPI
--static struct dw_dma_platform_data dw_dma_acpi_pdata = {
--      .nr_channels = 8,
--      .is_private = true,
--      .chan_allocation_order = CHAN_ALLOCATION_ASCENDING,
--      .chan_priority = CHAN_PRIORITY_ASCENDING,
--      .block_size = 4095,
--      .nr_masters = 2,
--};
--
- static const struct acpi_device_id dw_dma_acpi_id_table[] = {
--      { "INTL9C60", (kernel_ulong_t)&dw_dma_acpi_pdata },
-+      { "INTL9C60", 0 },
-       { }
- };
- MODULE_DEVICE_TABLE(acpi, dw_dma_acpi_id_table);
---- a/drivers/dma/dw/regs.h
-+++ b/drivers/dma/dw/regs.h
-@@ -114,10 +114,6 @@ struct dw_dma_regs {
- #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 */
-@@ -143,6 +139,10 @@ enum dw_dma_msize {
-       DW_DMA_MSIZE_256,
- };
-+/* Bitfields in LLP */
-+#define DWC_LLP_LMS(x)                ((x) & 3)       /* list master select */
-+#define DWC_LLP_LOC(x)                ((x) & ~3)      /* next lli */
-+
- /* Bitfields in CTL_LO */
- #define DWC_CTLL_INT_EN               (1 << 0)        /* irqs enabled? */
- #define DWC_CTLL_DST_WIDTH(n) ((n)<<1)        /* bytes per element */
-@@ -150,7 +150,7 @@ enum dw_dma_msize {
- #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_INC      (0<<9)          /* 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 */
-@@ -216,6 +216,8 @@ enum dw_dma_msize {
- enum dw_dmac_flags {
-       DW_DMA_IS_CYCLIC = 0,
-       DW_DMA_IS_SOFT_LLP = 1,
-+      DW_DMA_IS_PAUSED = 2,
-+      DW_DMA_IS_INITIALIZED = 3,
- };
- struct dw_dma_chan {
-@@ -224,8 +226,6 @@ struct dw_dma_chan {
-       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;
-@@ -236,8 +236,6 @@ struct dw_dma_chan {
-       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;
-@@ -249,8 +247,8 @@ struct dw_dma_chan {
-       /* custom slave configuration */
-       u8                      src_id;
-       u8                      dst_id;
--      u8                      src_master;
--      u8                      dst_master;
-+      u8                      m_master;
-+      u8                      p_master;
-       /* configuration passed via .device_config */
-       struct dma_slave_config dma_sconfig;
-@@ -283,9 +281,8 @@ struct dw_dma {
-       u8                      all_chan_mask;
-       u8                      in_use;
--      /* hardware configuration */
--      unsigned char           nr_masters;
--      unsigned char           data_width[DW_DMA_MAX_NR_MASTERS];
-+      /* platform data */
-+      struct dw_dma_platform_data     *pdata;
- };
- static inline struct dw_dma_regs __iomem *__dw_regs(struct dw_dma *dw)
-@@ -308,32 +305,51 @@ static inline struct dw_dma *to_dw_dma(s
-       return container_of(ddev, struct dw_dma, dma);
- }
-+#ifdef CONFIG_DW_DMAC_BIG_ENDIAN_IO
-+typedef __be32 __dw32;
-+#else
-+typedef __le32 __dw32;
-+#endif
-+
- /* 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;
-+      __dw32          sar;
-+      __dw32          dar;
-+      __dw32          llp;            /* chain to next lli */
-+      __dw32          ctllo;
-       /* values that may get written back: */
--      u32             ctlhi;
-+      __dw32          ctlhi;
-       /* sstat and dstat can snapshot peripheral register state.
-        * silicon config may discard either or both...
-        */
--      u32             sstat;
--      u32             dstat;
-+      __dw32          sstat;
-+      __dw32          dstat;
- };
- struct dw_desc {
-       /* FIRST values the hardware uses */
-       struct dw_lli                   lli;
-+#ifdef CONFIG_DW_DMAC_BIG_ENDIAN_IO
-+#define lli_set(d, reg, v)            ((d)->lli.reg |= cpu_to_be32(v))
-+#define lli_clear(d, reg, v)          ((d)->lli.reg &= ~cpu_to_be32(v))
-+#define lli_read(d, reg)              be32_to_cpu((d)->lli.reg)
-+#define lli_write(d, reg, v)          ((d)->lli.reg = cpu_to_be32(v))
-+#else
-+#define lli_set(d, reg, v)            ((d)->lli.reg |= cpu_to_le32(v))
-+#define lli_clear(d, reg, v)          ((d)->lli.reg &= ~cpu_to_le32(v))
-+#define lli_read(d, reg)              le32_to_cpu((d)->lli.reg)
-+#define lli_write(d, reg, v)          ((d)->lli.reg = cpu_to_le32(v))
-+#endif
-+
-       /* 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;
-+      u32                             residue;
- };
- #define to_dw_desc(h) list_entry(h, struct dw_desc, desc_node)
---- a/include/linux/dma/dw.h
-+++ b/include/linux/dma/dw.h
-@@ -27,6 +27,7 @@ struct dw_dma;
-  * @regs:             memory mapped I/O space
-  * @clk:              hclk clock
-  * @dw:                       struct dw_dma that is filed by dw_dma_probe()
-+ * @pdata:            pointer to platform data
-  */
- struct dw_dma_chip {
-       struct device   *dev;
-@@ -34,10 +35,12 @@ struct dw_dma_chip {
-       void __iomem    *regs;
-       struct clk      *clk;
-       struct dw_dma   *dw;
-+
-+      const struct dw_dma_platform_data       *pdata;
- };
- /* Export to the platform drivers */
--int dw_dma_probe(struct dw_dma_chip *chip, struct dw_dma_platform_data *pdata);
-+int dw_dma_probe(struct dw_dma_chip *chip);
- int dw_dma_remove(struct dw_dma_chip *chip);
- /* DMA API extensions */
---- a/include/linux/platform_data/dma-dw.h
-+++ b/include/linux/platform_data/dma-dw.h
-@@ -21,15 +21,15 @@
-  * @dma_dev:  required DMA master device
-  * @src_id:   src request line
-  * @dst_id:   dst request line
-- * @src_master: src master for transfers on allocated channel.
-- * @dst_master: dest master for transfers on allocated channel.
-+ * @m_master: memory master for transfers on allocated channel
-+ * @p_master: peripheral master for transfers on allocated channel
-  */
- struct dw_dma_slave {
-       struct device           *dma_dev;
-       u8                      src_id;
-       u8                      dst_id;
--      u8                      src_master;
--      u8                      dst_master;
-+      u8                      m_master;
-+      u8                      p_master;
- };
- /**
-@@ -43,7 +43,7 @@ struct dw_dma_slave {
-  * @block_size: Maximum block size supported by the controller
-  * @nr_masters: Number of AHB masters supported by the controller
-  * @data_width: Maximum data width supported by hardware per AHB master
-- *            (0 - 8bits, 1 - 16bits, ..., 5 - 256bits)
-+ *            (in bytes, power of 2)
-  */
- struct dw_dma_platform_data {
-       unsigned int    nr_channels;
-@@ -55,7 +55,7 @@ struct dw_dma_platform_data {
- #define CHAN_PRIORITY_ASCENDING               0       /* chan0 highest */
- #define CHAN_PRIORITY_DESCENDING      1       /* chan7 highest */
-       unsigned char   chan_priority;
--      unsigned short  block_size;
-+      unsigned int    block_size;
-       unsigned char   nr_masters;
-       unsigned char   data_width[DW_DMA_MAX_NR_MASTERS];
- };