sync: Introduce optional explicit way to unlock Mutex

Normally mutexes are unlocked by the Drop impl of MutexGuard when it
goes out of scope, but there may sometimes be an opportunity for clearer
code by unlocking explicitly.

    let mut regs = self.regs.lock();
    regs.piv = 1;
    regs.civ = 0;
    Mutex::unlock(regs);

    keep_going();

Alternative 1: use mem::drop from the prelude, which is less clear of
its purpose and can go wrong if we end up unintentionally passing it a
&MutexGuard or &mut MutexGuard.

    let mut regs = self.regs.lock();
    regs.piv = 1;
    regs.civ = 0;
    drop(regs);

    keep_going();

Alternative 2: use a curly braced block, which increases indentation and
requires the reader to deduce that the block exists only to drop the
mutex guard.

    {
        let mut regs = self.regs.lock();
        regs.piv = 1;
        regs.civ = 0;
    }

    keep_going();

TEST=cargo check

Change-Id: Ic42b46eb20d978f17a2309ea63ee15331537ec0b
diff --git a/devices/src/pci/ac97_bus_master.rs b/devices/src/pci/ac97_bus_master.rs
index b1245b9..364aba9 100644
--- a/devices/src/pci/ac97_bus_master.rs
+++ b/devices/src/pci/ac97_bus_master.rs
@@ -369,13 +369,13 @@
             } else if cr & CR_RPBM == 0 {
                 // Not already running.
                 // Run/Pause set to run.
-                {
-                    let mut regs = self.regs.lock();
-                    let func_regs = regs.func_regs_mut(func);
-                    func_regs.piv = 1;
-                    func_regs.civ = 0;
-                    func_regs.sr &= !SR_DCH;
-                }
+                let mut regs = self.regs.lock();
+                let func_regs = regs.func_regs_mut(func);
+                func_regs.piv = 1;
+                func_regs.civ = 0;
+                func_regs.sr &= !SR_DCH;
+                Mutex::unlock(regs);
+
                 if self.start_audio(func, mixer).is_err() {
                     warn!("Failed to start audio");
                 }
diff --git a/sync/src/mutex.rs b/sync/src/mutex.rs
index c479a2e..b03d629 100644
--- a/sync/src/mutex.rs
+++ b/sync/src/mutex.rs
@@ -89,6 +89,51 @@
             Err(_) => panic!("mutex is poisoned"),
         }
     }
+
+    /// An optional explicit way to unlock a mutex.
+    ///
+    /// Normally mutexes are unlocked by the Drop impl of MutexGuard when it
+    /// goes out of scope, but there may sometimes be an opportunity for clearer
+    /// code by unlocking explicitly.
+    ///
+    /// ```ignore
+    /// let mut regs = self.regs.lock();
+    /// regs.piv = 1;
+    /// regs.civ = 0;
+    /// Mutex::unlock(regs);
+    ///
+    /// keep_going();
+    /// ```
+    ///
+    /// Alternative 1: use mem::drop from the prelude, which is less clear of
+    /// its purpose and can go wrong if we end up unintentionally passing it a
+    /// &MutexGuard or &mut MutexGuard.
+    ///
+    /// ```ignore
+    /// let mut regs = self.regs.lock();
+    /// regs.piv = 1;
+    /// regs.civ = 0;
+    /// drop(regs);
+    ///
+    /// keep_going();
+    /// ```
+    ///
+    /// Alternative 2: use a curly braced block, which increases indentation and
+    /// requires the reader to deduce that the block exists only to drop the
+    /// mutex guard.
+    ///
+    /// ```ignore
+    /// {
+    ///     let mut regs = self.regs.lock();
+    ///     regs.piv = 1;
+    ///     regs.civ = 0;
+    /// }
+    ///
+    /// keep_going();
+    /// ```
+    pub fn unlock(_guard: MutexGuard<T>) {
+        // _guard unlocks on drop.
+    }
 }
 
 impl<T> From<T> for Mutex<T> {