X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=drivers%2Fstaging%2Fline6%2Fpcm.c;h=4795f128490636a48909b21816f4985cc66a46c0;hb=1873e50028ce87dd9014049c86d71a898fa02166;hp=02f77d74809f3d15572c82ad44b79ebac2dc33b0;hpb=9306a398e76df1952685e95cc293c4100fe5286d;p=firefly-linux-kernel-4.4.55.git diff --git a/drivers/staging/line6/pcm.c b/drivers/staging/line6/pcm.c index 02f77d74809f..4795f1284906 100644 --- a/drivers/staging/line6/pcm.c +++ b/drivers/staging/line6/pcm.c @@ -107,11 +107,15 @@ static bool test_flags(unsigned long flags0, unsigned long flags1, int line6_pcm_acquire(struct snd_line6_pcm *line6pcm, int channels) { - unsigned long flags_old = - __sync_fetch_and_or(&line6pcm->flags, channels); - unsigned long flags_new = flags_old | channels; - unsigned long flags_final = flags_old; - int err = 0; + unsigned long flags_old, flags_new, flags_final; + int err; + + do { + flags_old = ACCESS_ONCE(line6pcm->flags); + flags_new = flags_old | channels; + } while (cmpxchg(&line6pcm->flags, flags_old, flags_new) != flags_old); + + flags_final = flags_old; line6pcm->prev_fbuf = NULL; @@ -197,9 +201,12 @@ pcm_acquire_error: int line6_pcm_release(struct snd_line6_pcm *line6pcm, int channels) { - unsigned long flags_old = - __sync_fetch_and_and(&line6pcm->flags, ~channels); - unsigned long flags_new = flags_old & ~channels; + unsigned long flags_old, flags_new; + + do { + flags_old = ACCESS_ONCE(line6pcm->flags); + flags_new = flags_old & ~channels; + } while (cmpxchg(&line6pcm->flags, flags_old, flags_new) != flags_old); if (test_flags(flags_new, flags_old, LINE6_BITS_CAPTURE_STREAM)) line6_unlink_audio_in_urbs(line6pcm);