Skip to content

Commit

Permalink
Merge tag 'dmaengine-4.16-rc1' of git://git.infradead.org/users/vkoul…
Browse files Browse the repository at this point in the history
…/slave-dma

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
  ...
  • Loading branch information
torvalds committed Jan 31, 2018
2 parents 2382dc9 + 330542f commit 2155e69
Show file tree
Hide file tree
Showing 34 changed files with 609 additions and 299 deletions.
4 changes: 2 additions & 2 deletions Documentation/devicetree/bindings/dma/qcom_hidma_mgmt.txt
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,8 @@ When the OS is not in control of the management interface (i.e. it's a guest),
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
Expand Down
38 changes: 17 additions & 21 deletions Documentation/driver-api/dmaengine/provider.rst
Original file line number Diff line number Diff line change
Expand Up @@ -111,40 +111,36 @@ The first thing you need to do in your driver is to allocate this
structure. Any of the usual memory allocators will do, but you'll also
need to initialize a few fields in there:

- channels: should be initialized as a list using the
- ``channels``: should be initialized as a list using the
INIT_LIST_HEAD macro for example

- src_addr_widths:
- ``src_addr_widths``:
should contain a bitmask of the supported source transfer width

- dst_addr_widths:
- ``dst_addr_widths``:
should contain a bitmask of the supported destination transfer width

- directions:
- ``directions``:
should contain a bitmask of the supported slave directions
(i.e. excluding mem2mem transfers)

- residue_granularity:
- ``residue_granularity``:
granularity of the transfer residue reported to dma_set_residue.
This can be either:

- Granularity of the transfer residue reported to dma_set_residue.
This can be either:
- Descriptor:
your device doesn't support any kind of residue
reporting. The framework will only know that a particular
transaction descriptor is done.

- Descriptor
- Segment:
your device is able to report which chunks have been transferred

- Your device doesn't support any kind of residue
reporting. The framework will only know that a particular
transaction descriptor is done.
- Burst:
your device is able to report which burst have been transferred

- Segment

- Your device is able to report which chunks have been transferred

- Burst

- Your device is able to report which burst have been transferred

- dev: should hold the pointer to the ``struct device`` associated
to your current driver instance.
- ``dev``: should hold the pointer to the ``struct device`` associated
to your current driver instance.

Supported transaction types
---------------------------
Expand Down
18 changes: 18 additions & 0 deletions drivers/acpi/bus.c
Original file line number Diff line number Diff line change
Expand Up @@ -785,6 +785,24 @@ const struct acpi_device_id *acpi_match_device(const struct acpi_device_id *ids,
}
EXPORT_SYMBOL_GPL(acpi_match_device);

void *acpi_get_match_data(const struct device *dev)
{
const struct acpi_device_id *match;

if (!dev->driver)
return NULL;

if (!dev->driver->acpi_match_table)
return NULL;

match = acpi_match_device(dev->driver->acpi_match_table, dev);
if (!match)
return NULL;

return (void *)match->driver_data;
}
EXPORT_SYMBOL_GPL(acpi_get_match_data);

int acpi_match_device_ids(struct acpi_device *device,
const struct acpi_device_id *ids)
{
Expand Down
8 changes: 8 additions & 0 deletions drivers/acpi/property.c
Original file line number Diff line number Diff line change
Expand Up @@ -1271,9 +1271,17 @@ static int acpi_fwnode_graph_parse_endpoint(const struct fwnode_handle *fwnode,
return 0;
}

static void *
acpi_fwnode_device_get_match_data(const struct fwnode_handle *fwnode,
const struct device *dev)
{
return acpi_get_match_data(dev);
}

#define DECLARE_ACPI_FWNODE_OPS(ops) \
const struct fwnode_operations ops = { \
.device_is_available = acpi_fwnode_device_is_available, \
.device_get_match_data = acpi_fwnode_device_get_match_data, \
.property_present = acpi_fwnode_property_present, \
.property_read_int_array = \
acpi_fwnode_property_read_int_array, \
Expand Down
7 changes: 7 additions & 0 deletions drivers/base/property.c
Original file line number Diff line number Diff line change
Expand Up @@ -1340,3 +1340,10 @@ int fwnode_graph_parse_endpoint(const struct fwnode_handle *fwnode,
return fwnode_call_int_op(fwnode, graph_parse_endpoint, endpoint);
}
EXPORT_SYMBOL(fwnode_graph_parse_endpoint);

void *device_get_match_data(struct device *dev)
{
return fwnode_call_ptr_op(dev_fwnode(dev), device_get_match_data,
dev);
}
EXPORT_SYMBOL_GPL(device_get_match_data);
11 changes: 10 additions & 1 deletion drivers/dma/amba-pl08x.c
Original file line number Diff line number Diff line change
Expand Up @@ -2182,7 +2182,7 @@ static int pl08x_terminate_all(struct dma_chan *chan)
}
/* Dequeue jobs and free LLIs */
if (plchan->at) {
pl08x_desc_free(&plchan->at->vd);
vchan_terminate_vdesc(&plchan->at->vd);
plchan->at = NULL;
}
/* Dequeue jobs not yet fired as well */
Expand All @@ -2193,6 +2193,13 @@ static int pl08x_terminate_all(struct dma_chan *chan)
return 0;
}

static void pl08x_synchronize(struct dma_chan *chan)
{
struct pl08x_dma_chan *plchan = to_pl08x_chan(chan);

vchan_synchronize(&plchan->vc);
}

static int pl08x_pause(struct dma_chan *chan)
{
struct pl08x_dma_chan *plchan = to_pl08x_chan(chan);
Expand Down Expand Up @@ -2773,6 +2780,7 @@ static int pl08x_probe(struct amba_device *adev, const struct amba_id *id)
pl08x->memcpy.device_pause = pl08x_pause;
pl08x->memcpy.device_resume = pl08x_resume;
pl08x->memcpy.device_terminate_all = pl08x_terminate_all;
pl08x->memcpy.device_synchronize = pl08x_synchronize;
pl08x->memcpy.src_addr_widths = PL80X_DMA_BUSWIDTHS;
pl08x->memcpy.dst_addr_widths = PL80X_DMA_BUSWIDTHS;
pl08x->memcpy.directions = BIT(DMA_MEM_TO_MEM);
Expand Down Expand Up @@ -2802,6 +2810,7 @@ static int pl08x_probe(struct amba_device *adev, const struct amba_id *id)
pl08x->slave.device_pause = pl08x_pause;
pl08x->slave.device_resume = pl08x_resume;
pl08x->slave.device_terminate_all = pl08x_terminate_all;
pl08x->slave.device_synchronize = pl08x_synchronize;
pl08x->slave.src_addr_widths = PL80X_DMA_BUSWIDTHS;
pl08x->slave.dst_addr_widths = PL80X_DMA_BUSWIDTHS;
pl08x->slave.directions =
Expand Down
10 changes: 9 additions & 1 deletion drivers/dma/bcm2835-dma.c
Original file line number Diff line number Diff line change
Expand Up @@ -812,7 +812,7 @@ static int bcm2835_dma_terminate_all(struct dma_chan *chan)
* c->desc is NULL and exit.)
*/
if (c->desc) {
bcm2835_dma_desc_free(&c->desc->vd);
vchan_terminate_vdesc(&c->desc->vd);
c->desc = NULL;
bcm2835_dma_abort(c->chan_base);

Expand All @@ -836,6 +836,13 @@ static int bcm2835_dma_terminate_all(struct dma_chan *chan)
return 0;
}

static void bcm2835_dma_synchronize(struct dma_chan *chan)
{
struct bcm2835_chan *c = to_bcm2835_dma_chan(chan);

vchan_synchronize(&c->vc);
}

static int bcm2835_dma_chan_init(struct bcm2835_dmadev *d, int chan_id,
int irq, unsigned int irq_flags)
{
Expand Down Expand Up @@ -942,6 +949,7 @@ static int bcm2835_dma_probe(struct platform_device *pdev)
od->ddev.device_prep_dma_memcpy = bcm2835_dma_prep_dma_memcpy;
od->ddev.device_config = bcm2835_dma_slave_config;
od->ddev.device_terminate_all = bcm2835_dma_terminate_all;
od->ddev.device_synchronize = bcm2835_dma_synchronize;
od->ddev.src_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_4_BYTES);
od->ddev.dst_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_4_BYTES);
od->ddev.directions = BIT(DMA_DEV_TO_MEM) | BIT(DMA_MEM_TO_DEV) |
Expand Down
2 changes: 1 addition & 1 deletion drivers/dma/cppi41.c
Original file line number Diff line number Diff line change
Expand Up @@ -934,7 +934,7 @@ static bool cpp41_dma_filter_fn(struct dma_chan *chan, void *param)

