Skip to content

Commit

Permalink
Merge tag 'dmaengine-5.10-rc1' of git://git.kernel.org/pub/scm/linux/…
Browse files Browse the repository at this point in the history
…kernel/git/vkoul/dmaengine

Pull dmaengine updates from Vinod Koul:
 "Core:

   - Mark dma_request_slave_channel() deprecated in favour of
     dma_request_chan()

   - subsystem conversion for tasklet_setup() API

   - subsystem removal of local dma_parms for arm drivers

  Also updates to bunch of driver notably TI, DW and AXI-DMAC"

* tag 'dmaengine-5.10-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/vkoul/dmaengine: (104 commits)
  dmaengine: owl-dma: fix kernel-doc style for enum
  dmaengine: zynqmp_dma: fix kernel-doc style for tasklet
  dmaengine: xilinx_dma: fix kernel-doc style for tasklet
  dmaengine: qcom: bam_dma: fix kernel-doc style for tasklet
  dmaengine: altera-msgdma: fix kernel-doc style for tasklet
  dmaengine: xilinx: dpdma: convert tasklets to use new tasklet_setup() API
  dmaengine: sf-pdma: convert tasklets to use new tasklet_setup() API
  dt-bindings: Fix 'reg' size issues in zynqmp examples
  dmaengine: rcar-dmac: drop double zeroing
  dmaengine: sh: drop double zeroing
  dmaengine: ioat: Allocate correct size for descriptor chunk
  dmaengine: ti: k3-udma: use devm_platform_ioremap_resource_byname
  dmaengine: fsl: remove bad channel update
  dmaengine: dma-jz4780: Fix race in jz4780_dma_tx_status
  dmaengine: pl330: fix argument for tasklet
  dmaengine: dmatest: Return boolean result directly in filter()
  dmaengine: dmatest: Check list for emptiness before access its last entry
  dmaengine: ti: k3-udma-glue: fix channel enable functions
  dmaengine: iop-adma: Fix pointer cast warnings
  dmaengine: dw-edma: Fix Using plain integer as NULL pointer in dw-edma-v0-debugfs.c
  ...
  • Loading branch information
Linus Torvalds committed Oct 15, 2020
2 parents c48b75b + fc143e3 commit f065199
Show file tree
Hide file tree
Showing 81 changed files with 930 additions and 437 deletions.
20 changes: 20 additions & 0 deletions Documentation/ABI/stable/sysfs-driver-dma-idxd
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,12 @@ Description: The maximum number of bandwidth tokens that may be in use at
one time by operations that access low bandwidth memory in the
device.

What: /sys/bus/dsa/devices/dsa<m>/cmd_status
Date: Aug 28, 2020
KernelVersion: 5.10.0
Contact: dmaengine@vger.kernel.org
Description: The last executed device administrative command's status/error.

What: /sys/bus/dsa/devices/wq<m>.<n>/group_id
Date: Oct 25, 2019
KernelVersion: 5.6.0
Expand Down Expand Up @@ -170,6 +176,20 @@ Contact: dmaengine@vger.kernel.org
Description: The number of entries in this work queue that may be filled
via a limited portal.

What: /sys/bus/dsa/devices/wq<m>.<n>/max_transfer_size
Date: Aug 28, 2020
KernelVersion: 5.10.0
Contact: dmaengine@vger.kernel.org
Description: The max transfer sized for this workqueue. Cannot exceed device
max transfer size. Configurable parameter.

What: /sys/bus/dsa/devices/wq<m>.<n>/max_batch_size
Date: Aug 28, 2020
KernelVersion: 5.10.0
Contact: dmaengine@vger.kernel.org
Description: The max batch size for this workqueue. Cannot exceed device
max batch size. Configurable parameter.

