diff options
author | Misael Lopez Cruz | 2016-05-05 18:30:44 -0500 |
---|---|---|
committer | Misael Lopez Cruz | 2016-05-27 16:56:02 -0500 |
commit | 1aad1b2243c3db7a1132777f875c39134e48cabe (patch) | |
tree | 8efa9bf14710a7933aa557bc4735b486151526c7 | |
parent | a4d3dd89638fc599f6d245db68d1a04567733146 (diff) | |
download | kernel-audio-1aad1b2243c3db7a1132777f875c39134e48cabe.tar.gz kernel-audio-1aad1b2243c3db7a1132777f875c39134e48cabe.tar.xz kernel-audio-1aad1b2243c3db7a1132777f875c39134e48cabe.zip |
ASoC: davinci-mcasp: Support shared CPU DAI
The McASP CPU DAI can be shared with other cores, typically the
DSP. The CPU DAI is configured from the DSP side but its power
management is kept on the ARM side.
A new optional devicetree property is added to indicate if the
CPU DAI is shared ("shared-dai"). It will prevent the device from
being power managed at runtime (clocks will be kept running).
Change-Id: Ib1b365e2d14ec0f9edf654d8c8ef50505cc6e947
Signed-off-by: Misael Lopez Cruz <misael.lopez@ti.com>
Signed-off-by: Stephen Molfetta <sjmolfetta@ti.com>
-rw-r--r-- | Documentation/devicetree/bindings/sound/davinci-mcasp-audio.txt | 2 | ||||
-rw-r--r-- | include/linux/platform_data/davinci_asp.h | 2 | ||||
-rw-r--r-- | sound/soc/davinci/davinci-mcasp.c | 93 |
3 files changed, 61 insertions, 36 deletions
diff --git a/Documentation/devicetree/bindings/sound/davinci-mcasp-audio.txt b/Documentation/devicetree/bindings/sound/davinci-mcasp-audio.txt index 46bc9829c71a..00107789a6dd 100644 --- a/Documentation/devicetree/bindings/sound/davinci-mcasp-audio.txt +++ b/Documentation/devicetree/bindings/sound/davinci-mcasp-audio.txt | |||
@@ -39,6 +39,8 @@ Optional properties: | |||
39 | please refer to pinctrl-bindings.txt | 39 | please refer to pinctrl-bindings.txt |
40 | - fck_parent : Should contain a valid clock name which will be used as parent | 40 | - fck_parent : Should contain a valid clock name which will be used as parent |
41 | for the McASP fck | 41 | for the McASP fck |
42 | - shared-dai : CPU DAI is shared (typically shared with DSP). McASP will not be | ||
43 | power managed at runtime. | ||
42 | 44 | ||
43 | Example: | 45 | Example: |
44 | 46 | ||
diff --git a/include/linux/platform_data/davinci_asp.h b/include/linux/platform_data/davinci_asp.h index 85ad68f9206a..4ed28436d187 100644 --- a/include/linux/platform_data/davinci_asp.h +++ b/include/linux/platform_data/davinci_asp.h | |||
@@ -86,6 +86,8 @@ struct davinci_mcasp_pdata { | |||
86 | u8 rxnumevt; | 86 | u8 rxnumevt; |
87 | int tx_dma_channel; | 87 | int tx_dma_channel; |
88 | int rx_dma_channel; | 88 | int rx_dma_channel; |
89 | |||
90 | bool shared_dai; | ||
89 | }; | 91 | }; |
90 | /* TODO: Fix arch/arm/mach-davinci/ users and remove this define */ | 92 | /* TODO: Fix arch/arm/mach-davinci/ users and remove this define */ |
91 | #define snd_platform_data davinci_mcasp_pdata | 93 | #define snd_platform_data davinci_mcasp_pdata |
diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c index 581d9010696a..fd284fec0eae 100644 --- a/sound/soc/davinci/davinci-mcasp.c +++ b/sound/soc/davinci/davinci-mcasp.c | |||
@@ -1705,6 +1705,11 @@ static struct davinci_mcasp_pdata *davinci_mcasp_set_pdata_from_of( | |||
1705 | if (ret >= 0) | 1705 | if (ret >= 0) |
1706 | pdata->sram_size_capture = val; | 1706 | pdata->sram_size_capture = val; |
1707 | 1707 | ||
1708 | if (of_find_property(np, "shared-dai", NULL)) | ||
1709 | pdata->shared_dai = 1; | ||
1710 | else | ||
1711 | pdata->shared_dai = 0; | ||
1712 | |||
1708 | return pdata; | 1713 | return pdata; |
1709 | 1714 | ||
1710 | nodata: | 1715 | nodata: |
@@ -1903,6 +1908,15 @@ static int davinci_mcasp_probe(struct platform_device *pdev) | |||
1903 | 1908 | ||
1904 | pm_runtime_enable(&pdev->dev); | 1909 | pm_runtime_enable(&pdev->dev); |
1905 | 1910 | ||
1911 | /* | ||
1912 | * Forbid runtime PM if the DAI is shared, data transfers will occur | ||
1913 | * from a different core (typically DSP). | ||
1914 | */ | ||
1915 | if (pdata->shared_dai) { | ||
1916 | dev_info(&pdev->dev, "DAI is shared\n"); | ||
1917 | pm_runtime_forbid(&pdev->dev); | ||
1918 | } | ||
1919 | |||
1906 | mcasp->op_mode = pdata->op_mode; | 1920 | mcasp->op_mode = pdata->op_mode; |
1907 | /* sanity check for tdm slots parameter */ | 1921 | /* sanity check for tdm slots parameter */ |
1908 | if (mcasp->op_mode == DAVINCI_MCASP_IIS_MODE) { | 1922 | if (mcasp->op_mode == DAVINCI_MCASP_IIS_MODE) { |
@@ -1932,51 +1946,58 @@ static int davinci_mcasp_probe(struct platform_device *pdev) | |||
1932 | 1946 | ||
1933 | mcasp->dev = &pdev->dev; | 1947 | mcasp->dev = &pdev->dev; |
1934 | 1948 | ||
1935 | irq = platform_get_irq_byname(pdev, "common"); | 1949 | /* |
1936 | if (irq >= 0) { | 1950 | * Do not register IRQ if DAI is shared, as the remote core will |
1937 | irq_name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "%s_common", | 1951 | * be responsible for servicing these interrupts. |
1938 | dev_name(&pdev->dev)); | 1952 | */ |
1939 | ret = devm_request_threaded_irq(&pdev->dev, irq, NULL, | 1953 | if (!pdata->shared_dai) { |
1940 | davinci_mcasp_common_irq_handler, | 1954 | irq = platform_get_irq_byname(pdev, "common"); |
1941 | IRQF_ONESHOT | IRQF_SHARED, | 1955 | if (irq >= 0) { |
1942 | irq_name, mcasp); | 1956 | irq_name = devm_kasprintf(&pdev->dev, GFP_KERNEL, |
1943 | if (ret) { | 1957 | "%s_common", dev_name(&pdev->dev)); |
1944 | dev_err(&pdev->dev, "common IRQ request failed\n"); | 1958 | ret = devm_request_threaded_irq(&pdev->dev, irq, NULL, |
1945 | goto err; | 1959 | davinci_mcasp_common_irq_handler, |
1946 | } | 1960 | IRQF_ONESHOT | IRQF_SHARED, |
1961 | irq_name, mcasp); | ||
1962 | if (ret) { | ||
1963 | dev_err(&pdev->dev, | ||
1964 | "common IRQ request failed\n"); | ||
1965 | goto err; | ||
1966 | } | ||
1947 | 1967 | ||
1948 | mcasp->irq_request[SNDRV_PCM_STREAM_PLAYBACK] = XUNDRN; | 1968 | mcasp->irq_request[SNDRV_PCM_STREAM_PLAYBACK] = XUNDRN; |
1949 | mcasp->irq_request[SNDRV_PCM_STREAM_CAPTURE] = ROVRN; | 1969 | mcasp->irq_request[SNDRV_PCM_STREAM_CAPTURE] = ROVRN; |
1950 | } | 1970 | } |
1951 | 1971 | ||
1952 | irq = platform_get_irq_byname(pdev, "rx"); | 1972 | irq = platform_get_irq_byname(pdev, "rx"); |
1953 | if (irq >= 0) { | 1973 | if (irq >= 0) { |
1954 | irq_name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "%s_rx", | 1974 | irq_name = devm_kasprintf(&pdev->dev, GFP_KERNEL, |
1955 | dev_name(&pdev->dev)); | 1975 | "%s_rx", dev_name(&pdev->dev)); |
1956 | ret = devm_request_threaded_irq(&pdev->dev, irq, NULL, | 1976 | ret = devm_request_threaded_irq(&pdev->dev, irq, NULL, |
1957 | davinci_mcasp_rx_irq_handler, | 1977 | davinci_mcasp_rx_irq_handler, |
1958 | IRQF_ONESHOT, irq_name, mcasp); | 1978 | IRQF_ONESHOT, irq_name, mcasp); |
1959 | if (ret) { | 1979 | if (ret) { |
1960 | dev_err(&pdev->dev, "RX IRQ request failed\n"); | 1980 | dev_err(&pdev->dev, "RX IRQ request failed\n"); |
1961 | goto err; | 1981 | goto err; |
1962 | } | 1982 | } |
1963 | 1983 | ||
1964 | mcasp->irq_request[SNDRV_PCM_STREAM_CAPTURE] = ROVRN; | 1984 | mcasp->irq_request[SNDRV_PCM_STREAM_CAPTURE] = ROVRN; |
1965 | } | 1985 | } |
1966 | 1986 | ||
1967 | irq = platform_get_irq_byname(pdev, "tx"); | 1987 | irq = platform_get_irq_byname(pdev, "tx"); |
1968 | if (irq >= 0) { | 1988 | if (irq >= 0) { |
1969 | irq_name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "%s_tx", | 1989 | irq_name = devm_kasprintf(&pdev->dev, GFP_KERNEL, |
1970 | dev_name(&pdev->dev)); | 1990 | "%s_tx", dev_name(&pdev->dev)); |
1971 | ret = devm_request_threaded_irq(&pdev->dev, irq, NULL, | 1991 | ret = devm_request_threaded_irq(&pdev->dev, irq, NULL, |
1972 | davinci_mcasp_tx_irq_handler, | 1992 | davinci_mcasp_tx_irq_handler, |
1973 | IRQF_ONESHOT, irq_name, mcasp); | 1993 | IRQF_ONESHOT, irq_name, mcasp); |
1974 | if (ret) { | 1994 | if (ret) { |
1975 | dev_err(&pdev->dev, "TX IRQ request failed\n"); | 1995 | dev_err(&pdev->dev, "TX IRQ request failed\n"); |
1976 | goto err; | 1996 | goto err; |
1977 | } | 1997 | } |
1978 | 1998 | ||
1979 | mcasp->irq_request[SNDRV_PCM_STREAM_PLAYBACK] = XUNDRN; | 1999 | mcasp->irq_request[SNDRV_PCM_STREAM_PLAYBACK] = XUNDRN; |
2000 | } | ||
1980 | } | 2001 | } |
1981 | 2002 | ||
1982 | dat = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dat"); | 2003 | dat = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dat"); |