BUILD_BUG_ON(ARRAY_SIZE(am335x_usb_queues_rx) !=
ARRAY_SIZE(am335x_usb_queues_tx));
if (WARN_ON(cchan->port_num > ARRAY_SIZE(am335x_usb_queues_rx)))
if (WARN_ON(cchan->port_num >= ARRAY_SIZE(am335x_usb_queues_rx)))
return false;

cchan->q_num = queues[cchan->port_num].submit;
Expand Down
10 changes: 9 additions & 1 deletion drivers/dma/dma-jz4780.c
Original file line number Diff line number Diff line change
Expand Up @@ -511,7 +511,7 @@ static int jz4780_dma_terminate_all(struct dma_chan *chan)
/* Clear the DMA status and stop the transfer. */
jz4780_dma_writel(jzdma, JZ_DMA_REG_DCS(jzchan->id), 0);
if (jzchan->desc) {
jz4780_dma_desc_free(&jzchan->desc->vdesc);
vchan_terminate_vdesc(&jzchan->desc->vdesc);
jzchan->desc = NULL;
}

Expand All @@ -523,6 +523,13 @@ static int jz4780_dma_terminate_all(struct dma_chan *chan)
return 0;
}

static void jz4780_dma_synchronize(struct dma_chan *chan)
{
struct jz4780_dma_chan *jzchan = to_jz4780_dma_chan(chan);

vchan_synchronize(&jzchan->vchan);
}

