Module Name:    src
Committed By:   mrg
Date:           Sun Nov 20 13:13:43 UTC 2011

Modified Files:
        src/sys/arch/arm/xscale [jmcneill-audiomp3]: pxa2x0_ac97.c

Log Message:
port to audiomp: alloc/free changes, get_locks support, no more IPL_AUDIO,
convert splaudio() -> sc_intr_lock usage, take sc_intr_lock in acu_intr().


To generate a diff of this commit:
cvs rdiff -u -r1.9 -r1.9.4.1 src/sys/arch/arm/xscale/pxa2x0_ac97.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/arch/arm/xscale/pxa2x0_ac97.c
diff -u src/sys/arch/arm/xscale/pxa2x0_ac97.c:1.9 src/sys/arch/arm/xscale/pxa2x0_ac97.c:1.9.4.1
--- src/sys/arch/arm/xscale/pxa2x0_ac97.c:1.9	Fri Jul  1 20:32:51 2011
+++ src/sys/arch/arm/xscale/pxa2x0_ac97.c	Sun Nov 20 13:13:43 2011
@@ -1,4 +1,4 @@
-/*	$NetBSD: pxa2x0_ac97.c,v 1.9 2011/07/01 20:32:51 dyoung Exp $	*/
+/*	$NetBSD: pxa2x0_ac97.c,v 1.9.4.1 2011/11/20 13:13:43 mrg Exp $	*/
 
 /*
  * Copyright (c) 2003, 2005 Wasabi Systems, Inc.
@@ -42,6 +42,7 @@
 #include <sys/malloc.h>
 #include <sys/select.h>
 #include <sys/audioio.h>
+#include <sys/kmem.h>
 
 #include <machine/intr.h>
 #include <sys/bus.h>
@@ -111,6 +112,10 @@ struct acu_softc {
 
 	/* auconv encodings */
 	struct audio_encoding_set *sc_encodings;
+
+	/* MPSAFE interfaces */
+	kmutex_t sc_lock;
+	kmutex_t sc_intr_lock;
 };
 
 static int	pxaacu_match(device_t, cfdata_t, void *);
