History

Support HDMI audio on NVIDIA Tegra20

Merge series from Dmitry Osipenko <digetx@gmail.com>: This series revives Tegra20 S/PDIF driver which was upstreamed long time ago, but never was used. It also turns Tegra DRM HDMI driver into HDMI audio CODEC provider. Finally, HDMI audio is enabled in device-trees. For now the audio is enable only for Acer A500 tablet and Toshiba AC100 netbook because they're already supported by upstream, later on ASUS TF101 tablet will join them. I based S/PDIF patches on Arnd's Bergmann patch from a separate series [1] that removes obsolete slave_id. This eases merging of the patches by removing the merge conflict. This is a note for Mark Brown. I also based this series on top of power management series [2]. I.e. [2] should be applied first, otherwise "Add S/PDIF node to Tegra20 device-tree" patch should have merge conflict. This is a note for Thierry. [1] https://patchwork.ozlabs.org/project/linux-tegra/list/?series=273312 [2] https://patchwork.ozlabs.org/project/linux-tegra/list/?series=274534 Changelog: v4: - Added patches that update multi_v7_defconfig with the enabled S/PDIF and APB DMA drivers. v3: - Renamed S/PDIF device-tree clocks as was suggested by Rob Herring. - Added r-bs and acks that were given by Rob Herring to v2. v2: - Corrected I2S yaml problem that was reported by the DT bot for v1 by removing the non-existent required clock-names property. - Removed assigned-clocks property from S/PDIF yaml since this property is now inherited from the clocks property. - Reordered the "tegra20: spdif: Set FIFO trigger level" patch, making it the first sound/soc patch in the series, like it was suggested by Mark Brown in the comment to v1. Also reworded commit message of this patch to *not* make it looks like it should be backported to stable kernels. Arnd Bergmann (1): ASoC: tegra20-spdif: stop setting slave_id Dmitry Osipenko (21): ASoC: dt-bindings: Add binding for Tegra20 S/PDIF ASoC: dt-bindings: tegra20-i2s: Convert to schema ASoC: dt-bindings: tegra20-i2s: Document new nvidia,fixed-parent-rate property dt-bindings: host1x: Document optional HDMI sound-dai-cells ASoC: tegra20: spdif: Set FIFO trigger level ASoC: tegra20: spdif: Support device-tree ASoC: tegra20: spdif: Improve driver's code ASoC: tegra20: spdif: Use more resource-managed helpers ASoC: tegra20: spdif: Reset hardware ASoC: tegra20: spdif: Support system suspend ASoC: tegra20: spdif: Filter out unsupported rates ASoC: tegra20: i2s: Filter out unsupported rates drm/tegra: hdmi: Unwind tegra_hdmi_init() errors drm/tegra: hdmi: Register audio CODEC on Tegra20 ARM: tegra_defconfig: Enable S/PDIF driver ARM: config: multi v7: Enable NVIDIA Tegra20 S/PDIF driver ARM: config: multi v7: Enable NVIDIA Tegra20 APB DMA driver ARM: tegra: Add S/PDIF node to Tegra20 device-tree ARM: tegra: Add HDMI audio graph to Tegra20 device-tree ARM: tegra: acer-a500: Enable S/PDIF and HDMI audio ARM: tegra: paz00: Enable S/PDIF and HDMI audio .../display/tegra/nvidia,tegra20-host1x.txt | 1 + .../bindings/sound/nvidia,tegra20-i2s.txt | 30 --- .../bindings/sound/nvidia,tegra20-i2s.yaml | 77 +++++++ .../bindings/sound/nvidia,tegra20-spdif.yaml | 85 ++++++++ .../boot/dts/tegra20-acer-a500-picasso.dts | 8 + arch/arm/boot/dts/tegra20-paz00.dts | 8 + arch/arm/boot/dts/tegra20.dtsi | 40 +++- arch/arm/configs/multi_v7_defconfig | 2 + arch/arm/configs/tegra_defconfig | 1 + drivers/gpu/drm/tegra/Kconfig | 3 + drivers/gpu/drm/tegra/hdmi.c | 168 +++++++++++++-- sound/soc/tegra/tegra20_i2s.c | 49 +++++ sound/soc/tegra/tegra20_spdif.c | 197 ++++++++++++------ sound/soc/tegra/tegra20_spdif.h | 1 + sound/soc/tegra/tegra_pcm.c | 6 + sound/soc/tegra/tegra_pcm.h | 1 + 16 files changed, 574 insertions(+), 103 deletions(-) delete mode 100644 Documentation/devicetree/bindings/sound/nvidia,tegra20-i2s.txt create mode 100644 Documentation/devicetree/bindings/sound/nvidia,tegra20-i2s.yaml create mode 100644 Documentation/devicetree/bindings/sound/nvidia,tegra20-spdif.yaml -- 2.33.1

Mark Brown committed 4 years ago

Commit be1d03e2 parents a92c1cd bfa467125 files · +475 −150Browse files

Unified · Split

25 files
  1. Documentation/devicetree/bindings/sound/nvidia,tegra20-i2s.txt +0 −30
  2. Documentation/devicetree/bindings/sound/nvidia,tegra20-i2s.yaml +77 −0
  3. Documentation/devicetree/bindings/sound/nvidia,tegra20-spdif.yaml +85 −0
  4. drivers/dma/mmp_pdma.c +0 −6
  5. drivers/dma/pxa_dma.c +0 −7
  6. drivers/dma/qcom/qcom_adm.c +49 −7
  7. drivers/dma/sh/shdma-base.c +0 −8
  8. drivers/dma/sprd-dma.c +0 −3
  9. drivers/dma/tegra20-apb-dma.c +0 −6
  10. drivers/dma/xilinx/xilinx_dpdma.c +11 −6
  11. drivers/gpu/drm/xlnx/zynqmp_disp.c +7 −2
  12. drivers/mmc/host/bcm2835.c +0 −2
  13. drivers/mtd/nand/raw/qcom_nandc.c +12 −2
  14. drivers/spi/spi-pic32.c +0 −2
  15. drivers/tty/serial/msm_serial.c +13 −2
  16. include/linux/dma/qcom_adm.h +12 −0
  17. include/linux/dma/xilinx_dpdma.h +11 −0
  18. include/linux/dmaengine.h +0 −4
  19. include/sound/dmaengine_pcm.h +0 −2
  20. sound/core/pcm_dmaengine.c +2 −3
  21. sound/soc/tegra/tegra20_i2s.c +49 −0
  22. sound/soc/tegra/tegra20_spdif.c +139 −58
  23. sound/soc/tegra/tegra20_spdif.h +1 −0
  24. sound/soc/tegra/tegra_pcm.c +6 −0
  25. sound/soc/tegra/tegra_pcm.h +1 −0
