>From 5aff10596bb5057f63cd5a34b78ec8e60d6f6cc9 Mon Sep 17 00:00:00 2001
From: Vinod Koul <[email protected]>
Date: Wed, 17 Nov 2010 22:15:41 +0530
Subject: [PATCH 3/4] sst: fix driver to work as module

The current driver remove was erroneous and causes errors when unloading or 
loading second time

This patch fixes both of these issues

Signed-off-by: Vinod Koul <[email protected]>
---
 sound/pci/sst/intel_sst.c |   10 ++++------
 sound/pci/sst/intelmid.c  |   40 +++++++++++++++++++++++++---------------
 2 files changed, 29 insertions(+), 21 deletions(-)

diff --git a/sound/pci/sst/intel_sst.c b/sound/pci/sst/intel_sst.c
index 2fc11aa..c58fcfe 100644
--- a/sound/pci/sst/intel_sst.c
+++ b/sound/pci/sst/intel_sst.c
@@ -370,7 +370,7 @@ free_mad_wq:
 do_free_drv_ctx:
        kfree(sst_drv_ctx);
        sst_drv_ctx = NULL;
-       pr_err("sst: Probe failed with 0x%x\n", ret);
+       pr_err("sst: Probe failed with %d\n", ret);
        return ret;
 }
 
@@ -406,11 +406,9 @@ static void __devexit intel_sst_remove(struct pci_dev *pci)
        destroy_workqueue(sst_drv_ctx->post_msg_wq);
        destroy_workqueue(sst_drv_ctx->mad_wq);
        kfree(sst_drv_ctx);
-       pci_release_region(pci, 1);
-       pci_release_region(pci, 2);
-       pci_release_region(pci, 3);
-       pci_release_region(pci, 4);
-       pci_release_region(pci, 5);
+       sst_drv_ctx = NULL;
+       pci_release_regions(pci);
+       pci_disable_device(pci);
        pci_set_drvdata(pci, NULL);
 }
 
diff --git a/sound/pci/sst/intelmid.c b/sound/pci/sst/intelmid.c
index 19e0a58..44431d7 100644
--- a/sound/pci/sst/intelmid.c
+++ b/sound/pci/sst/intelmid.c
@@ -817,6 +817,10 @@ static int __devinit snd_intelmad_sst_register(
        return ret_val;
 }
 
+static void snd_intelmad_page_free(struct snd_pcm *pcm)
+{
+       snd_pcm_lib_preallocate_free_for_all(pcm);
+}
 /* Driver Init/exit functionalities */
 /**
  * snd_intelmad_pcm_new - to setup pcm for the card
@@ -868,6 +872,7 @@ static int __devinit snd_intelmad_pcm_new(struct snd_card 
*card,
                snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, cap_ops);
        /* setup private data which can be retrieved when required */
        pcm->private_data = intelmaddata;
+       pcm->private_free = snd_intelmad_page_free;
        pcm->info_flags = 0;
        strncpy(pcm->name, card->shortname, strlen(card->shortname));
        /* allocate dma pages for ALSA stream operations */
@@ -1007,14 +1012,14 @@ static int snd_intelmad_dev_free(struct snd_device 
*device)
        intelmaddata = device->device_data;
 
        pr_debug("sst: snd_intelmad_dev_free called\n");
-       snd_card_free(intelmaddata->card);
-       /*genl_unregister_family(&audio_event_genl_family);*/
        unregister_sst_card(intelmaddata->sstdrv_ops);
 
        /* free allocated memory for internal context */
        destroy_workqueue(intelmaddata->mad_jack_wq);
+       device->device_data = NULL;
        kfree(intelmaddata->sstdrv_ops);
        kfree(intelmaddata);
+
        return 0;
 }
 
@@ -1100,7 +1105,7 @@ int __devinit snd_intelmad_probe(struct platform_device 
*pdev)
        ret_val = snd_intelmad_sst_register(intelmaddata);
        if (ret_val) {
                pr_err("sst: snd_intelmad_sst_register failed\n");
-               goto free_allocs;
+               goto set_null_data;
        }
 
        intelmaddata->pmic_status = PMIC_INIT;
@@ -1108,19 +1113,19 @@ int __devinit snd_intelmad_probe(struct platform_device 
*pdev)
        ret_val = snd_intelmad_pcm(card, intelmaddata);
        if (ret_val) {
                pr_err("sst: snd_intelmad_pcm failed\n");
-               goto free_allocs;
+               goto free_sst;
        }
 
        ret_val = snd_intelmad_mixer(intelmaddata);
        if (ret_val) {
                pr_err("sst: snd_intelmad_mixer failed\n");
-               goto free_allocs;
+               goto free_card;
        }
 
        ret_val = snd_intelmad_jack(intelmaddata);
        if (ret_val) {
                pr_err("sst: snd_intelmad_jack failed\n");
-               goto free_allocs;
+               goto free_card;
        }
 
        /*create work queue for jack interrupt*/
@@ -1129,33 +1134,41 @@ int __devinit snd_intelmad_probe(struct platform_device 
*pdev)
 
        intelmaddata->mad_jack_wq = create_workqueue("sst_mad_jack_wq");
        if (!intelmaddata->mad_jack_wq)
-               goto free_mad_jack_wq;
+               goto free_card;
 
        ret_val = snd_intelmad_register_irq(intelmaddata);
        if (ret_val) {
                pr_err("sst: snd_intelmad_register_irq fail\n");
-               goto free_allocs;
+               goto free_mad_jack_wq;
        }
 
        /* internal function call to register device with ALSA */
        ret_val = snd_intelmad_create(intelmaddata, card);
        if (ret_val) {
                pr_err("sst: snd_intelmad_create failed\n");
-               goto free_allocs;
+               goto free_mad_jack_wq;
        }
        card->private_data = &intelmaddata;
        snd_card_set_dev(card, &pdev->dev);
        ret_val = snd_card_register(card);
        if (ret_val) {
                pr_err("sst: snd_card_register failed\n");
-               goto free_allocs;
+               goto set_pvt_data;;
        }
 
        pr_debug("sst:snd_intelmad_probe complete\n");
        return ret_val;
 
+set_pvt_data:
+       card->private_data = NULL;
 free_mad_jack_wq:
        destroy_workqueue(intelmaddata->mad_jack_wq);
+free_card:
+       snd_card_free(intelmaddata->card);
+free_sst:
+       unregister_sst_card(intelmaddata->sstdrv_ops);
+set_null_data:
+       platform_set_drvdata(pdev, NULL);
 free_allocs:
        pr_err("sst: probe failed\n");
        snd_card_free(card);
@@ -1170,13 +1183,10 @@ static int snd_intelmad_remove(struct platform_device 
*pdev)
        struct snd_intelmad *intelmaddata = platform_get_drvdata(pdev);
 
        if (intelmaddata) {
+               free_irq(intelmaddata->irq, intelmaddata);
                snd_card_free(intelmaddata->card);
-               unregister_sst_card(intelmaddata->sstdrv_ops);
-               /* free allocated memory for internal context */
-               destroy_workqueue(intelmaddata->mad_jack_wq);
-               kfree(intelmaddata->sstdrv_ops);
-               kfree(intelmaddata);
        }
+       platform_set_drvdata(pdev, NULL);
        return 0;
 }
 
-- 
1.7.2.3

Attachment: 0003-sst-fix-driver-to-work-as-module.patch
Description: 0003-sst-fix-driver-to-work-as-module.patch

_______________________________________________
MeeGo-kernel mailing list
[email protected]
http://lists.meego.com/listinfo/meego-kernel

Reply via email to