What: /sys/bus/dsa/devices/engine<m>.<n>/group_id
Date: Oct 25, 2019
KernelVersion: 5.6.0
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ properties:
compatible:
items:
- enum:
- renesas,dmac-r8a7742 # RZ/G1H
- renesas,dmac-r8a7743 # RZ/G1M
- renesas,dmac-r8a7744 # RZ/G1N
- renesas,dmac-r8a7745 # RZ/G1E
Expand Down
7 changes: 5 additions & 2 deletions Documentation/devicetree/bindings/dma/snps,dma-spear1340.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,15 @@ properties:
const: snps,dma-spear1340

"#dma-cells":
const: 3
minimum: 3
maximum: 4
description: |
First cell is a phandle pointing to the DMA controller. Second one is
the DMA request line number. Third cell is the memory master identifier
for transfers on dynamically allocated channel. Fourth cell is the
peripheral master identifier for transfers on an allocated channel.
peripheral master identifier for transfers on an allocated channel. Fifth
cell is an optional mask of the DMA channels permitted to be allocated
for the corresponding client device.
reg:
maxItems: 1
Expand Down
8 changes: 4 additions & 4 deletions drivers/dma/altera-msgdma.c
Original file line number Diff line number Diff line change
Expand Up @@ -678,11 +678,11 @@ static int msgdma_alloc_chan_resources(struct dma_chan *dchan)

/**
* msgdma_tasklet - Schedule completion tasklet
* @data: Pointer to the Altera sSGDMA channel structure
* @t: Pointer to the Altera sSGDMA channel structure
*/
static void msgdma_tasklet(unsigned long data)
static void msgdma_tasklet(struct tasklet_struct *t)
{
struct msgdma_device *mdev = (struct msgdma_device *)data;
struct msgdma_device *mdev = from_tasklet(mdev, t, irq_tasklet);
u32 count;
u32 __maybe_unused size;
u32 __maybe_unused status;
Expand Down Expand Up @@ -830,7 +830,7 @@ static int msgdma_probe(struct platform_device *pdev)
if (ret)
return ret;

tasklet_init(&mdev->irq_tasklet, msgdma_tasklet, (unsigned long)mdev);
tasklet_setup(&mdev->irq_tasklet, msgdma_tasklet);

dma_cookie_init(&mdev->dmachan);

Expand Down
7 changes: 3 additions & 4 deletions drivers/dma/at_hdmac.c
Original file line number Diff line number Diff line change
Expand Up @@ -598,9 +598,9 @@ static void atc_handle_cyclic(struct at_dma_chan *atchan)

/*-- IRQ & Tasklet ---------------------------------------------------*/

static void atc_tasklet(unsigned long data)
static void atc_tasklet(struct tasklet_struct *t)
{
struct at_dma_chan *atchan = (struct at_dma_chan *)data;
struct at_dma_chan *atchan = from_tasklet(atchan, t, tasklet);

if (test_and_clear_bit(ATC_IS_ERROR, &atchan->status))
return atc_handle_error(atchan);
Expand Down Expand Up @@ -1892,8 +1892,7 @@ static int __init at_dma_probe(struct platform_device *pdev)
INIT_LIST_HEAD(&atchan->queue);
INIT_LIST_HEAD(&atchan->free_list);

tasklet_init(&atchan->tasklet, atc_tasklet,
(unsigned long)atchan);
tasklet_setup(&atchan->tasklet, atc_tasklet);
atc_enable_chan_irq(atdma, i);
}

Expand Down
7 changes: 3 additions & 4 deletions drivers/dma/at_xdmac.c
Original file line number Diff line number Diff line change
Expand Up @@ -1613,9 +1613,9 @@ static void at_xdmac_handle_error(struct at_xdmac_chan *atchan)
/* Then continue with usual descriptor management */
}