Documentation/devicetree/bindings/sound/nvidia,tegra20-i2s.txt+0−30
@@ -1,30 +0,0 @@
1−NVIDIA Tegra 20 I2S controller
2−
3−Required properties:
4−- compatible : "nvidia,tegra20-i2s"
5−- reg : Should contain I2S registers location and length
6−- interrupts : Should contain I2S interrupt
7−- resets : Must contain an entry for each entry in reset-names.
8− See ../reset/reset.txt for details.
9−- reset-names : Must include the following entries:
10− - i2s
11−- dmas : Must contain an entry for each entry in clock-names.
12− See ../dma/dma.txt for details.
13−- dma-names : Must include the following entries:
14− - rx
15− - tx
16−- clocks : Must contain one entry, for the module clock.
17− See ../clocks/clock-bindings.txt for details.
18−
19−Example:
20−
21−i2s@70002800 {
22− compatible = "nvidia,tegra20-i2s";
23− reg = <0x70002800 0x200>;
24− interrupts = < 45 >;
25− clocks = <&tegra_car 11>;
26− resets = <&tegra_car 11>;
27− reset-names = "i2s";
28− dmas = <&apbdma 21>, <&apbdma 21>;
29− dma-names = "rx", "tx";
30−};
Documentation/devicetree/bindings/sound/nvidia,tegra20-i2s.yaml+77−0
@@ -0,0 +1,77 @@
1+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
2+%YAML 1.2
3+---
4+$id: http://devicetree.org/schemas/sound/nvidia,tegra20-i2s.yaml#
5+$schema: http://devicetree.org/meta-schemas/core.yaml#
6+
7+title: NVIDIA Tegra20 I2S Controller
8+
9+description: |
10+ The I2S Controller streams synchronous serial audio data between system
11+ memory and an external audio device. The controller supports the I2S Left
12+ Justified Mode, Right Justified Mode, and DSP mode formats.
13+
14+maintainers:
15+ - Thierry Reding <treding@nvidia.com>
16+ - Jon Hunter <jonathanh@nvidia.com>
17+
18+properties:
19+ compatible:
20+ const: nvidia,tegra20-i2s
21+
22+ reg:
23+ maxItems: 1
24+
25+ resets:
26+ maxItems: 1
27+
28+ reset-names:
29+ const: i2s
30+
31+ interrupts:
32+ maxItems: 1
33+
34+ clocks:
35+ minItems: 1
36+
37+ dmas:
38+ minItems: 2
39+
40+ dma-names:
41+ items:
42+ - const: rx
43+ - const: tx
44+
45+ nvidia,fixed-parent-rate:
46+ description: |
47+ Specifies whether board prefers parent clock to stay at a fixed rate.
48+ This allows multiple Tegra20 audio components work simultaneously by
49+ limiting number of supportable audio rates.
50+ type: boolean
51+
52+required:
53+ - compatible
54+ - reg
55+ - resets
56+ - reset-names
57+ - interrupts
58+ - clocks
59+ - dmas
60+ - dma-names
61+
62+additionalProperties: false
63+
64+examples:
65+ - |
66+ i2s@70002800 {
67+ compatible = "nvidia,tegra20-i2s";
68+ reg = <0x70002800 0x200>;
69+ interrupts = <45>;
70+ clocks = <&tegra_car 11>;
71+ resets = <&tegra_car 11>;
72+ reset-names = "i2s";
73+ dmas = <&apbdma 21>, <&apbdma 21>;
74+ dma-names = "rx", "tx";
75+ };
76+
77+...
Documentation/devicetree/bindings/sound/nvidia,tegra20-spdif.yaml+85−0
@@ -0,0 +1,85 @@
1+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
2+%YAML 1.2
3+---
4+$id: http://devicetree.org/schemas/sound/nvidia,tegra20-spdif.yaml#
5+$schema: http://devicetree.org/meta-schemas/core.yaml#
6+
7+title: NVIDIA Tegra20 S/PDIF Controller
8+
9+description: |
10+ The S/PDIF controller supports both input and output in serial audio
11+ digital interface format. The input controller can digitally recover
12+ a clock from the received stream. The S/PDIF controller is also used
13+ to generate the embedded audio for HDMI output channel.
14+
15+maintainers:
16+ - Thierry Reding <treding@nvidia.com>
17+ - Jon Hunter <jonathanh@nvidia.com>
18+
19+properties:
20+ compatible:
21+ const: nvidia,tegra20-spdif
22+
23+ reg:
24+ maxItems: 1
25+
26+ resets:
27+ maxItems: 1
28+
29+ interrupts:
30+ maxItems: 1
31+
32+ clocks:
33+ minItems: 2
34+
35+ clock-names:
36+ items:
37+ - const: out
38+ - const: in
39+
40+ dmas:
41+ minItems: 2
42+
43+ dma-names:
44+ items:
45+ - const: rx
46+ - const: tx
47+
48+ "#sound-dai-cells":
49+ const: 0
50+
51+ nvidia,fixed-parent-rate:
52+ description: |
53+ Specifies whether board prefers parent clock to stay at a fixed rate.
54+ This allows multiple Tegra20 audio components work simultaneously by
55+ limiting number of supportable audio rates.
56+ type: boolean
57+
58+required:
59+ - compatible
60+ - reg
61+ - resets
62+ - interrupts
63+ - clocks
64+ - clock-names
65+ - dmas
66+ - dma-names
67+ - "#sound-dai-cells"
68+
69+additionalProperties: false
70+
71+examples:
72+ - |
73+ spdif@70002400 {
74+ compatible = "nvidia,tegra20-spdif";
75+ reg = <0x70002400 0x200>;
76+ interrupts = <77>;
77+ clocks = <&clk 99>, <&clk 98>;
78+ clock-names = "out", "in";
79+ resets = <&rst 10>;
80+ dmas = <&apbdma 3>, <&apbdma 3>;
81+ dma-names = "rx", "tx";
82+ #sound-dai-cells = <0>;
83+ };
84+
85+...
drivers/dma/mmp_pdma.c+0−6
@@ -727,12 +727,6 @@ static int mmp_pdma_config_write(struct dma_chan *dchan, · 726 unmodified lines
727727
728728 chan->dir = direction;
729729 chan->dev_addr = addr;
730− /* FIXME: drivers should be ported over to use the filter
731− * function. Once that's done, the following two lines can
732− * be removed.
733− */
734− if (cfg->slave_id)
735− chan->drcmr = cfg->slave_id;
736730
737731 return 0;
738732 }
drivers/dma/pxa_dma.c+0−7
@@ -909,13 +909,6 @@ static void pxad_get_config(struct pxad_chan *chan, · 908 unmodified lines
909909 *dcmd |= PXA_DCMD_BURST16;
910910 else if (maxburst == 32)
911911 *dcmd |= PXA_DCMD_BURST32;
912−
913− /* FIXME: drivers should be ported over to use the filter
914− * function. Once that's done, the following two lines can
915− * be removed.
916− */
917− if (chan->cfg.slave_id)
918− chan->drcmr = chan->cfg.slave_id;
919912 }
920913
921914 static struct dma_async_tx_descriptor *
drivers/dma/qcom/qcom_adm.c+49−7
@@ -8,6 +8,7 @@ · 7 unmodified lines
88 #include <linux/device.h>
99 #include <linux/dmaengine.h>
1010 #include <linux/dma-mapping.h>
11+#include <linux/dma/qcom_adm.h>
1112 #include <linux/init.h>
1213 #include <linux/interrupt.h>
1314 #include <linux/io.h>
@@ -140,6 +141,8 @@ struct adm_chan { · 126 unmodified lines
140141
141142 struct adm_async_desc *curr_txd;
142143 struct dma_slave_config slave;
144+ u32 crci;
145+ u32 mux;
143146 struct list_head node;
144147
145148 int error;
@@ -379,8 +382,8 @@ static struct dma_async_tx_descriptor *adm_prep_slave_sg(struct dma_chan *chan, · 233 unmodified lines
379382 return ERR_PTR(-EINVAL);
380383 }
381384
382− crci = achan->slave.slave_id & 0xf;
383− if (!crci || achan->slave.slave_id > 0x1f) {
385+ crci = achan->crci & 0xf;
386+ if (!crci || achan->crci > 0x1f) {
384387 dev_err(adev->dev, "invalid crci value\n");
385388 return ERR_PTR(-EINVAL);
386389 }
@@ -403,9 +406,7 @@ static struct dma_async_tx_descriptor *adm_prep_slave_sg(struct dma_chan *chan, · 16 unmodified lines
403406 if (!async_desc)
404407 return ERR_PTR(-ENOMEM);
405408
406− if (crci)
407− async_desc->mux = achan->slave.slave_id & ADM_CRCI_MUX_SEL ?
408− ADM_CRCI_CTL_MUX_SEL : 0;
409+ async_desc->mux = achan->mux ? ADM_CRCI_CTL_MUX_SEL : 0;
409410 async_desc->crci = crci;
410411 async_desc->blk_size = blk_size;
411412 async_desc->dma_len = single_count * sizeof(struct adm_desc_hw_single) +
@@ -488,10 +489,13 @@ static int adm_terminate_all(struct dma_chan *chan) · 76 unmodified lines
488489 static int adm_slave_config(struct dma_chan *chan, struct dma_slave_config *cfg)
489490 {
490491 struct adm_chan *achan = to_adm_chan(chan);
492+ struct qcom_adm_peripheral_config *config = cfg->peripheral_config;
491493 unsigned long flag;
492494
493495 spin_lock_irqsave(&achan->vc.lock, flag);
494496 memcpy(&achan->slave, cfg, sizeof(struct dma_slave_config));
497+ if (cfg->peripheral_size == sizeof(config))
498+ achan->crci = config->crci;
495499 spin_unlock_irqrestore(&achan->vc.lock, flag);
496500
497501 return 0;
@@ -694,6 +698,45 @@ static void adm_channel_init(struct adm_device *adev, struct adm_chan *achan, · 196 unmodified lines
694698 achan->vc.desc_free = adm_dma_free_desc;
695699 }
696700
701+/**
702+ * adm_dma_xlate
703+ * @dma_spec: pointer to DMA specifier as found in the device tree
704+ * @ofdma: pointer to DMA controller data
705+ *
706+ * This can use either 1-cell or 2-cell formats, the first cell
707+ * identifies the slave device, while the optional second cell
708+ * contains the crci value.
709+ *
710+ * Returns pointer to appropriate dma channel on success or NULL on error.
711+ */
712+static struct dma_chan *adm_dma_xlate(struct of_phandle_args *dma_spec,
713+ struct of_dma *ofdma)
714+{
715+ struct dma_device *dev = ofdma->of_dma_data;
716+ struct dma_chan *chan, *candidate = NULL;
717+ struct adm_chan *achan;
718+
719+ if (!dev || dma_spec->args_count > 2)
720+ return NULL;
721+
722+ list_for_each_entry(chan, &dev->channels, device_node)
723+ if (chan->chan_id == dma_spec->args[0]) {
724+ candidate = chan;
725+ break;
726+ }
727+
728+ if (!candidate)
729+ return NULL;
730+
731+ achan = to_adm_chan(candidate);
732+ if (dma_spec->args_count == 2)
733+ achan->crci = dma_spec->args[1];
734+ else
735+ achan->crci = 0;
736+
737+ return dma_get_slave_channel(candidate);
738+}
739+
697740 static int adm_dma_probe(struct platform_device *pdev)
698741 {
699742 struct adm_device *adev;
@@ -838,8 +881,7 @@ static int adm_dma_probe(struct platform_device *pdev) · 138 unmodified lines
838881 goto err_disable_clks;
839882 }
840883
841− ret = of_dma_controller_register(pdev->dev.of_node,
842− of_dma_xlate_by_chan_id,
884+ ret = of_dma_controller_register(pdev->dev.of_node, adm_dma_xlate,
843885 &adev->common);
844886 if (ret)
845887 goto err_unregister_dma;
drivers/dma/sh/shdma-base.c+0−8
@@ -786,14 +786,6 @@ static int shdma_config(struct dma_chan *chan, · 785 unmodified lines
786786 if (!config)
787787 return -EINVAL;
788788
789− /*
790− * overriding the slave_id through dma_slave_config is deprecated,
791− * but possibly some out-of-tree drivers still do it.
792− */
793− if (WARN_ON_ONCE(config->slave_id &&
794− config->slave_id != schan->real_slave_id))
795− schan->real_slave_id = config->slave_id;
796−
797789 /*
798790 * We could lock this, but you shouldn't be configuring the
799791 * channel, while using it...
drivers/dma/sprd-dma.c+0−3
@@ -795,9 +795,6 @@ static int sprd_dma_fill_desc(struct dma_chan *chan, · 794 unmodified lines
795795 return dst_datawidth;
796796 }
797797
798− if (slave_cfg->slave_id)
799− schan->dev_id = slave_cfg->slave_id;
800−
801798 hw->cfg = SPRD_DMA_DONOT_WAIT_BDONE << SPRD_DMA_WAIT_BDONE_OFFSET;
802799
803800 /*
drivers/dma/tegra20-apb-dma.c+0−6
@@ -343,12 +343,6 @@ static int tegra_dma_slave_config(struct dma_chan *dc, · 342 unmodified lines
343343 }
344344
345345 memcpy(&tdc->dma_sconfig, sconfig, sizeof(*sconfig));
346− if (tdc->slave_id == TEGRA_APBDMA_SLAVE_ID_INVALID &&
347− sconfig->device_fc) {
348− if (sconfig->slave_id > TEGRA_APBDMA_CSR_REQ_SEL_MASK)
349− return -EINVAL;
350− tdc->slave_id = sconfig->slave_id;
351− }
352346 tdc->config_init = true;
353347
354348 return 0;
drivers/dma/xilinx/xilinx_dpdma.c+11−6
@@ -12,6 +12,7 @@ · 11 unmodified lines
1212 #include <linux/clk.h>
1313 #include <linux/debugfs.h>
1414 #include <linux/delay.h>
15+#include <linux/dma/xilinx_dpdma.h>
1516 #include <linux/dmaengine.h>
1617 #include <linux/dmapool.h>
1718 #include <linux/interrupt.h>
@@ -1273,6 +1274,7 @@ static int xilinx_dpdma_config(struct dma_chan *dchan, · 1255 unmodified lines
12731274 struct dma_slave_config *config)
12741275 {
12751276 struct xilinx_dpdma_chan *chan = to_xilinx_chan(dchan);
1277+ struct xilinx_dpdma_peripheral_config *pconfig;
12761278 unsigned long flags;
12771279
12781280 /*
@@ -1282,15 +1284,18 @@ static int xilinx_dpdma_config(struct dma_chan *dchan, · 3 unmodified lines
12821284 * fixed both on the DPDMA side and on the DP controller side.
12831285 */
12841286
1285− spin_lock_irqsave(&chan->lock, flags);
1286−
12871287 /*
1288− * Abuse the slave_id to indicate that the channel is part of a video
1289− * group.
1288+ * Use the peripheral_config to indicate that the channel is part
1289+ * of a video group. This requires matching use of the custom
1290+ * structure in each driver.
12901291 */
1291− if (chan->id <= ZYNQMP_DPDMA_VIDEO2)
1292− chan->video_group = config->slave_id != 0;
1292+ pconfig = config->peripheral_config;
1293+ if (WARN_ON(pconfig && config->peripheral_size != sizeof(*pconfig)))
1294+ return -EINVAL;
12931295
1296+ spin_lock_irqsave(&chan->lock, flags);
1297+ if (chan->id <= ZYNQMP_DPDMA_VIDEO2 && pconfig)
1298+ chan->video_group = pconfig->video_group;
12941299 spin_unlock_irqrestore(&chan->lock, flags);
12951300
12961301 return 0;
drivers/gpu/drm/xlnx/zynqmp_disp.c+7−2
@@ -24,6 +24,7 @@ · 23 unmodified lines
2424
2525 #include <linux/clk.h>
2626 #include <linux/delay.h>
27+#include <linux/dma/xilinx_dpdma.h>
2728 #include <linux/dma-mapping.h>
2829 #include <linux/dmaengine.h>
2930 #include <linux/module.h>
@@ -1058,14 +1059,18 @@ static void zynqmp_disp_layer_set_format(struct zynqmp_disp_layer *layer, · 1028 unmodified lines
10581059 zynqmp_disp_avbuf_set_format(layer->disp, layer, layer->disp_fmt);
10591060
10601061 /*
1061− * Set slave_id for each DMA channel to indicate they're part of a
1062+ * Set pconfig for each DMA channel to indicate they're part of a
10621063 * video group.
10631064 */
10641065 for (i = 0; i < info->num_planes; i++) {
10651066 struct zynqmp_disp_layer_dma *dma = &layer->dmas[i];
1067+ struct xilinx_dpdma_peripheral_config pconfig = {
1068+ .video_group = true,
1069+ };
10661070 struct dma_slave_config config = {
10671071 .direction = DMA_MEM_TO_DEV,
1068− .slave_id = 1,
1072+ .peripheral_config = &pconfig,
1073+ .peripheral_size = sizeof(pconfig),
10691074 };
10701075
10711076 dmaengine_slave_config(dma->chan, &config);
drivers/mmc/host/bcm2835.c+0−2
@@ -1293,14 +1293,12 @@ static int bcm2835_add_host(struct bcm2835_host *host) · 1292 unmodified lines
12931293
12941294 host->dma_cfg_tx.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
12951295 host->dma_cfg_tx.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
1296− host->dma_cfg_tx.slave_id = 13; /* DREQ channel */
12971296 host->dma_cfg_tx.direction = DMA_MEM_TO_DEV;
12981297 host->dma_cfg_tx.src_addr = 0;
12991298 host->dma_cfg_tx.dst_addr = host->phys_addr + SDDATA;
13001299
13011300 host->dma_cfg_rx.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
13021301 host->dma_cfg_rx.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
1303− host->dma_cfg_rx.slave_id = 13; /* DREQ channel */
13041302 host->dma_cfg_rx.direction = DMA_DEV_TO_MEM;
13051303 host->dma_cfg_rx.src_addr = host->phys_addr + SDDATA;
13061304 host->dma_cfg_rx.dst_addr = 0;
drivers/mtd/nand/raw/qcom_nandc.c+12−2
@@ -6,6 +6,7 @@ · 5 unmodified lines
66 #include <linux/clk.h>
77 #include <linux/slab.h>
88 #include <linux/bitops.h>
9+#include <linux/dma/qcom_adm.h>
910 #include <linux/dma-mapping.h>
1011 #include <linux/dmaengine.h>
1112 #include <linux/module.h>
@@ -952,6 +953,7 @@ static int prep_adm_dma_desc(struct qcom_nand_controller *nandc, bool read, · 940 unmodified lines
952953 struct dma_async_tx_descriptor *dma_desc;
953954 struct scatterlist *sgl;
954955 struct dma_slave_config slave_conf;
956+ struct qcom_adm_peripheral_config periph_conf = {};
955957 enum dma_transfer_direction dir_eng;
956958 int ret;
957959
@@ -983,11 +985,19 @@ static int prep_adm_dma_desc(struct qcom_nand_controller *nandc, bool read, · 25 unmodified lines
983985 if (read) {
984986 slave_conf.src_maxburst = 16;
985987 slave_conf.src_addr = nandc->base_dma + reg_off;
986− slave_conf.slave_id = nandc->data_crci;
988+ if (nandc->data_crci) {
989+ periph_conf.crci = nandc->data_crci;
990+ slave_conf.peripheral_config = &periph_conf;
991+ slave_conf.peripheral_size = sizeof(periph_conf);
992+ }
987993 } else {
988994 slave_conf.dst_maxburst = 16;
989995 slave_conf.dst_addr = nandc->base_dma + reg_off;
990− slave_conf.slave_id = nandc->cmd_crci;
996+ if (nandc->cmd_crci) {
997+ periph_conf.crci = nandc->cmd_crci;
998+ slave_conf.peripheral_config = &periph_conf;
999+ slave_conf.peripheral_size = sizeof(periph_conf);
1000+ }
9911001 }
9921002
9931003 ret = dmaengine_slave_config(nandc->chan, &slave_conf);
drivers/spi/spi-pic32.c+0−2
@@ -370,7 +370,6 @@ static int pic32_spi_dma_config(struct pic32_spi *pic32s, u32 dma_width) · 369 unmodified lines
370370 cfg.src_addr_width = dma_width;
371371 cfg.dst_addr_width = dma_width;
372372 /* tx channel */
373− cfg.slave_id = pic32s->tx_irq;
374373 cfg.direction = DMA_MEM_TO_DEV;
375374 ret = dmaengine_slave_config(master->dma_tx, &cfg);
376375 if (ret) {
@@ -378,7 +377,6 @@ static int pic32_spi_dma_config(struct pic32_spi *pic32s, u32 dma_width) · 1 unmodified line
378377 return ret;
379378 }
380379 /* rx channel */
381− cfg.slave_id = pic32s->rx_irq;
382380 cfg.direction = DMA_DEV_TO_MEM;
383381 ret = dmaengine_slave_config(master->dma_rx, &cfg);
384382 if (ret)
drivers/tty/serial/msm_serial.c+13−2
@@ -9,6 +9,7 @@ · 8 unmodified lines
99
1010 #include <linux/kernel.h>
1111 #include <linux/atomic.h>
12+#include <linux/dma/qcom_adm.h>
1213 #include <linux/dma-mapping.h>
1314 #include <linux/dmaengine.h>
1415 #include <linux/module.h>
@@ -290,6 +291,7 @@ static void msm_request_tx_dma(struct msm_port *msm_port, resource_size_t base) · 275 unmodified lines
290291 {
291292 struct device *dev = msm_port->uart.dev;
292293 struct dma_slave_config conf;
294+ struct qcom_adm_peripheral_config periph_conf = {};
293295 struct msm_dma *dma;
294296 u32 crci = 0;
295297 int ret;
@@ -308,7 +310,11 @@ static void msm_request_tx_dma(struct msm_port *msm_port, resource_size_t base) · 12 unmodified lines
308310 conf.device_fc = true;
309311 conf.dst_addr = base + UARTDM_TF;
310312 conf.dst_maxburst = UARTDM_BURST_SIZE;
311− conf.slave_id = crci;
313+ if (crci) {
314+ conf.peripheral_config = &periph_conf;
315+ conf.peripheral_size = sizeof(periph_conf);
316+ periph_conf.crci = crci;
317+ }
312318
313319 ret = dmaengine_slave_config(dma->chan, &conf);
314320 if (ret)
@@ -333,6 +339,7 @@ static void msm_request_rx_dma(struct msm_port *msm_port, resource_size_t base) · 18 unmodified lines
333339 {
334340 struct device *dev = msm_port->uart.dev;
335341 struct dma_slave_config conf;
342+ struct qcom_adm_peripheral_config periph_conf = {};
336343 struct msm_dma *dma;
337344 u32 crci = 0;
338345 int ret;
@@ -355,7 +362,11 @@ static void msm_request_rx_dma(struct msm_port *msm_port, resource_size_t base) · 16 unmodified lines
355362 conf.device_fc = true;
356363 conf.src_addr = base + UARTDM_RF;
357364 conf.src_maxburst = UARTDM_BURST_SIZE;
358− conf.slave_id = crci;
365+ if (crci) {
366+ conf.peripheral_config = &periph_conf;
367+ conf.peripheral_size = sizeof(periph_conf);
368+ periph_conf.crci = crci;
369+ }
359370
360371 ret = dmaengine_slave_config(dma->chan, &conf);
361372 if (ret)
include/linux/dma/qcom_adm.h+12−0
@@ -0,0 +1,12 @@
1+// SPDX-License-Identifier: GPL-2.0-only
2+#ifndef __LINUX_DMA_QCOM_ADM_H
3+#define __LINUX_DMA_QCOM_ADM_H
4+
5+#include <linux/types.h>
6+
7+struct qcom_adm_peripheral_config {
8+ u32 crci;
9+ u32 mux;
10+};
11+
12+#endif /* __LINUX_DMA_QCOM_ADM_H */
include/linux/dma/xilinx_dpdma.h+11−0
@@ -0,0 +1,11 @@
1+// SPDX-License-Identifier: GPL-2.0
2+#ifndef __LINUX_DMA_XILINX_DPDMA_H
3+#define __LINUX_DMA_XILINX_DPDMA_H
4+
5+#include <linux/types.h>
6+
7+struct xilinx_dpdma_peripheral_config {
8+ bool video_group;
9+};
10+
11+#endif /* __LINUX_DMA_XILINX_DPDMA_H */
include/linux/dmaengine.h+0−4
@@ -418,9 +418,6 @@ enum dma_slave_buswidth { · 417 unmodified lines
418418 * @device_fc: Flow Controller Settings. Only valid for slave channels. Fill
419419 * with 'true' if peripheral should be flow controller. Direction will be
420420 * selected at Runtime.
421− * @slave_id: Slave requester id. Only valid for slave channels. The dma
422− * slave peripheral will have unique id as dma requester which need to be
423− * pass as slave config.
424421 * @peripheral_config: peripheral configuration for programming peripheral
425422 * for dmaengine transfer
426423 * @peripheral_size: peripheral configuration buffer size
@@ -448,7 +445,6 @@ struct dma_slave_config { · 21 unmodified lines
448445 u32 src_port_window_size;
449446 u32 dst_port_window_size;
450447 bool device_fc;
451− unsigned int slave_id;
452448 void *peripheral_config;
453449 size_t peripheral_size;
454450 };
include/sound/dmaengine_pcm.h+0−2
@@ -60,7 +60,6 @@ struct dma_chan *snd_dmaengine_pcm_get_chan(struct snd_pcm_substream *substream) · 59 unmodified lines
6060 * @maxburst: Maximum number of words(note: words, as in units of the
6161 * src_addr_width member, not bytes) that can be send to or received from the
6262 * DAI in one burst.
63− * @slave_id: Slave requester id for the DMA channel.
6463 * @filter_data: Custom DMA channel filter data, this will usually be used when
6564 * requesting the DMA channel.
6665 * @chan_name: Custom channel name to use when requesting DMA channel.
@@ -74,7 +73,6 @@ struct snd_dmaengine_dai_dma_data { · 7 unmodified lines
7473 dma_addr_t addr;
7574 enum dma_slave_buswidth addr_width;
7675 u32 maxburst;
77− unsigned int slave_id;
7876 void *filter_data;
7977 const char *chan_name;
8078 unsigned int fifo_size;
sound/core/pcm_dmaengine.c+2−3
@@ -91,8 +91,8 @@ EXPORT_SYMBOL_GPL(snd_hwparams_to_dma_slave_config); · 90 unmodified lines
9191 * @dma_data: DAI DMA data
9292 * @slave_config: DMA slave configuration
9393 *
94− * Initializes the {dst,src}_addr, {dst,src}_maxburst, {dst,src}_addr_width and
95− * slave_id fields of the DMA slave config from the same fields of the DAI DMA
94+ * Initializes the {dst,src}_addr, {dst,src}_maxburst, {dst,src}_addr_width
95+ * fields of the DMA slave config from the same fields of the DAI DMA
9696 * data struct. The src and dst fields will be initialized depending on the
9797 * direction of the substream. If the substream is a playback stream the dst
9898 * fields will be initialized, if it is a capture stream the src fields will be
@@ -124,7 +124,6 @@ void snd_dmaengine_pcm_set_config_from_dai_data( · 25 unmodified lines
124124 slave_config->src_addr_width = dma_data->addr_width;
125125 }
126126
127− slave_config->slave_id = dma_data->slave_id;
128127 slave_config->peripheral_config = dma_data->peripheral_config;
129128 slave_config->peripheral_size = dma_data->peripheral_size;
130129 }
sound/soc/tegra/tegra20_i2s.c+49−0
@@ -262,10 +262,59 @@ static int tegra20_i2s_probe(struct snd_soc_dai *dai) · 261 unmodified lines
262262 return 0;
263263 }
264264
265+static const unsigned int tegra20_i2s_rates[] = {
266+ 8000, 11025, 16000, 22050, 32000, 44100, 48000, 64000, 88200, 96000
267+};
268+
269+static int tegra20_i2s_filter_rates(struct snd_pcm_hw_params *params,
270+ struct snd_pcm_hw_rule *rule)
271+{
272+ struct snd_interval *r = hw_param_interval(params, rule->var);
273+ struct snd_soc_dai *dai = rule->private;
274+ struct tegra20_i2s *i2s = dev_get_drvdata(dai->dev);
275+ struct clk *parent = clk_get_parent(i2s->clk_i2s);
276+ long i, parent_rate, valid_rates = 0;
277+
278+ parent_rate = clk_get_rate(parent);
279+ if (parent_rate <= 0) {
280+ dev_err(dai->dev, "Can't get parent clock rate: %ld\n",
281+ parent_rate);
282+ return parent_rate ?: -EINVAL;
283+ }
284+
285+ for (i = 0; i < ARRAY_SIZE(tegra20_i2s_rates); i++) {
286+ if (parent_rate % (tegra20_i2s_rates[i] * 128) == 0)
287+ valid_rates |= BIT(i);
288+ }
289+
290+ /*
291+ * At least one rate must be valid, otherwise the parent clock isn't
292+ * audio PLL. Nothing should be filtered in this case.
293+ */
294+ if (!valid_rates)
295+ valid_rates = BIT(ARRAY_SIZE(tegra20_i2s_rates)) - 1;
296+
297+ return snd_interval_list(r, ARRAY_SIZE(tegra20_i2s_rates),
298+ tegra20_i2s_rates, valid_rates);
299+}
300+
301+static int tegra20_i2s_startup(struct snd_pcm_substream *substream,
302+ struct snd_soc_dai *dai)
303+{
304+ if (!device_property_read_bool(dai->dev, "nvidia,fixed-parent-rate"))
305+ return 0;
306+
307+ return snd_pcm_hw_rule_add(substream->runtime, 0,
308+ SNDRV_PCM_HW_PARAM_RATE,
309+ tegra20_i2s_filter_rates, dai,
310+ SNDRV_PCM_HW_PARAM_RATE, -1);
311+}
312+
265313 static const struct snd_soc_dai_ops tegra20_i2s_dai_ops = {
266314 .set_fmt = tegra20_i2s_set_fmt,
267315 .hw_params = tegra20_i2s_hw_params,
268316 .trigger = tegra20_i2s_trigger,
317+ .startup = tegra20_i2s_startup,
269318 };
270319
271320 static const struct snd_soc_dai_driver tegra20_i2s_dai_template = {
sound/soc/tegra/tegra20_spdif.c+139−58
@@ -7,12 +7,15 @@ · 6 unmodified lines
77 */
88
99 #include <linux/clk.h>
10+#include <linux/delay.h>
1011 #include <linux/device.h>
1112 #include <linux/io.h>
1213 #include <linux/module.h>
14+#include <linux/of_device.h>
1315 #include <linux/platform_device.h>
1416 #include <linux/pm_runtime.h>
1517 #include <linux/regmap.h>
18+#include <linux/reset.h>
1619 #include <linux/slab.h>
1720 #include <sound/core.h>
1821 #include <sound/pcm.h>
@@ -22,12 +25,12 @@ · 3 unmodified lines
2225
2326 #include "tegra20_spdif.h"
2427
25−#define DRV_NAME "tegra20-spdif"
26−
2728 static __maybe_unused int tegra20_spdif_runtime_suspend(struct device *dev)
2829 {
2930 struct tegra20_spdif *spdif = dev_get_drvdata(dev);
3031
32+ regcache_cache_only(spdif->regmap, true);
33+
3134 clk_disable_unprepare(spdif->clk_spdif_out);
3235
3336 return 0;
@@ -38,23 +41,45 @@ static __maybe_unused int tegra20_spdif_runtime_resume(struct device *dev) · 4 unmodified lines
3841 struct tegra20_spdif *spdif = dev_get_drvdata(dev);
3942 int ret;
4043
44+ ret = reset_control_assert(spdif->reset);
45+ if (ret)
46+ return ret;
47+
4148 ret = clk_prepare_enable(spdif->clk_spdif_out);
4249 if (ret) {
4350 dev_err(dev, "clk_enable failed: %d\n", ret);
4451 return ret;
4552 }
4653
54+ usleep_range(10, 100);
55+
56+ ret = reset_control_deassert(spdif->reset);
57+ if (ret)
58+ goto disable_clocks;
59+
60+ regcache_cache_only(spdif->regmap, false);
61+ regcache_mark_dirty(spdif->regmap);
62+
63+ ret = regcache_sync(spdif->regmap);
64+ if (ret)
65+ goto disable_clocks;
66+
4767 return 0;
68+
69+disable_clocks:
70+ clk_disable_unprepare(spdif->clk_spdif_out);
71+
72+ return ret;
4873 }
4974
5075 static int tegra20_spdif_hw_params(struct snd_pcm_substream *substream,
51− struct snd_pcm_hw_params *params,
52− struct snd_soc_dai *dai)
76+ struct snd_pcm_hw_params *params,
77+ struct snd_soc_dai *dai)
5378 {
54− struct device *dev = dai->dev;
55− struct tegra20_spdif *spdif = snd_soc_dai_get_drvdata(dai);
79+ struct tegra20_spdif *spdif = dev_get_drvdata(dai->dev);
5680 unsigned int mask = 0, val = 0;
5781 int ret, spdifclock;
82+ long rate;
5883
5984 mask |= TEGRA20_SPDIF_CTRL_PACK |
6085 TEGRA20_SPDIF_CTRL_BIT_MODE_MASK;
@@ -69,6 +94,14 @@ static int tegra20_spdif_hw_params(struct snd_pcm_substream *substream, · 8 unmodified lines
6994
7095 regmap_update_bits(spdif->regmap, TEGRA20_SPDIF_CTRL, mask, val);
7196
97+ /*
98+ * FIFO trigger level must be bigger than DMA burst or equal to it,
99+ * otherwise data is discarded on overflow.
100+ */
101+ regmap_update_bits(spdif->regmap, TEGRA20_SPDIF_DATA_FIFO_CSR,
102+ TEGRA20_SPDIF_DATA_FIFO_CSR_TX_ATN_LVL_MASK,
103+ TEGRA20_SPDIF_DATA_FIFO_CSR_TX_ATN_LVL_TU4_WORD_FULL);
104+
72105 switch (params_rate(params)) {
73106 case 32000:
74107 spdifclock = 4096000;
@@ -97,10 +130,16 @@ static int tegra20_spdif_hw_params(struct snd_pcm_substream *substream, · 22 unmodified lines
97130
98131 ret = clk_set_rate(spdif->clk_spdif_out, spdifclock);
99132 if (ret) {
100− dev_err(dev, "Can't set SPDIF clock rate: %d\n", ret);
133+ dev_err(dai->dev, "Can't set SPDIF clock rate: %d\n", ret);
101134 return ret;
102135 }
103136
137+ rate = clk_get_rate(spdif->clk_spdif_out);
138+ if (rate != spdifclock)
139+ dev_warn_once(dai->dev,
140+ "SPDIF clock rate %d doesn't match requested rate %lu\n",
141+ spdifclock, rate);
142+
104143 return 0;
105144 }
106145
@@ -118,9 +157,9 @@ static void tegra20_spdif_stop_playback(struct tegra20_spdif *spdif) · 11 unmodified lines
118157 }
119158
120159 static int tegra20_spdif_trigger(struct snd_pcm_substream *substream, int cmd,
121− struct snd_soc_dai *dai)
160+ struct snd_soc_dai *dai)
122161 {
123− struct tegra20_spdif *spdif = snd_soc_dai_get_drvdata(dai);
162+ struct tegra20_spdif *spdif = dev_get_drvdata(dai->dev);
124163
125164 switch (cmd) {
126165 case SNDRV_PCM_TRIGGER_START:
@@ -140,9 +179,62 @@ static int tegra20_spdif_trigger(struct snd_pcm_substream *substream, int cmd, · 13 unmodified lines
140179 return 0;
141180 }
142181
182+static int tegra20_spdif_filter_rates(struct snd_pcm_hw_params *params,
183+ struct snd_pcm_hw_rule *rule)
184+{
185+ struct snd_interval *r = hw_param_interval(params, rule->var);
186+ struct snd_soc_dai *dai = rule->private;
187+ struct tegra20_spdif *spdif = dev_get_drvdata(dai->dev);
188+ struct clk *parent = clk_get_parent(spdif->clk_spdif_out);
189+ const unsigned int rates[] = { 32000, 44100, 48000 };
190+ long i, parent_rate, valid_rates = 0;
191+
192+ parent_rate = clk_get_rate(parent);
193+ if (parent_rate <= 0) {
194+ dev_err(dai->dev, "Can't get parent clock rate: %ld\n",
195+ parent_rate);
196+ return parent_rate ?: -EINVAL;
197+ }
198+
199+ for (i = 0; i < ARRAY_SIZE(rates); i++) {
200+ if (parent_rate % (rates[i] * 128) == 0)
201+ valid_rates |= BIT(i);
202+ }
203+
204+ /*
205+ * At least one rate must be valid, otherwise the parent clock isn't
206+ * audio PLL. Nothing should be filtered in this case.
207+ */
208+ if (!valid_rates)
209+ valid_rates = BIT(ARRAY_SIZE(rates)) - 1;
210+
211+ return snd_interval_list(r, ARRAY_SIZE(rates), rates, valid_rates);
212+}
213+
214+static int tegra20_spdif_startup(struct snd_pcm_substream *substream,
215+ struct snd_soc_dai *dai)
216+{
217+ if (!device_property_read_bool(dai->dev, "nvidia,fixed-parent-rate"))
218+ return 0;
219+
220+ /*
221+ * SPDIF and I2S share audio PLL. HDMI takes audio packets from SPDIF
222+ * and audio may not work on some TVs if clock rate isn't precise.
223+ *
224+ * PLL rate is controlled by I2S side. Filter out audio rates that
225+ * don't match PLL rate at the start of stream to allow both SPDIF
226+ * and I2S work simultaneously, assuming that PLL rate won't be
227+ * changed later on.
228+ */
229+ return snd_pcm_hw_rule_add(substream->runtime, 0,
230+ SNDRV_PCM_HW_PARAM_RATE,
231+ tegra20_spdif_filter_rates, dai,
232+ SNDRV_PCM_HW_PARAM_RATE, -1);
233+}
234+
143235 static int tegra20_spdif_probe(struct snd_soc_dai *dai)
144236 {
145− struct tegra20_spdif *spdif = snd_soc_dai_get_drvdata(dai);
237+ struct tegra20_spdif *spdif = dev_get_drvdata(dai->dev);
146238
147239 dai->capture_dma_data = NULL;
148240 dai->playback_dma_data = &spdif->playback_dma_data;
@@ -151,26 +243,27 @@ static int tegra20_spdif_probe(struct snd_soc_dai *dai) · 2 unmodified lines
151243 }
152244
153245 static const struct snd_soc_dai_ops tegra20_spdif_dai_ops = {
154− .hw_params = tegra20_spdif_hw_params,
155− .trigger = tegra20_spdif_trigger,
246+ .hw_params = tegra20_spdif_hw_params,
247+ .trigger = tegra20_spdif_trigger,
248+ .startup = tegra20_spdif_startup,
156249 };
157250
158251 static struct snd_soc_dai_driver tegra20_spdif_dai = {
159− .name = DRV_NAME,
252+ .name = "tegra20-spdif",
160253 .probe = tegra20_spdif_probe,
161254 .playback = {
162255 .stream_name = "Playback",
163256 .channels_min = 2,
164257 .channels_max = 2,
165258 .rates = SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |
166− SNDRV_PCM_RATE_48000,
259+ SNDRV_PCM_RATE_48000,
167260 .formats = SNDRV_PCM_FMTBIT_S16_LE,
168261 },
169262 .ops = &tegra20_spdif_dai_ops,
170263 };
171264
172265 static const struct snd_soc_component_driver tegra20_spdif_component = {
173− .name = DRV_NAME,
266+ .name = "tegra20-spdif",
174267 };
175268
176269 static bool tegra20_spdif_wr_rd_reg(struct device *dev, unsigned int reg)
@@ -251,7 +344,7 @@ static const struct regmap_config tegra20_spdif_regmap_config = { · 74 unmodified lines
251344 static int tegra20_spdif_platform_probe(struct platform_device *pdev)
252345 {
253346 struct tegra20_spdif *spdif;
254− struct resource *mem, *dmareq;
347+ struct resource *mem;
255348 void __iomem *regs;
256349 int ret;
257350
@@ -262,89 +355,77 @@ static int tegra20_spdif_platform_probe(struct platform_device *pdev) · 4 unmodified lines
262355
263356 dev_set_drvdata(&pdev->dev, spdif);
264357
265− spdif->clk_spdif_out = devm_clk_get(&pdev->dev, "spdif_out");
358+ spdif->reset = devm_reset_control_get_exclusive(&pdev->dev, NULL);
359+ if (IS_ERR(spdif->reset)) {
360+ dev_err(&pdev->dev, "Can't retrieve spdif reset\n");
361+ return PTR_ERR(spdif->reset);
362+ }
363+
364+ spdif->clk_spdif_out = devm_clk_get(&pdev->dev, "out");
266365 if (IS_ERR(spdif->clk_spdif_out)) {
267− pr_err("Can't retrieve spdif clock\n");
268− ret = PTR_ERR(spdif->clk_spdif_out);
269− return ret;
366+ dev_err(&pdev->dev, "Could not retrieve spdif clock\n");
367+ return PTR_ERR(spdif->clk_spdif_out);
270368 }
271369
272370 regs = devm_platform_get_and_ioremap_resource(pdev, 0, &mem);
273371 if (IS_ERR(regs))
274372 return PTR_ERR(regs);
275373
276− dmareq = platform_get_resource(pdev, IORESOURCE_DMA, 0);
277− if (!dmareq) {
278− dev_err(&pdev->dev, "No DMA resource\n");
279− return -ENODEV;
280− }
281−
282374 spdif->regmap = devm_regmap_init_mmio(&pdev->dev, regs,
283− &tegra20_spdif_regmap_config);
375+ &tegra20_spdif_regmap_config);
284376 if (IS_ERR(spdif->regmap)) {
285377 dev_err(&pdev->dev, "regmap init failed\n");
286− ret = PTR_ERR(spdif->regmap);
287− return ret;
378+ return PTR_ERR(spdif->regmap);
288379 }
289380
290381 spdif->playback_dma_data.addr = mem->start + TEGRA20_SPDIF_DATA_OUT;
291382 spdif->playback_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
292383 spdif->playback_dma_data.maxburst = 4;
293− spdif->playback_dma_data.slave_id = dmareq->start;
294384
295− pm_runtime_enable(&pdev->dev);
385+ ret = devm_pm_runtime_enable(&pdev->dev);
386+ if (ret)
387+ return ret;
296388
297− ret = snd_soc_register_component(&pdev->dev, &tegra20_spdif_component,
298− &tegra20_spdif_dai, 1);
389+ ret = devm_snd_soc_register_component(&pdev->dev,
390+ &tegra20_spdif_component,
391+ &tegra20_spdif_dai, 1);
299392 if (ret) {
300393 dev_err(&pdev->dev, "Could not register DAI: %d\n", ret);
301− ret = -ENOMEM;
302− goto err_pm_disable;
394+ return ret;
303395 }
304396
305− ret = tegra_pcm_platform_register(&pdev->dev);
397+ ret = devm_tegra_pcm_platform_register(&pdev->dev);
306398 if (ret) {
307399 dev_err(&pdev->dev, "Could not register PCM: %d\n", ret);
308− goto err_unregister_component;
400+ return ret;
309401 }
310402
311− return 0;
312−
313−err_unregister_component:
314− snd_soc_unregister_component(&pdev->dev);
315−err_pm_disable:
316− pm_runtime_disable(&pdev->dev);
317−
318− return ret;
319−}
320−
321−static int tegra20_spdif_platform_remove(struct platform_device *pdev)
322−{
323− tegra_pcm_platform_unregister(&pdev->dev);
324− snd_soc_unregister_component(&pdev->dev);
325−
326− pm_runtime_disable(&pdev->dev);
327−
328403 return 0;
329404 }
330405
331406 static const struct dev_pm_ops tegra20_spdif_pm_ops = {
332407 SET_RUNTIME_PM_OPS(tegra20_spdif_runtime_suspend,
333408 tegra20_spdif_runtime_resume, NULL)
409+ SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
410+ pm_runtime_force_resume)
334411 };
335412
413+static const struct of_device_id tegra20_spdif_of_match[] = {
414+ { .compatible = "nvidia,tegra20-spdif", },
415+ {},
416+};
417+MODULE_DEVICE_TABLE(of, tegra20_spdif_of_match);
418+
336419 static struct platform_driver tegra20_spdif_driver = {
337420 .driver = {
338− .name = DRV_NAME,
421+ .name = "tegra20-spdif",
339422 .pm = &tegra20_spdif_pm_ops,
423+ .of_match_table = tegra20_spdif_of_match,
340424 },
341425 .probe = tegra20_spdif_platform_probe,
342− .remove = tegra20_spdif_platform_remove,
343426 };
344−
345427 module_platform_driver(tegra20_spdif_driver);
346428
347429 MODULE_AUTHOR("Stephen Warren <swarren@nvidia.com>");
348430 MODULE_DESCRIPTION("Tegra20 SPDIF ASoC driver");
349431 MODULE_LICENSE("GPL");
350−MODULE_ALIAS("platform:" DRV_NAME);
sound/soc/tegra/tegra20_spdif.h+1−0
@@ -451,6 +451,7 @@ struct tegra20_spdif { · 450 unmodified lines
451451 struct snd_dmaengine_dai_dma_data capture_dma_data;
452452 struct snd_dmaengine_dai_dma_data playback_dma_data;
453453 struct regmap *regmap;
454+ struct reset_control *reset;
454455 };
455456
456457 #endif
sound/soc/tegra/tegra_pcm.c+6−0
@@ -48,6 +48,12 @@ int tegra_pcm_platform_register(struct device *dev) · 47 unmodified lines
4848 }
4949 EXPORT_SYMBOL_GPL(tegra_pcm_platform_register);
5050
51+int devm_tegra_pcm_platform_register(struct device *dev)
52+{
53+ return devm_snd_dmaengine_pcm_register(dev, &tegra_dmaengine_pcm_config, 0);
54+}
55+EXPORT_SYMBOL_GPL(devm_tegra_pcm_platform_register);
56+
5157 int tegra_pcm_platform_register_with_chan_names(struct device *dev,
5258 struct snd_dmaengine_pcm_config *config,
5359 char *txdmachan, char *rxdmachan)
sound/soc/tegra/tegra_pcm.h+1−0
@@ -32,6 +32,7 @@ int tegra_pcm_hw_params(struct snd_soc_component *component, · 31 unmodified lines
3232 snd_pcm_uframes_t tegra_pcm_pointer(struct snd_soc_component *component,
3333 struct snd_pcm_substream *substream);
3434 int tegra_pcm_platform_register(struct device *dev);
35+int devm_tegra_pcm_platform_register(struct device *dev);
3536 int tegra_pcm_platform_register_with_chan_names(struct device *dev,
3637 struct snd_dmaengine_pcm_config *config,
3738 char *txdmachan, char *rxdmachan);

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t