@@ -143,11 +148,12 @@ static int acu_getdev(void *, struct aud
 static int acu_mixer_set_port(void *, mixer_ctrl_t *);
 static int acu_mixer_get_port(void *, mixer_ctrl_t *);
 static int acu_query_devinfo(void *, mixer_devinfo_t *);
-static void *acu_malloc(void *, int, size_t, struct malloc_type *, int);
-static void acu_free(void *, void *, struct malloc_type *);
+static void *acu_malloc(void *, int, size_t);
+static void acu_free(void *, void *, size_t);
 static size_t acu_round_buffersize(void *, int, size_t);
 static paddr_t acu_mappage(void *, void *, off_t, int);
 static int acu_get_props(void *);
+static void acu_get_locks(void *, kmutex_t **, kmutex_t **);
 
 struct audio_hw_if acu_hw_if = {
 	acu_open,
@@ -177,6 +183,8 @@ struct audio_hw_if acu_hw_if = {
 	acu_trigger_output,
 	acu_trigger_input,
 	NULL,
+	NULL,
+	acu_get_locks,
 };
 
 struct audio_device acu_device = {
@@ -274,7 +282,7 @@ pxaacu_attach(device_t parent, device_t 
 		return;
 	}
 
-	sc->sc_irqcookie = pxa2x0_intr_establish(pxa->pxa_intr, IPL_AUDIO,
+	sc->sc_irqcookie = pxa2x0_intr_establish(pxa->pxa_intr, IPL_SCHED,
 	    acu_intr, sc);
 	KASSERT(sc->sc_irqcookie != NULL);
 
@@ -311,7 +319,7 @@ pxaacu_attach(device_t parent, device_t 
 	sc->sc_in_reset = 0;
 	sc->sc_dac_rate = sc->sc_adc_rate = 0;
 
-	if (ac97_attach(&sc->sc_host_if, sc->sc_dev)) {
+	if (ac97_attach(&sc->sc_host_if, sc->sc_dev, &sc->sc_lock)) {
 		aprint_error_dev(self, "Failed to attach primary codec\n");
  fail:
 		acu_reg_write(sc, AC97_GCR, 0);
@@ -359,7 +367,7 @@ acu_codec_read(void *arg, u_int8_t codec
 {
 	struct acu_softc *sc = arg;
 	u_int32_t val;
-	int s, reg, rv = 1;
+	int reg, rv = 1;
 
 	/*
 	 * If we're currently closed, return non-zero. The ac97 frontend
@@ -370,7 +378,7 @@ acu_codec_read(void *arg, u_int8_t codec
 
 	reg = AC97_CODEC_BASE(0) + codec_reg * 2;
 
-	s = splaudio();
+	mutex_spin_enter(&sc->sc_intr_lock);
 
 	if (!acu_codec_ready(sc) || (acu_reg_read(sc, AC97_CAR) & CAR_CAIP))
 		goto out_nocar;
@@ -403,7 +411,7 @@ acu_codec_read(void *arg, u_int8_t codec
 out:
 	acu_reg_write(sc, AC97_CAR, 0);
 out_nocar:
-	splx(s);
+	mutex_spin_exit(&sc->sc_intr_lock);
 	delay(10);
 	return (rv);
 }
@@ -413,7 +421,6 @@ acu_codec_write(void *arg, u_int8_t code
 {
 	struct acu_softc *sc = arg;
 	u_int16_t rv;
-	int s;
 
 	/*
 	 * If we're currently closed, chances are the user is just
@@ -424,10 +431,10 @@ acu_codec_write(void *arg, u_int8_t code
 	if (sc->sc_in_reset)
 		return (0);
 
-	s = splaudio();
+	mutex_spin_enter(&sc->sc_intr_lock);
 
 	if (!acu_codec_ready(sc) || (acu_reg_read(sc, AC97_CAR) & CAR_CAIP)) {
-		splx(s);
+		mutex_spin_exit(&sc->sc_intr_lock);
 		return (1);
 	}
 
@@ -443,7 +450,7 @@ acu_codec_write(void *arg, u_int8_t code
 	(void) acu_wait_gsr(sc, GSR_CDONE);
 	acu_reg_write(sc, AC97_CAR, 0);
 
-	splx(s);
+	mutex_spin_exit(&sc->sc_intr_lock);
 	delay(10);
 	return (0);
 }
@@ -475,6 +482,7 @@ acu_intr(void *arg)
 	struct acu_softc *sc = arg;
 	u_int32_t gsr, reg;
 
+	mutex_spin_enter(&sc->sc_intr_lock);
 	gsr = acu_reg_read(sc, AC97_GSR);
 
 	/*
@@ -503,6 +511,8 @@ acu_intr(void *arg)
 		aprint_error_dev(sc->sc_dev, "Rx PCM Fifo overrun\n");
 	}
 
+	mutex_spin_exit(&sc->sc_intr_lock);
+
 	return (1);
 }
 
@@ -659,16 +669,16 @@ acu_query_devinfo(void *arg, mixer_devin
 }
 
 static void *
-acu_malloc(void *arg, int direction, size_t size,
-    struct malloc_type *pool, int flags)
+acu_malloc(void *arg, int direction, size_t size)
 {
 	struct acu_softc *sc = arg;
 	struct acu_dma *ad;
 	int error;
 
-	if ((ad = malloc(sizeof(*ad), pool, flags)) == NULL)
+	if ((ad = kmem_alloc(sizeof(*ad), KM_SLEEP)) == NULL)
 		return (NULL);
 
+	/* XXX */
 	if ((ad->ad_dx = pxa2x0_dmac_allocate_xfer(M_NOWAIT)) == NULL)
 		goto error;
 
@@ -696,7 +706,7 @@ acu_malloc(void *arg, int direction, siz
 unmap_dmamem:	bus_dmamem_unmap(sc->sc_dmat, ad->ad_addr, size);
 free_dmamem:	bus_dmamem_free(sc->sc_dmat, ad->ad_segs, ad->ad_nsegs);
 free_xfer:	pxa2x0_dmac_free_xfer(ad->ad_dx);
-error:		free(ad, pool);
+error:		kmem_free(ad, sizeof(*ad));
 		return (NULL);
 	}
 
@@ -711,7 +721,7 @@ error:		free(ad, pool);
 }
 
 static void
-acu_free(void *arg, void *ptr, struct malloc_type *pool)
+acu_free(void *arg, void *ptr, size_t size)
 {
 	struct acu_softc *sc = arg;
 	struct acu_dma *ad, **adp;
@@ -726,7 +736,7 @@ acu_free(void *arg, void *ptr, struct ma
 			bus_dmamem_unmap(sc->sc_dmat, ad->ad_addr, ad->ad_size);
 			bus_dmamem_free(sc->sc_dmat, ad->ad_segs, ad->ad_nsegs);
 			*adp = ad->ad_next;
-			free(ad, pool);
+			kmem_free(ad, sizeof(*ad));
 			return;
 		}
 	}
@@ -762,20 +772,28 @@ acu_get_props(void *arg)
 	return (AUDIO_PROP_MMAP|AUDIO_PROP_INDEPENDENT|AUDIO_PROP_FULLDUPLEX);
 }
 
+static void
+acu_get_locks(void *opaque, kmutex_t **intr, kmutex_t **thread)
+{
+	struct acu_softc *sc = opaque;
+
+	*intr = &sc->sc_intr_lock;
+	*thread = &sc->sc_lock;
+}
+
 static int
 acu_halt_output(void *arg)
 {
 	struct acu_softc *sc = arg;
-	int s;
 
-	s = splaudio();
+	mutex_spin_enter(&sc->sc_intr_lock);
 	if (sc->sc_txdma) {
 		acu_reg_write(sc, AC97_POCR, 0);
 		acu_reg_write(sc, AC97_POSR, AC97_FIFOE);
 		pxa2x0_dmac_abort_xfer(sc->sc_txdma->ad_dx);
 		sc->sc_txdma = NULL;
 	}
-	splx(s);
+	mutex_spin_exit(&sc->sc_intr_lock);
 	return (0);
 }
 
@@ -783,16 +801,15 @@ static int
 acu_halt_input(void *arg)
 {
 	struct acu_softc *sc = arg;
-	int s;
 
-	s = splaudio();
+	mutex_spin_enter(&sc->sc_intr_lock);
 	if (sc->sc_rxdma) {
 		acu_reg_write(sc, AC97_PICR, 0);
 		acu_reg_write(sc, AC97_PISR, AC97_FIFOE);
 		pxa2x0_dmac_abort_xfer(sc->sc_rxdma->ad_dx);
 		sc->sc_rxdma = NULL;
 	}
-	splx(s);
+	mutex_spin_exit(&sc->sc_intr_lock);
 	return (0);
 }
 
@@ -914,7 +931,6 @@ acu_tx_loop_segment(struct dmac_xfer *dx
 {
 	struct acu_softc *sc = dx->dx_cookie;
 	struct acu_dma *ad;
-	int s;
 
 	if ((ad = sc->sc_txdma) == NULL)
 		panic("acu_tx_loop_segment: bad TX dma descriptor!");
@@ -928,9 +944,9 @@ acu_tx_loop_segment(struct dmac_xfer *dx
 		    status);
 	}
 
-	s = splaudio();
+	mutex_spin_enter(&sc->sc_intr_lock);
 	(sc->sc_txfunc)(sc->sc_txarg);
-	splx(s);
+	mutex_spin_exit(&sc->sc_intr_lock);
 }
 
 static void
@@ -938,7 +954,6 @@ acu_rx_loop_segment(struct dmac_xfer *dx
 {
 	struct acu_softc *sc = dx->dx_cookie;
 	struct acu_dma *ad;
-	int s;
 
 	if ((ad = sc->sc_rxdma) == NULL)
 		panic("acu_rx_loop_segment: bad RX dma descriptor!");
@@ -952,7 +967,7 @@ acu_rx_loop_segment(struct dmac_xfer *dx
 		    status);
 	}
 
-	s = splaudio();
+	mutex_spin_enter(&sc->sc_intr_lock);
 	(sc->sc_rxfunc)(sc->sc_rxarg);
-	splx(s);
+	mutex_spin_exit(&sc->sc_intr_lock);
 }

Reply via email to