Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F174410744
D59073.id187126.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
5 KB
Referenced Files
None
Subscribers
None
D59073.id187126.diff
View Options
diff --git a/sys/dev/sound/macio/onyx.c b/sys/dev/sound/macio/onyx.c
--- a/sys/dev/sound/macio/onyx.c
+++ b/sys/dev/sound/macio/onyx.c
@@ -39,6 +39,7 @@
#include <sys/malloc.h>
#include <sys/lock.h>
#include <sys/mutex.h>
+#include <sys/taskqueue.h>
#include <machine/dbdma.h>
#include <machine/intr_machdep.h>
#include <machine/resource.h>
@@ -65,6 +66,10 @@
{
device_t sc_dev;
uint32_t sc_addr;
+ struct mtx sc_volume_mtx;
+ struct task sc_volume_task;
+ uint8_t sc_left;
+ uint8_t sc_right;
};
static int onyx_probe(device_t);
@@ -185,6 +190,26 @@
return (0);
}
+/*
+ * onyx_write() sleeps in iicbus_transfer(), so onyx_set() cannot program the
+ * volume registers inline. Hand the new values to a task instead, which runs
+ * with no lock held.
+ */
+static void
+onyx_volume_task(void *arg, int pending __unused)
+{
+ struct onyx_softc *sc = arg;
+ uint8_t l, r;
+
+ mtx_lock(&sc->sc_volume_mtx);
+ l = sc->sc_left;
+ r = sc->sc_right;
+ mtx_unlock(&sc->sc_volume_mtx);
+
+ onyx_write(sc, PCM3052_REG_LEFT_ATTN, l);
+ onyx_write(sc, PCM3052_REG_RIGHT_ATTN, r);
+}
+
static int
onyx_probe(device_t dev)
{
@@ -216,6 +241,9 @@
sc->sc_dev = dev;
sc->sc_addr = iicbus_get_addr(dev);
+ mtx_init(&sc->sc_volume_mtx, "onyx volume", NULL, MTX_DEF);
+ TASK_INIT(&sc->sc_volume_task, 0, onyx_volume_task, sc);
+
i2s_mixer_class = &onyx_mixer_class;
i2s_mixer = dev;
@@ -255,6 +283,12 @@
static int
onyx_uninit(struct snd_mixer *m)
{
+ struct onyx_softc *sc;
+
+ sc = device_get_softc(mix_getdevinfo(m));
+
+ taskqueue_drain(taskqueue_thread, &sc->sc_volume_task);
+
return (0);
}
@@ -280,8 +314,12 @@
l = left + 128;
r = right + 128;
- onyx_write(sc, PCM3052_REG_LEFT_ATTN, l);
- onyx_write(sc, PCM3052_REG_RIGHT_ATTN, r);
+ mtx_lock(&sc->sc_volume_mtx);
+ sc->sc_left = l;
+ sc->sc_right = r;
+ mtx_unlock(&sc->sc_volume_mtx);
+
+ taskqueue_enqueue(taskqueue_thread, &sc->sc_volume_task);
return (left | (right << 8));
}
diff --git a/sys/dev/sound/macio/snapper.c b/sys/dev/sound/macio/snapper.c
--- a/sys/dev/sound/macio/snapper.c
+++ b/sys/dev/sound/macio/snapper.c
@@ -65,6 +65,7 @@
#include <sys/malloc.h>
#include <sys/lock.h>
#include <sys/mutex.h>
+#include <sys/taskqueue.h>
#include <machine/dbdma.h>
#include <machine/intr_machdep.h>
#include <machine/resource.h>
@@ -91,6 +92,9 @@
{
device_t sc_dev;
uint32_t sc_addr;
+ struct mtx sc_volume_mtx;
+ struct task sc_volume_task;
+ u_char sc_volume_reg[6];
};
static int snapper_probe(device_t);
@@ -338,6 +342,24 @@
return (0);
}
+/*
+ * snapper_write() sleeps in iicbus_transfer(), so snapper_set() cannot
+ * program the volume registers inline. Hand the new values to a task
+ * instead, which runs with no lock held.
+ */
+static void
+snapper_volume_task(void *arg, int pending __unused)
+{
+ struct snapper_softc *sc = arg;
+ u_char reg[6];
+
+ mtx_lock(&sc->sc_volume_mtx);
+ memcpy(reg, sc->sc_volume_reg, sizeof(reg));
+ mtx_unlock(&sc->sc_volume_mtx);
+
+ snapper_write(sc, SNAPPER_VOLUME, reg);
+}
+
static int
snapper_probe(device_t dev)
{
@@ -371,6 +393,9 @@
sc->sc_dev = dev;
sc->sc_addr = iicbus_get_addr(dev);
+ mtx_init(&sc->sc_volume_mtx, "snapper volume", NULL, MTX_DEF);
+ TASK_INIT(&sc->sc_volume_task, 0, snapper_volume_task, sc);
+
i2s_mixer_class = &snapper_mixer_class;
i2s_mixer = dev;
@@ -423,6 +448,12 @@
static int
snapper_uninit(struct snd_mixer *m)
{
+ struct snapper_softc *sc;
+
+ sc = device_get_softc(mix_getdevinfo(m));
+
+ taskqueue_drain(taskqueue_thread, &sc->sc_volume_task);
+
return (0);
}
@@ -456,7 +487,11 @@
reg[4] = (r & 0x00ff00) >> 8;
reg[5] = r & 0x0000ff;
- snapper_write(sc, SNAPPER_VOLUME, reg);
+ mtx_lock(&sc->sc_volume_mtx);
+ memcpy(sc->sc_volume_reg, reg, sizeof(reg));
+ mtx_unlock(&sc->sc_volume_mtx);
+
+ taskqueue_enqueue(taskqueue_thread, &sc->sc_volume_task);
return (left | (right << 8));
}
diff --git a/sys/dev/sound/macio/tumbler.c b/sys/dev/sound/macio/tumbler.c
--- a/sys/dev/sound/macio/tumbler.c
+++ b/sys/dev/sound/macio/tumbler.c
@@ -65,6 +65,7 @@
#include <sys/malloc.h>
#include <sys/lock.h>
#include <sys/mutex.h>
+#include <sys/taskqueue.h>
#include <machine/dbdma.h>
#include <machine/intr_machdep.h>
#include <machine/resource.h>
@@ -91,6 +92,9 @@
{
device_t sc_dev;
uint32_t sc_addr;
+ struct mtx sc_volume_mtx;
+ struct task sc_volume_task;
+ u_char sc_volume_reg[6];
};
static int tumbler_probe(device_t);
@@ -299,6 +303,24 @@
return (0);
}
+/*
+ * tumbler_write() sleeps in iicbus_transfer(), so tumbler_set() cannot
+ * program the volume registers inline. Hand the new values to a task
+ * instead, which runs with no lock held.
+ */
+static void
+tumbler_volume_task(void *arg, int pending __unused)
+{
+ struct tumbler_softc *sc = arg;
+ u_char reg[6];
+
+ mtx_lock(&sc->sc_volume_mtx);
+ memcpy(reg, sc->sc_volume_reg, sizeof(reg));
+ mtx_unlock(&sc->sc_volume_mtx);
+
+ tumbler_write(sc, TUMBLER_VOLUME, reg);
+}
+
static int
tumbler_probe(device_t dev)
{
@@ -326,6 +348,9 @@
sc->sc_dev = dev;
sc->sc_addr = iicbus_get_addr(dev);
+ mtx_init(&sc->sc_volume_mtx, "tumbler volume", NULL, MTX_DEF);
+ TASK_INIT(&sc->sc_volume_task, 0, tumbler_volume_task, sc);
+
i2s_mixer_class = &tumbler_mixer_class;
i2s_mixer = dev;
@@ -370,6 +395,12 @@
static int
tumbler_uninit(struct snd_mixer *m)
{
+ struct tumbler_softc *sc;
+
+ sc = device_get_softc(mix_getdevinfo(m));
+
+ taskqueue_drain(taskqueue_thread, &sc->sc_volume_task);
+
return (0);
}
@@ -403,7 +434,11 @@
reg[4] = (r & 0x00ff00) >> 8;
reg[5] = r & 0x0000ff;
- tumbler_write(sc, TUMBLER_VOLUME, reg);
+ mtx_lock(&sc->sc_volume_mtx);
+ memcpy(sc->sc_volume_reg, reg, sizeof(reg));
+ mtx_unlock(&sc->sc_volume_mtx);
+
+ taskqueue_enqueue(taskqueue_thread, &sc->sc_volume_task);
return (left | (right << 8));
}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sun, Oct 4, 12:20 AM (12 h, 57 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
40160271
Default Alt Text
D59073.id187126.diff (5 KB)
Attached To
Mode
D59073: sound: Defer macio codec volume writes to a task
Attached
Detach File
Event Timeline
Log In to Comment