1 | // SPDX-License-Identifier: GPL-2.0 |
2 | // Copyright (C) 2013,2019 Intel Corporation |
3 | |
4 | #include <linux/acpi.h> |
5 | #include <linux/acpi_dma.h> |
6 | |
7 | #include "internal.h" |
8 | |
9 | static bool dw_dma_acpi_filter(struct dma_chan *chan, void *param) |
10 | { |
11 | struct acpi_dma_spec *dma_spec = param; |
12 | struct dw_dma_slave slave = { |
13 | .dma_dev = dma_spec->dev, |
14 | .src_id = dma_spec->slave_id, |
15 | .dst_id = dma_spec->slave_id, |
16 | .m_master = 0, |
17 | .p_master = 1, |
18 | }; |
19 | |
20 | return dw_dma_filter(chan, param: &slave); |
21 | } |
22 | |
23 | void dw_dma_acpi_controller_register(struct dw_dma *dw) |
24 | { |
25 | struct device *dev = dw->dma.dev; |
26 | struct acpi_dma_filter_info *info; |
27 | int ret; |
28 | |
29 | if (!has_acpi_companion(dev)) |
30 | return; |
31 | |
32 | info = devm_kzalloc(dev, size: sizeof(*info), GFP_KERNEL); |
33 | if (!info) |
34 | return; |
35 | |
36 | dma_cap_zero(info->dma_cap); |
37 | dma_cap_set(DMA_SLAVE, info->dma_cap); |
38 | info->filter_fn = dw_dma_acpi_filter; |
39 | |
40 | ret = acpi_dma_controller_register(dev, acpi_dma_xlate: acpi_dma_simple_xlate, data: info); |
41 | if (ret) |
42 | dev_err(dev, "could not register acpi_dma_controller\n" ); |
43 | } |
44 | EXPORT_SYMBOL_GPL(dw_dma_acpi_controller_register); |
45 | |
46 | void dw_dma_acpi_controller_free(struct dw_dma *dw) |
47 | { |
48 | struct device *dev = dw->dma.dev; |
49 | |
50 | if (!has_acpi_companion(dev)) |
51 | return; |
52 | |
53 | acpi_dma_controller_free(dev); |
54 | } |
55 | EXPORT_SYMBOL_GPL(dw_dma_acpi_controller_free); |
56 | |