static int jz4780_dma_config(struct dma_chan *chan,
struct dma_slave_config *config)
{
Expand Down Expand Up @@ -813,6 +820,7 @@ static int jz4780_dma_probe(struct platform_device *pdev)
dd->device_prep_dma_memcpy = jz4780_dma_prep_dma_memcpy;
dd->device_config = jz4780_dma_config;
dd->device_terminate_all = jz4780_dma_terminate_all;
dd->device_synchronize = jz4780_dma_synchronize;
dd->device_tx_status = jz4780_dma_tx_status;
dd->device_issue_pending = jz4780_dma_issue_pending;
dd->src_addr_widths = JZ_DMA_BUSWIDTHS;
Expand Down
2 changes: 1 addition & 1 deletion drivers/dma/dmatest.c
Original file line number Diff line number Diff line change
Expand Up @@ -355,7 +355,7 @@ static void dmatest_callback(void *arg)
{
struct dmatest_done *done = arg;
struct dmatest_thread *thread =
container_of(arg, struct dmatest_thread, done_wait);
container_of(done, struct dmatest_thread, test_done);
if (!thread->done) {
done->done = true;
wake_up_all(done->wait);
Expand Down
7 changes: 2 additions & 5 deletions drivers/dma/edma.c
Original file line number Diff line number Diff line change
Expand Up @@ -860,11 +860,8 @@ static int edma_terminate_all(struct dma_chan *chan)
/* Move the cyclic channel back to default queue */
if (!echan->tc && echan->edesc->cyclic)
edma_assign_channel_eventq(echan, EVENTQ_DEFAULT);
/*
* free the running request descriptor
* since it is not in any of the vdesc lists
*/
edma_desc_free(&echan->edesc->vdesc);

vchan_terminate_vdesc(&echan->edesc->vdesc);
echan->edesc = NULL;
}

Expand Down
17 changes: 12 additions & 5 deletions drivers/dma/img-mdc-dma.c
Original file line number Diff line number Diff line change
Expand Up @@ -694,7 +694,6 @@ static unsigned int mdc_get_new_events(struct mdc_chan *mchan)
static int mdc_terminate_all(struct dma_chan *chan)
{
struct mdc_chan *mchan = to_mdc_chan(chan);
struct mdc_tx_desc *mdesc;
unsigned long flags;
LIST_HEAD(head);

Expand All @@ -703,21 +702,28 @@ static int mdc_terminate_all(struct dma_chan *chan)
mdc_chan_writel(mchan, MDC_CONTROL_AND_STATUS_CANCEL,
MDC_CONTROL_AND_STATUS);

mdesc = mchan->desc;
mchan->desc = NULL;
if (mchan->desc) {
vchan_terminate_vdesc(&mchan->desc->vd);
mchan->desc = NULL;
}
vchan_get_all_descriptors(&mchan->vc, &head);

mdc_get_new_events(mchan);

spin_unlock_irqrestore(&mchan->vc.lock, flags);

if (mdesc)
mdc_desc_free(&mdesc->vd);
vchan_dma_desc_free_list(&mchan->vc, &head);

return 0;
}

static void mdc_synchronize(struct dma_chan *chan)
{
struct mdc_chan *mchan = to_mdc_chan(chan);

vchan_synchronize(&mchan->vc);
}

static int mdc_slave_config(struct dma_chan *chan,
struct dma_slave_config *config)
{
Expand Down Expand Up @@ -952,6 +958,7 @@ static int mdc_dma_probe(struct platform_device *pdev)
mdma->dma_dev.device_tx_status = mdc_tx_status;
mdma->dma_dev.device_issue_pending = mdc_issue_pending;
mdma->dma_dev.device_terminate_all = mdc_terminate_all;
mdma->dma_dev.device_synchronize = mdc_synchronize;
mdma->dma_dev.device_config = mdc_slave_config;

mdma->dma_dev.directions = BIT(DMA_DEV_TO_MEM) | BIT(DMA_MEM_TO_DEV);
Expand Down
6 changes: 6 additions & 0 deletions drivers/dma/imx-sdma.c
Original file line number Diff line number Diff line change
Expand Up @@ -1939,4 +1939,10 @@ module_platform_driver(sdma_driver);

MODULE_AUTHOR("Sascha Hauer, Pengutronix <[email protected]>");
MODULE_DESCRIPTION("i.MX SDMA driver");
#if IS_ENABLED(CONFIG_SOC_IMX6Q)
MODULE_FIRMWARE("imx/sdma/sdma-imx6q.bin");
#endif
#if IS_ENABLED(CONFIG_SOC_IMX7D)
MODULE_FIRMWARE("imx/sdma/sdma-imx7d.bin");
#endif
MODULE_LICENSE("GPL");
10 changes: 9 additions & 1 deletion drivers/dma/k3dma.c
Original file line number Diff line number Diff line change
Expand Up @@ -719,7 +719,7 @@ static int k3_dma_terminate_all(struct dma_chan *chan)
c->phy = NULL;
p->vchan = NULL;
if (p->ds_run) {
k3_dma_free_desc(&p->ds_run->vd);
vchan_terminate_vdesc(&p->ds_run->vd);
p->ds_run = NULL;
}
p->ds_done = NULL;
Expand All @@ -730,6 +730,13 @@ static int k3_dma_terminate_all(struct dma_chan *chan)
return 0;
}

static void k3_dma_synchronize(struct dma_chan *chan)
{
struct k3_dma_chan *c = to_k3_chan(chan);

vchan_synchronize(&c->vc);
}

static int k3_dma_transfer_pause(struct dma_chan *chan)
{
struct k3_dma_chan *c = to_k3_chan(chan);
Expand Down Expand Up @@ -868,6 +875,7 @@ static int k3_dma_probe(struct platform_device *op)
d->slave.device_pause = k3_dma_transfer_pause;
d->slave.device_resume = k3_dma_transfer_resume;
d->slave.device_terminate_all = k3_dma_terminate_all;
d->slave.device_synchronize = k3_dma_synchronize;
d->slave.copy_align = DMAENGINE_ALIGN_8_BYTES;

/* init virtual channel */
Expand Down
4 changes: 1 addition & 3 deletions drivers/dma/mic_x100_dma.c
Original file line number Diff line number Diff line change
Expand Up @@ -480,9 +480,7 @@ static int mic_dma_setup_irq(struct mic_dma_chan *ch)
to_mbus_hw_ops(ch)->request_threaded_irq(to_mbus_device(ch),
mic_dma_intr_handler, mic_dma_thread_fn,
"mic dma_channel", ch, ch->ch_num);
if (IS_ERR(ch->cookie))
return PTR_ERR(ch->cookie);
return 0;
return PTR_ERR_OR_ZERO(ch->cookie);
}

static inline void mic_dma_free_irq(struct mic_dma_chan *ch)
Expand Down
2 changes: 1 addition & 1 deletion drivers/dma/omap-dma.c
Original file line number Diff line number Diff line change
Expand Up @@ -1311,7 +1311,7 @@ static int omap_dma_terminate_all(struct dma_chan *chan)
* c->desc is NULL and exit.)
*/
if (c->desc) {
omap_dma_desc_free(&c->desc->vd);
vchan_terminate_vdesc(&c->desc->vd);
c->desc = NULL;
/* Avoid stopping the dma twice */
if (!c->paused)
Expand Down
Loading

0 comments on commit 2155e69

Please sign in to comment.