Merge tag 'dmaengine-4.16-rc1' of git://git.infradead.org/users/vkoul/slave-dma
authorLinus Torvalds <torvalds@linux-foundation.org>
Wed, 31 Jan 2018 19:52:20 +0000 (11:52 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Wed, 31 Jan 2018 19:52:20 +0000 (11:52 -0800)
Pull dmaengine updates from Vinod Koul:
 "This time is smallish update with updates mainly to drivers:

   - updates to xilinx and zynqmp dma controllers

   - update reside calculation for rcar controller

   - more RSTify fixes for documentation

   - add support for race free transfer termination and updating for
     users for that

   - support for new rev of hidma with addition new APIs to get device
     match data in ACPI/OF

   - random updates to bunch of other drivers"

* tag 'dmaengine-4.16-rc1' of git://git.infradead.org/users/vkoul/slave-dma: (47 commits)
  dmaengine: dmatest: fix container_of member in dmatest_callback
  dmaengine: stm32-dmamux: Remove unnecessary platform_get_resource() error check
  dmaengine: sprd: statify 'sprd_dma_prep_dma_memcpy'
  dmaengine: qcom_hidma: simplify DT resource parsing
  dmaengine: xilinx_dma: Free BD consistent memory
  dmaengine: xilinx_dma: Fix warning variable prev set but not used
  dmaengine: xilinx_dma: properly configure the SG mode bit in the driver for cdma
  dmaengine: doc: format struct fields using monospace
  dmaengine: doc: fix bullet list formatting
  dmaengine: ti-dma-crossbar: Fix event mapping for TPCC_EVT_MUX_60_63
  dmaengine: cppi41: Fix channel queues array size check
  dmaengine: imx-sdma: Add MODULE_FIRMWARE
  dmaengine: xilinx_dma: Fix typos
  dmaengine: xilinx_dma: Differentiate probe based on the ip type
  dmaengine: xilinx_dma: fix style issues from checkpatch
  dmaengine: xilinx_dma: Fix kernel doc warnings
  dmaengine: xilinx_dma: Fix race condition in the driver for multiple descriptor scenario
  dmaeninge: xilinx_dma: Fix bug in multiple frame stores scenario in vdma
  dmaengine: xilinx_dma: Check for channel idle state before submitting dma descriptor
  dmaengine: zynqmp_dma: Fix race condition in the probe
  ...

1  2 
Documentation/devicetree/bindings/dma/qcom_hidma_mgmt.txt
drivers/dma/sh/rcar-dmac.c
include/linux/acpi.h

@@@ -47,8 -47,8 +47,8 @@@ When the OS is not in control of the ma
  the channel nodes appear on their own, not under a management node.
  
  Required properties:
- - compatible: must contain "qcom,hidma-1.0" for initial HW or "qcom,hidma-1.1"
- for MSI capable HW.
+ - compatible: must contain "qcom,hidma-1.0" for initial HW or
  "qcom,hidma-1.1"/"qcom,hidma-1.2" for MSI capable HW.
  - reg: Addresses for the transfer and event channel
  - interrupts: Should contain the event interrupt
  - desc-count: Number of asynchronous requests this channel can handle
@@@ -73,7 -73,7 +73,7 @@@ Hypervisor OS configuration
                max-read-transactions = <31>;
                channel-reset-timeout-cycles = <0x500>;
  
 -              hidma_24: dma-controller@0x5c050000 {
 +              hidma_24: dma-controller@5c050000 {
                        compatible = "qcom,hidma-1.0";
                        reg = <0 0x5c050000 0x0 0x1000>,
                              <0 0x5c0b0000 0x0 0x1000>;
@@@ -85,7 -85,7 +85,7 @@@
  
  Guest OS configuration:
  
 -      hidma_24: dma-controller@0x5c050000 {
 +      hidma_24: dma-controller@5c050000 {
                compatible = "qcom,hidma-1.0";
                reg = <0 0x5c050000 0x0 0x1000>,
                      <0 0x5c0b0000 0x0 0x1000>;
@@@ -10,6 -10,7 +10,7 @@@
   * published by the Free Software Foundation.
   */
  
+ #include <linux/delay.h>
  #include <linux/dma-mapping.h>
  #include <linux/dmaengine.h>
  #include <linux/interrupt.h>
@@@ -741,6 -742,41 +742,41 @@@ static int rcar_dmac_fill_hwdesc(struc
  /* -----------------------------------------------------------------------------
   * Stop and reset
   */
+ static void rcar_dmac_chcr_de_barrier(struct rcar_dmac_chan *chan)
+ {
+       u32 chcr;
+       unsigned int i;
+       /*
+        * Ensure that the setting of the DE bit is actually 0 after
+        * clearing it.
+        */
+       for (i = 0; i < 1024; i++) {
+               chcr = rcar_dmac_chan_read(chan, RCAR_DMACHCR);
+               if (!(chcr & RCAR_DMACHCR_DE))
+                       return;
+               udelay(1);
+       }
+       dev_err(chan->chan.device->dev, "CHCR DE check error\n");
+ }
+ static void rcar_dmac_sync_tcr(struct rcar_dmac_chan *chan)
+ {
+       u32 chcr = rcar_dmac_chan_read(chan, RCAR_DMACHCR);
+       if (!(chcr & RCAR_DMACHCR_DE))
+               return;
+       /* set DE=0 and flush remaining data */
+       rcar_dmac_chan_write(chan, RCAR_DMACHCR, (chcr & ~RCAR_DMACHCR_DE));
+       /* make sure all remaining data was flushed */
+       rcar_dmac_chcr_de_barrier(chan);
+       /* back DE */
+       rcar_dmac_chan_write(chan, RCAR_DMACHCR, chcr);
+ }
  
  static void rcar_dmac_chan_halt(struct rcar_dmac_chan *chan)
  {
        chcr &= ~(RCAR_DMACHCR_DSE | RCAR_DMACHCR_DSIE | RCAR_DMACHCR_IE |
                  RCAR_DMACHCR_TE | RCAR_DMACHCR_DE);
        rcar_dmac_chan_write(chan, RCAR_DMACHCR, chcr);
+       rcar_dmac_chcr_de_barrier(chan);
  }
  
  static void rcar_dmac_chan_reinit(struct rcar_dmac_chan *chan)
@@@ -1309,8 -1346,11 +1346,11 @@@ static unsigned int rcar_dmac_chan_get_
                residue += chunk->size;
        }
  
+       if (desc->direction == DMA_DEV_TO_MEM)
+               rcar_dmac_sync_tcr(chan);
        /* Add the residue for the current chunk. */
-       residue += rcar_dmac_chan_read(chan, RCAR_DMATCR) << desc->xfer_shift;
+       residue += rcar_dmac_chan_read(chan, RCAR_DMATCRB) << desc->xfer_shift;
  
        return residue;
  }
@@@ -1481,6 -1521,8 +1521,8 @@@ static irqreturn_t rcar_dmac_isr_channe
        if (chcr & RCAR_DMACHCR_TE)
                mask |= RCAR_DMACHCR_DE;
        rcar_dmac_chan_write(chan, RCAR_DMACHCR, chcr & ~mask);
+       if (mask & RCAR_DMACHCR_DE)
+               rcar_dmac_chcr_de_barrier(chan);
  
        if (chcr & RCAR_DMACHCR_DSE)
                ret |= rcar_dmac_isr_desc_stage_end(chan);
@@@ -1615,6 -1657,22 +1657,6 @@@ static struct dma_chan *rcar_dmac_of_xl
   * Power management
   */
  
 -#ifdef CONFIG_PM_SLEEP
 -static int rcar_dmac_sleep_suspend(struct device *dev)
 -{
 -      /*
 -       * TODO: Wait for the current transfer to complete and stop the device.
 -       */
 -      return 0;
 -}
 -
 -static int rcar_dmac_sleep_resume(struct device *dev)
 -{
 -      /* TODO: Resume transfers, if any. */
 -      return 0;
 -}
 -#endif
 -
  #ifdef CONFIG_PM
  static int rcar_dmac_runtime_suspend(struct device *dev)
  {
@@@ -1630,13 -1688,7 +1672,13 @@@ static int rcar_dmac_runtime_resume(str
  #endif
  
  static const struct dev_pm_ops rcar_dmac_pm = {
 -      SET_SYSTEM_SLEEP_PM_OPS(rcar_dmac_sleep_suspend, rcar_dmac_sleep_resume)
 +      /*
 +       * TODO for system sleep/resume:
 +       *   - Wait for the current transfer to complete and stop the device,
 +       *   - Resume transfers, if any.
 +       */
 +      SET_LATE_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
 +                                   pm_runtime_force_resume)
        SET_RUNTIME_PM_OPS(rcar_dmac_runtime_suspend, rcar_dmac_runtime_resume,
                           NULL)
  };
diff --combined include/linux/acpi.h
@@@ -451,7 -451,6 +451,7 @@@ void __init acpi_no_s4_hw_signature(voi
  void __init acpi_old_suspend_ordering(void);
  void __init acpi_nvs_nosave(void);
  void __init acpi_nvs_nosave_s3(void);
 +void __init acpi_sleep_no_blacklist(void);
  #endif /* CONFIG_PM_SLEEP */
  
  struct acpi_osc_context {
@@@ -585,6 -584,7 +585,7 @@@ extern int acpi_nvs_for_each_region(in
  const struct acpi_device_id *acpi_match_device(const struct acpi_device_id *ids,
                                               const struct device *dev);
  
+ void *acpi_get_match_data(const struct device *dev);
  extern bool acpi_driver_match_device(struct device *dev,
                                     const struct device_driver *drv);
  int acpi_device_uevent_modalias(struct device *, struct kobj_uevent_env *);
@@@ -641,12 -641,6 +642,12 @@@ static inline bool acpi_dev_present(con
        return false;
  }
  
 +static inline const char *
 +acpi_dev_get_first_match_name(const char *hid, const char *uid, s64 hrv)
 +{
 +      return NULL;
 +}
 +
  static inline bool is_acpi_node(struct fwnode_handle *fwnode)
  {
        return false;
@@@ -758,6 -752,11 +759,11 @@@ struct acpi_device_id
  
  static inline const struct acpi_device_id *acpi_match_device(
        const struct acpi_device_id *ids, const struct device *dev)
+ {
+       return NULL;
+ }
+ static inline void *acpi_get_match_data(const struct device *dev)
  {
        return NULL;
  }