lkml.org 
[lkml]   [2022]   [Aug]   [8]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 3/3] ASoC: apple: mca: Add locks on foreign cluster access
    Date
    In DAI ops, accesses to the native cluster (of the DAI), and to data of
    clusters related to it by a DPCM frontend-backend link, should have
    been synchronized by the 'pcm_mutex' lock at ASoC level.

    What is not covered are the 'port_driver' accesses on foreign clusters
    to which the current cluster has no a priori relation, so fill in
    locking for that. (This should only matter in bizarre configurations of
    sharing one MCA peripheral between ASoC cards.)

    Signed-off-by: Martin Povišer <povik+lin@cutebit.org>
    ---
    sound/soc/apple/mca.c | 27 ++++++++++++++++++++++++---
    1 file changed, 24 insertions(+), 3 deletions(-)

    diff --git a/sound/soc/apple/mca.c b/sound/soc/apple/mca.c
    index ab41fd1a2444..1e2464e89d1c 100644
    --- a/sound/soc/apple/mca.c
    +++ b/sound/soc/apple/mca.c
    @@ -159,6 +159,9 @@ struct mca_data {
    struct reset_control *rstc;
    struct device_link *pd_link;

    + /* Mutex for accessing port_driver of foreign clusters */
    + struct mutex port_mutex;
    +
    int nclusters;
    struct mca_cluster clusters[];
    };
    @@ -297,16 +300,21 @@ static bool mca_fe_clocks_in_use(struct mca_cluster *cl)
    struct mca_cluster *be_cl;
    int stream, i;

    + mutex_lock(&mca->port_mutex);
    for (i = 0; i < mca->nclusters; i++) {
    be_cl = &mca->clusters[i];

    if (be_cl->port_driver != cl->no)
    continue;

    - for_each_pcm_streams(stream)
    - if (be_cl->clocks_in_use[stream])
    + for_each_pcm_streams(stream) {
    + if (be_cl->clocks_in_use[stream]) {
    + mutex_unlock(&mca->port_mutex);
    return true;
    + }
    + }
    }
    + mutex_unlock(&mca->port_mutex);
    return false;
    }

    @@ -331,8 +339,10 @@ static int mca_be_prepare(struct snd_pcm_substream *substream,
    */
    if (!mca_fe_clocks_in_use(fe_cl)) {
    ret = mca_fe_enable_clocks(fe_cl);
    - if (ret < 0)
    + if (ret < 0) {
    + mutex_unlock(&mca->port_mutex);
    return ret;
    + }
    }

    cl->clocks_in_use[substream->stream] = true;
    @@ -350,6 +360,11 @@ static int mca_be_hw_free(struct snd_pcm_substream *substream,
    if (cl->port_driver < 0)
    return -EINVAL;

    + /*
    + * We are operating on a foreign cluster here, but since we
    + * belong to the same PCM, accesses should have been
    + * synchronized at ASoC level.
    + */
    fe_cl = &mca->clusters[cl->port_driver];
    if (!mca_fe_clocks_in_use(fe_cl))
    return 0; /* Nothing to do */
    @@ -722,7 +737,9 @@ static int mca_be_startup(struct snd_pcm_substream *substream,
    cl->base + REG_PORT_CLOCK_SEL);
    writel_relaxed(PORT_DATA_SEL_TXA(fe_cl->no),
    cl->base + REG_PORT_DATA_SEL);
    + mutex_lock(&mca->port_mutex);
    cl->port_driver = fe_cl->no;
    + mutex_unlock(&mca->port_mutex);
    cl->port_started[substream->stream] = true;

    return 0;
    @@ -732,6 +749,7 @@ static void mca_be_shutdown(struct snd_pcm_substream *substream,
    struct snd_soc_dai *dai)
    {
    struct mca_cluster *cl = mca_dai_to_cluster(dai);
    + struct mca_data *mca = cl->host;

    cl->port_started[substream->stream] = false;

    @@ -742,7 +760,9 @@ static void mca_be_shutdown(struct snd_pcm_substream *substream,
    */
    writel_relaxed(0, cl->base + REG_PORT_ENABLES);
    writel_relaxed(0, cl->base + REG_PORT_DATA_SEL);
    + mutex_lock(&mca->port_mutex);
    cl->port_driver = -1;
    + mutex_unlock(&mca->port_mutex);
    }
    }

    @@ -963,6 +983,7 @@ static int apple_mca_probe(struct platform_device *pdev)
    return -ENOMEM;
    mca->dev = &pdev->dev;
    mca->nclusters = nclusters;
    + mutex_init(&mca->port_mutex);
    platform_set_drvdata(pdev, mca);
    clusters = mca->clusters;

    --
    2.33.0
    \
     
     \ /
      Last update: 2022-08-09 00:43    [W:2.937 / U:0.048 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site