All of lore.kernel.org
 help / color / mirror / Atom feed
From: Takashi Iwai <tiwai@suse.de>
To: "Michał Mirosław" <mirqus@gmail.com>
Cc: alsa-devel@alsa-project.org
Subject: Re: [PATCH 10/24] ALSA: au1x00: convert to platform device
Date: Fri, 14 Feb 2014 08:33:50 +0100	[thread overview]
Message-ID: <s5h38jmjggx.wl%tiwai@suse.de> (raw)
In-Reply-To: <CAHXqBF+wram51r4T4Gjd-3pYpg=ahzv2aZ7CVTPCLieB_o3fVg@mail.gmail.com>

At Fri, 14 Feb 2014 01:19:22 +0100,
Michał Mirosław wrote:
> 
> 2014-02-12 11:35 GMT+01:00 Takashi Iwai <tiwai@suse.de>:
> > From: Manuel Lauss <mano@roarinelk.homelinux.net>
> [...]
> > --- a/sound/mips/au1x00.c
> > +++ b/sound/mips/au1x00.c
> [...]
> > -static int __init
> > -au1000_init(void)
> > +static int au1000_ac97_probe(struct platform_device *pdev)
> >  {
> [...]
> > +out3:
> > +       kfree(au1000->stream[PLAYBACK]);
> > +out2:
> > +       kfree(au1000->stream[PLAYBACK]);
> > +out1:
> [...]
> 
> This looks bad.

Good catch.

> Maybe it could use devm_*() functions?

devm_*() doesn't fit with this structured data, unfortunately.
The revised patch below simplifies the part by just calling the single
destructor like other sound drivers.


thanks,

Takashi

-- >8 --
From: Manuel Lauss <mano@roarinelk.homelinux.net>
Subject: [PATCH v2] ALSA: au1x00: convert to platform device

Make sound/mips/au1x00.c a proper platform_driver.

[minor coding style fixes, cleanup and forward-ported by tiwai]

Cc: Charles Eidsness <charles@cooper-street.com>
Signed-off-by: Manuel Lauss <mano@roarinelk.homelinux.net>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
 sound/mips/au1x00.c | 239 +++++++++++++++++++++++++++++++---------------------
 1 file changed, 141 insertions(+), 98 deletions(-)

diff --git a/sound/mips/au1x00.c b/sound/mips/au1x00.c
index 224f54be15a6..526e59f43832 100644
--- a/sound/mips/au1x00.c
+++ b/sound/mips/au1x00.c
@@ -37,6 +37,7 @@
 #include <linux/ioport.h>
 #include <linux/interrupt.h>
 #include <linux/init.h>
+#include <linux/platform_device.h>
 #include <linux/slab.h>
 #include <linux/module.h>
 #include <sound/core.h>
@@ -98,6 +99,7 @@ struct snd_au1000 {
 
 	struct snd_pcm *pcm;
 	struct audio_stream *stream[2];	/* playback & capture */
+	int dmaid[2];		/* tx(0)/rx(1) DMA ids */
 };
 
 /*--------------------------- Local Functions --------------------------------*/
@@ -465,15 +467,17 @@ snd_au1000_pcm_new(struct snd_au1000 *au1000)
 	spin_lock_init(&au1000->stream[CAPTURE]->dma_lock);
 
 	flags = claim_dma_lock();
-	if ((au1000->stream[PLAYBACK]->dma = request_au1000_dma(DMA_ID_AC97C_TX,
+	au1000->stream[PLAYBACK]->dma = request_au1000_dma(au1000->dmaid[0],
 			"AC97 TX", au1000_dma_interrupt, 0,
-			au1000->stream[PLAYBACK])) < 0) {
+			au1000->stream[PLAYBACK]);
+	if (au1000->stream[PLAYBACK]->dma < 0) {
 		release_dma_lock(flags);
 		return -EBUSY;
 	}
-	if ((au1000->stream[CAPTURE]->dma = request_au1000_dma(DMA_ID_AC97C_RX,
+	au1000->stream[CAPTURE]->dma = request_au1000_dma(au1000->dmaid[1],
 			"AC97 RX", au1000_dma_interrupt, 0,
-			au1000->stream[CAPTURE])) < 0){
+			au1000->stream[CAPTURE]);
+	if (au1000->stream[CAPTURE]->dma < 0){
 		release_dma_lock(flags);
 		return -EBUSY;
 	}
@@ -552,69 +556,12 @@ get the interrupt driven case to work efficiently */
 	spin_unlock(&au1000->ac97_lock);
 }
 
-static int
-snd_au1000_ac97_new(struct snd_au1000 *au1000)
-{
-	int err;
-	struct snd_ac97_bus *pbus;
-	struct snd_ac97_template ac97;
- 	static struct snd_ac97_bus_ops ops = {
-		.write = snd_au1000_ac97_write,
-		.read = snd_au1000_ac97_read,
-	};
-
-	if ((au1000->ac97_res_port = request_mem_region(CPHYSADDR(AC97C_CONFIG),
-	       		0x100000, "Au1x00 AC97")) == NULL) {
-		snd_printk(KERN_ERR "ALSA AC97: can't grap AC97 port\n");
-		return -EBUSY;
-	}
-	au1000->ac97_ioport = (struct au1000_ac97_reg *)
-		KSEG1ADDR(au1000->ac97_res_port->start);
-
-	spin_lock_init(&au1000->ac97_lock);
-
-	/* configure pins for AC'97
-	TODO: move to board_setup.c */
-	au_writel(au_readl(SYS_PINFUNC) & ~0x02, SYS_PINFUNC);
-
-	/* Initialise Au1000's AC'97 Control Block */
-	au1000->ac97_ioport->cntrl = AC97C_RS | AC97C_CE;
-	udelay(10);
-	au1000->ac97_ioport->cntrl = AC97C_CE;
-	udelay(10);
-
-	/* Initialise External CODEC -- cold reset */
-	au1000->ac97_ioport->config = AC97C_RESET;
-	udelay(10);
-	au1000->ac97_ioport->config = 0x0;
-	mdelay(5);
-
-	/* Initialise AC97 middle-layer */
-	if ((err = snd_ac97_bus(au1000->card, 0, &ops, au1000, &pbus)) < 0)
- 		return err;
-
-	memset(&ac97, 0, sizeof(ac97));
-	ac97.private_data = au1000;
-	if ((err = snd_ac97_mixer(pbus, &ac97, &au1000->ac97)) < 0)
-		return err;
-
-	return 0;
-}
-
 /*------------------------------ Setup / Destroy ----------------------------*/
 
-void
-snd_au1000_free(struct snd_card *card)
+static void snd_au1000_free(struct snd_card *card)
 {
 	struct snd_au1000 *au1000 = card->private_data;
 
-	if (au1000->ac97_res_port) {
-		/* put internal AC97 block into reset */
-		au1000->ac97_ioport->cntrl = AC97C_RS;
-		au1000->ac97_ioport = NULL;
-		release_and_free_resource(au1000->ac97_res_port);
-	}
-
 	if (au1000->stream[PLAYBACK]) {
 	  	if (au1000->stream[PLAYBACK]->dma >= 0)
 			free_au1000_dma(au1000->stream[PLAYBACK]->dma);
@@ -626,71 +573,167 @@ snd_au1000_free(struct snd_card *card)
 			free_au1000_dma(au1000->stream[CAPTURE]->dma);
 		kfree(au1000->stream[CAPTURE]);
 	}
-}
 
+	if (au1000->ac97_res_port) {
+		/* put internal AC97 block into reset */
+		if (au1000->ac97_ioport) {
+			au1000->ac97_ioport->cntrl = AC97C_RS;
+			iounmap(au1000->ac97_ioport);
+			au1000->ac97_ioport = NULL;
+		}
+		release_and_free_resource(au1000->ac97_res_port);
+		au1000->ac97_res_port = NULL;
+	}
+}
 
-static struct snd_card *au1000_card;
+static struct snd_ac97_bus_ops ops = {
+	.write	= snd_au1000_ac97_write,
+	.read	= snd_au1000_ac97_read,
+};
 
-static int __init
-au1000_init(void)
+static int au1000_ac97_probe(struct platform_device *pdev)
 {
 	int err;
+	void __iomem *io;
+	struct resource *r;
 	struct snd_card *card;
 	struct snd_au1000 *au1000;
+	struct snd_ac97_bus *pbus;
+	struct snd_ac97_template ac97;
 
 	err = snd_card_create(-1, "AC97", THIS_MODULE,
-			      sizeof(struct snd_au1000), &card);
+				sizeof(struct snd_au1000), &card);
 	if (err < 0)
 		return err;
 
-	card->private_free = snd_au1000_free;
 	au1000 = card->private_data;
 	au1000->card = card;
+	spin_lock_init(&au1000->ac97_lock);
 
-	au1000->stream[PLAYBACK] = kmalloc(sizeof(struct audio_stream), GFP_KERNEL);
-	au1000->stream[CAPTURE ] = kmalloc(sizeof(struct audio_stream), GFP_KERNEL);
-	/* so that snd_au1000_free will work as intended */
- 	au1000->ac97_res_port = NULL;
-	if (au1000->stream[PLAYBACK])
-		au1000->stream[PLAYBACK]->dma = -1;
-	if (au1000->stream[CAPTURE ])
-		au1000->stream[CAPTURE ]->dma = -1;
-
-	if (au1000->stream[PLAYBACK] == NULL ||
-	    au1000->stream[CAPTURE ] == NULL) {
-		snd_card_free(card);
-		return -ENOMEM;
-	}
+	/* from here on let ALSA call the special freeing function */
+	card->private_free = snd_au1000_free;
 
-	if ((err = snd_au1000_ac97_new(au1000)) < 0 ) {
-		snd_card_free(card);
-		return err;
+	/* TX DMA ID */
+	r = platform_get_resource(pdev, IORESOURCE_DMA, 0);
+	if (!r) {
+		err = -ENODEV;
+		snd_printk(KERN_INFO "no TX DMA platform resource!\n");
+		goto out;
 	}
-
-	if ((err = snd_au1000_pcm_new(au1000)) < 0) {
-		snd_card_free(card);
-		return err;
+	au1000->dmaid[0] = r->start;
+
+	/* RX DMA ID */
+	r = platform_get_resource(pdev, IORESOURCE_DMA, 1);
+	if (!r) {
+		err = -ENODEV;
+		snd_printk(KERN_INFO "no RX DMA platform resource!\n");
+		goto out;
+	}
+	au1000->dmaid[1] = r->start;
+
+	au1000->stream[PLAYBACK] = kmalloc(sizeof(struct audio_stream),
+					   GFP_KERNEL);
+	if (!au1000->stream[PLAYBACK])
+		goto out;
+	au1000->stream[PLAYBACK]->dma = -1;
+
+	au1000->stream[CAPTURE] = kmalloc(sizeof(struct audio_stream),
+					  GFP_KERNEL);
+	if (!au1000->stream[CAPTURE])
+		goto out;
+	au1000->stream[CAPTURE]->dma = -1;
+
+	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!r)
+		goto out;
+
+	err = -EBUSY;
+	au1000->ac97_res_port = request_mem_region(r->start,
+					r->end - r->start + 1, pdev->name);
+	if (!au1000->ac97_res_port) {
+		snd_printk(KERN_ERR "ALSA AC97: can't grab AC97 port\n");
+		goto out;
 	}
 
+	io = ioremap(r->start, r->end - r->start + 1);
+	if (!io)
+		goto out;
+
+	au1000->ac97_ioport = (struct au1000_ac97_reg *)io;
+
+	/* configure pins for AC'97
+	TODO: move to board_setup.c */
+	au_writel(au_readl(SYS_PINFUNC) & ~0x02, SYS_PINFUNC);
+
+	/* Initialise Au1000's AC'97 Control Block */
+	au1000->ac97_ioport->cntrl = AC97C_RS | AC97C_CE;
+	udelay(10);
+	au1000->ac97_ioport->cntrl = AC97C_CE;
+	udelay(10);
+
+	/* Initialise External CODEC -- cold reset */
+	au1000->ac97_ioport->config = AC97C_RESET;
+	udelay(10);
+	au1000->ac97_ioport->config = 0x0;
+	mdelay(5);
+
+	/* Initialise AC97 middle-layer */
+	err = snd_ac97_bus(au1000->card, 0, &ops, au1000, &pbus);
+	if (err < 0)
+		goto out;
+
+	memset(&ac97, 0, sizeof(ac97));
+	ac97.private_data = au1000;
+	err = snd_ac97_mixer(pbus, &ac97, &au1000->ac97);
+	if (err < 0)
+		goto out;
+
+	err = snd_au1000_pcm_new(au1000);
+	if (err < 0)
+		goto out;
+
 	strcpy(card->driver, "Au1000-AC97");
 	strcpy(card->shortname, "AMD Au1000-AC97");
 	sprintf(card->longname, "AMD Au1000--AC97 ALSA Driver");
 
-	if ((err = snd_card_register(card)) < 0) {
-		snd_card_free(card);
-		return err;
-	}
+	err = snd_card_register(card);
+	if (err < 0)
+		goto out;
 
 	printk(KERN_INFO "ALSA AC97: Driver Initialized\n");
-	au1000_card = card;
+
+	platform_set_drvdata(pdev, card);
+
 	return 0;
+
+ out:
+	snd_card_free(card);
+	return err;
+}
+
+static int au1000_ac97_remove(struct platform_device *pdev)
+{
+	return snd_card_free(platform_get_drvdata(pdev));
 }
 
-static void __exit au1000_exit(void)
+struct platform_driver au1000_ac97c_driver = {
+	.driver	= {
+		.name	= "au1000-ac97c",
+		.owner	= THIS_MODULE,
+	},
+	.probe		= au1000_ac97_probe,
+	.remove		= au1000_ac97_remove,
+};
+
+static int __init au1000_ac97_load(void)
 {
-	snd_card_free(au1000_card);
+	return platform_driver_register(&au1000_ac97c_driver);
 }
 
-module_init(au1000_init);
-module_exit(au1000_exit);
+static void __exit au1000_ac97_unload(void)
+{
+	platform_driver_unregister(&au1000_ac97c_driver);
+}
 
+module_init(au1000_ac97_load);
+module_exit(au1000_ac97_unload);
-- 
1.8.5.2


_______________________________________________
Alsa-devel mailing list
Alsa-devel@alsa-project.org
http://mailman.alsa-project.org/mailman/listinfo/alsa-devel

  reply	other threads:[~2014-02-14  7:33 UTC|newest]

Thread overview: 31+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-02-12 10:35 [RFC PATCH 00/24] Mandate to pass a device pointer at card creation Takashi Iwai
2014-02-12 10:35 ` [PATCH 01/24] ALSA: Drop unused name argument in snd_register_oss_device() Takashi Iwai
2014-02-12 10:35 ` [PATCH 02/24] ALSA: Mandate to pass a device pointer at card creation time Takashi Iwai
2014-02-12 10:35 ` [PATCH 03/24] ALSA: drivers: Convert to snd_card_new() with a device pointer Takashi Iwai
2014-02-12 10:35 ` [PATCH 04/24] ALSA: isa: " Takashi Iwai
2014-02-12 10:35 ` [PATCH 05/24] ALSA: pci: " Takashi Iwai
2014-02-12 10:35 ` [PATCH 06/24] ALSA: usb: " Takashi Iwai
2014-02-12 10:35 ` [PATCH 07/24] ALSA: firewire: " Takashi Iwai
2014-02-14  6:56   ` Takashi Sakamoto
2014-02-12 10:35 ` [PATCH 08/24] ALSA: arm: " Takashi Iwai
2014-02-12 10:35 ` [PATCH 09/24] ALSA: atmel: " Takashi Iwai
2014-02-12 10:35 ` [PATCH 10/24] ALSA: au1x00: convert to platform device Takashi Iwai
2014-02-14  0:19   ` Michał Mirosław
2014-02-14  7:33     ` Takashi Iwai [this message]
2014-02-12 10:35 ` [PATCH 11/24] ALSA: mips: Convert to snd_card_new() with a device pointer Takashi Iwai
2014-02-12 10:35 ` [PATCH 12/24] ALSA: parisc: " Takashi Iwai
2014-02-12 10:35 ` [PATCH 13/24] ALSA: pcmcia: " Takashi Iwai
2014-02-12 10:35 ` [PATCH 14/24] ALSA: ppc: " Takashi Iwai
2014-02-12 10:35 ` [PATCH 15/24] ALSA: sh: " Takashi Iwai
2014-02-12 10:35 ` [PATCH 16/24] ALSA: sparc: " Takashi Iwai
2014-02-12 10:35 ` [PATCH 17/24] ALSA: spi: " Takashi Iwai
2014-02-12 10:35 ` [PATCH 18/24] ASoC: core: " Takashi Iwai
2014-02-12 13:04   ` Mark Brown
2014-02-12 13:10     ` Takashi Iwai
2014-02-12 10:35 ` [PATCH 19/24] HID: prodikeys: " Takashi Iwai
2014-02-12 10:35 ` [PATCH 20/24] [media] " Takashi Iwai
2014-02-12 10:35 ` [PATCH 21/24] thinkpad_acpi: " Takashi Iwai
2014-02-12 10:35 ` [PATCH 22/24] staging/line6: " Takashi Iwai
2014-02-12 10:35 ` [PATCH 23/24] staging/media: " Takashi Iwai
2014-02-12 10:35 ` [PATCH 24/24] usb: gadget: " Takashi Iwai
2014-02-14 11:58 ` [RFC PATCH 00/24] Mandate to pass a device pointer at card creation Takashi Iwai

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=s5h38jmjggx.wl%tiwai@suse.de \
    --to=tiwai@suse.de \
    --cc=alsa-devel@alsa-project.org \
    --cc=mirqus@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.