static void at_xdmac_tasklet(unsigned long data)
static void at_xdmac_tasklet(struct tasklet_struct *t)
{
struct at_xdmac_chan *atchan = (struct at_xdmac_chan *)data;
struct at_xdmac_chan *atchan = from_tasklet(atchan, t, tasklet);
struct at_xdmac_desc *desc;
u32 error_mask;

Expand Down Expand Up @@ -2063,8 +2063,7 @@ static int at_xdmac_probe(struct platform_device *pdev)
spin_lock_init(&atchan->lock);
INIT_LIST_HEAD(&atchan->xfers_list);
INIT_LIST_HEAD(&atchan->free_descs_list);
tasklet_init(&atchan->tasklet, at_xdmac_tasklet,
(unsigned long)atchan);
tasklet_setup(&atchan->tasklet, at_xdmac_tasklet);

/* Clear pending interrupts. */
while (at_xdmac_chan_read(atchan, AT_XDMAC_CIS))
Expand Down
3 changes: 0 additions & 3 deletions drivers/dma/bcm2835-dma.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,14 +41,12 @@
* struct bcm2835_dmadev - BCM2835 DMA controller
* @ddev: DMA device
* @base: base address of register map
* @dma_parms: DMA parameters (to convey 1 GByte max segment size to clients)
* @zero_page: bus address of zero page (to detect transactions copying from
* zero page and avoid accessing memory if so)
*/
struct bcm2835_dmadev {
struct dma_device ddev;
void __iomem *base;
struct device_dma_parameters dma_parms;
dma_addr_t zero_page;
};

Expand Down Expand Up @@ -902,7 +900,6 @@ static int bcm2835_dma_probe(struct platform_device *pdev)
if (!od)
return -ENOMEM;

pdev->dev.dma_parms = &od->dma_parms;
dma_set_max_seg_size(&pdev->dev, 0x3FFFFFFF);

res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
Expand Down
7 changes: 3 additions & 4 deletions drivers/dma/coh901318.c
Original file line number Diff line number Diff line change
Expand Up @@ -1868,9 +1868,9 @@ static struct coh901318_desc *coh901318_queue_start(struct coh901318_chan *cohc)
* This tasklet is called from the interrupt handler to
* handle each descriptor (DMA job) that is sent to a channel.
*/
static void dma_tasklet(unsigned long data)
static void dma_tasklet(struct tasklet_struct *t)
{
struct coh901318_chan *cohc = (struct coh901318_chan *) data;
struct coh901318_chan *cohc = from_tasklet(cohc, t, tasklet);
struct coh901318_desc *cohd_fin;
unsigned long flags;
struct dmaengine_desc_callback cb;
Expand Down Expand Up @@ -2615,8 +2615,7 @@ static void coh901318_base_init(struct dma_device *dma, const int *pick_chans,
INIT_LIST_HEAD(&cohc->active);
INIT_LIST_HEAD(&cohc->queue);

tasklet_init(&cohc->tasklet, dma_tasklet,
(unsigned long) cohc);
tasklet_setup(&cohc->tasklet, dma_tasklet);

list_add_tail(&cohc->chan.device_node,
&dma->channels);
Expand Down
141 changes: 107 additions & 34 deletions drivers/dma/dma-axi-dmac.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
* Author: Lars-Peter Clausen <lars@metafoo.de>
*/

#include <linux/bitfield.h>
#include <linux/clk.h>
#include <linux/device.h>
#include <linux/dma-mapping.h>
Expand Down Expand Up @@ -45,6 +46,16 @@
* there is no address than can or needs to be configured for the device side.
*/

#define AXI_DMAC_REG_INTERFACE_DESC 0x10
#define AXI_DMAC_DMA_SRC_TYPE_MSK GENMASK(13, 12)
#define AXI_DMAC_DMA_SRC_TYPE_GET(x) FIELD_GET(AXI_DMAC_DMA_SRC_TYPE_MSK, x)
#define AXI_DMAC_DMA_SRC_WIDTH_MSK GENMASK(11, 8)
#define AXI_DMAC_DMA_SRC_WIDTH_GET(x) FIELD_GET(AXI_DMAC_DMA_SRC_WIDTH_MSK, x)
#define AXI_DMAC_DMA_DST_TYPE_MSK GENMASK(5, 4)
#define AXI_DMAC_DMA_DST_TYPE_GET(x) FIELD_GET(AXI_DMAC_DMA_DST_TYPE_MSK, x)
#define AXI_DMAC_DMA_DST_WIDTH_MSK GENMASK(3, 0)
#define AXI_DMAC_DMA_DST_WIDTH_GET(x) FIELD_GET(AXI_DMAC_DMA_DST_WIDTH_MSK, x)

#define AXI_DMAC_REG_IRQ_MASK 0x80
#define AXI_DMAC_REG_IRQ_PENDING 0x84
#define AXI_DMAC_REG_IRQ_SOURCE 0x88
Expand Down Expand Up @@ -134,8 +145,6 @@ struct axi_dmac {

struct dma_device dma_dev;
struct axi_dmac_chan chan;

struct device_dma_parameters dma_parms;
};

static struct axi_dmac *chan_to_axi_dmac(struct axi_dmac_chan *chan)
Expand Down Expand Up @@ -717,6 +726,20 @@ static const struct regmap_config axi_dmac_regmap_config = {
.writeable_reg = axi_dmac_regmap_rdwr,
};

static void axi_dmac_adjust_chan_params(struct axi_dmac_chan *chan)
{
chan->address_align_mask = max(chan->dest_width, chan->src_width) - 1;

if (axi_dmac_dest_is_mem(chan) && axi_dmac_src_is_mem(chan))
chan->direction = DMA_MEM_TO_MEM;
else if (!axi_dmac_dest_is_mem(chan) && axi_dmac_src_is_mem(chan))
chan->direction = DMA_MEM_TO_DEV;
else if (axi_dmac_dest_is_mem(chan) && !axi_dmac_src_is_mem(chan))
chan->direction = DMA_DEV_TO_MEM;
else
chan->direction = DMA_DEV_TO_DEV;
}

/*
* The configuration stored in the devicetree matches the configuration
* parameters of the peripheral instance and allows the driver to know which
Expand Down Expand Up @@ -760,26 +783,81 @@ static int axi_dmac_parse_chan_dt(struct device_node *of_chan,
return ret;
chan->dest_width = val / 8;

chan->address_align_mask = max(chan->dest_width, chan->src_width) - 1;
axi_dmac_adjust_chan_params(chan);

if (axi_dmac_dest_is_mem(chan) && axi_dmac_src_is_mem(chan))
chan->direction = DMA_MEM_TO_MEM;
else if (!axi_dmac_dest_is_mem(chan) && axi_dmac_src_is_mem(chan))
chan->direction = DMA_MEM_TO_DEV;
else if (axi_dmac_dest_is_mem(chan) && !axi_dmac_src_is_mem(chan))
chan->direction = DMA_DEV_TO_MEM;
else
chan->direction = DMA_DEV_TO_DEV;
return 0;
}

static int axi_dmac_parse_dt(struct device *dev, struct axi_dmac *dmac)
{
struct device_node *of_channels, *of_chan;
int ret;

of_channels = of_get_child_by_name(dev->of_node, "adi,channels");
if (of_channels == NULL)
return -ENODEV;

for_each_child_of_node(of_channels, of_chan) {
ret = axi_dmac_parse_chan_dt(of_chan, &dmac->chan);
if (ret) {
of_node_put(of_chan);
of_node_put(of_channels);
return -EINVAL;
}
}
of_node_put(of_channels);

return 0;
}

static int axi_dmac_detect_caps(struct axi_dmac *dmac)
static int axi_dmac_read_chan_config(struct device *dev, struct axi_dmac *dmac)
{
struct axi_dmac_chan *chan = &dmac->chan;
unsigned int version;
unsigned int val, desc;

version = axi_dmac_read(dmac, ADI_AXI_REG_VERSION);
desc = axi_dmac_read(dmac, AXI_DMAC_REG_INTERFACE_DESC);
if (desc == 0) {
dev_err(dev, "DMA interface register reads zero\n");
return -EFAULT;
}

val = AXI_DMAC_DMA_SRC_TYPE_GET(desc);
if (val > AXI_DMAC_BUS_TYPE_FIFO) {
dev_err(dev, "Invalid source bus type read: %d\n", val);
return -EINVAL;
}
chan->src_type = val;

val = AXI_DMAC_DMA_DST_TYPE_GET(desc);
if (val > AXI_DMAC_BUS_TYPE_FIFO) {
dev_err(dev, "Invalid destination bus type read: %d\n", val);
return -EINVAL;
}
chan->dest_type = val;

val = AXI_DMAC_DMA_SRC_WIDTH_GET(desc);
if (val == 0) {
dev_err(dev, "Source bus width is zero\n");
return -EINVAL;
}
/* widths are stored in log2 */
chan->src_width = 1 << val;

val = AXI_DMAC_DMA_DST_WIDTH_GET(desc);
if (val == 0) {
dev_err(dev, "Destination bus width is zero\n");
return -EINVAL;
}
chan->dest_width = 1 << val;

axi_dmac_adjust_chan_params(chan);

return 0;
}

static int axi_dmac_detect_caps(struct axi_dmac *dmac, unsigned int version)
{
struct axi_dmac_chan *chan = &dmac->chan;

axi_dmac_write(dmac, AXI_DMAC_REG_FLAGS, AXI_DMAC_FLAG_CYCLIC);
if (axi_dmac_read(dmac, AXI_DMAC_REG_FLAGS) == AXI_DMAC_FLAG_CYCLIC)
Expand Down Expand Up @@ -826,11 +904,11 @@ static int axi_dmac_detect_caps(struct axi_dmac *dmac)

static int axi_dmac_probe(struct platform_device *pdev)
{
struct device_node *of_channels, *of_chan;
struct dma_device *dma_dev;
struct axi_dmac *dmac;
struct resource *res;
struct regmap *regmap;
unsigned int version;
int ret;

dmac = devm_kzalloc(&pdev->dev, sizeof(*dmac), GFP_KERNEL);
Expand All @@ -852,23 +930,22 @@ static int axi_dmac_probe(struct platform_device *pdev)
if (IS_ERR(dmac->clk))
return PTR_ERR(dmac->clk);

INIT_LIST_HEAD(&dmac->chan.active_descs);
ret = clk_prepare_enable(dmac->clk);
if (ret < 0)
return ret;

of_channels = of_get_child_by_name(pdev->dev.of_node, "adi,channels");
if (of_channels == NULL)
return -ENODEV;
version = axi_dmac_read(dmac, ADI_AXI_REG_VERSION);

for_each_child_of_node(of_channels, of_chan) {
ret = axi_dmac_parse_chan_dt(of_chan, &dmac->chan);
if (ret) {
of_node_put(of_chan);
of_node_put(of_channels);
return -EINVAL;
}
}
of_node_put(of_channels);
if (version >= ADI_AXI_PCORE_VER(4, 3, 'a'))
ret = axi_dmac_read_chan_config(&pdev->dev, dmac);
else
ret = axi_dmac_parse_dt(&pdev->dev, dmac);

if (ret < 0)
goto err_clk_disable;

INIT_LIST_HEAD(&dmac->chan.active_descs);

pdev->dev.dma_parms = &dmac->dma_parms;
dma_set_max_seg_size(&pdev->dev, UINT_MAX);

dma_dev = &dmac->dma_dev;
Expand All @@ -894,11 +971,7 @@ static int axi_dmac_probe(struct platform_device *pdev)
dmac->chan.vchan.desc_free = axi_dmac_desc_free;
vchan_init(&dmac->chan.vchan, dma_dev);

ret = clk_prepare_enable(dmac->clk);
if (ret < 0)
return ret;

ret = axi_dmac_detect_caps(dmac);
ret = axi_dmac_detect_caps(dmac, version);
if (ret)
goto err_clk_disable;

Expand Down
Loading

0 comments on commit f065199

Please sign in to comment.