ASoC: Intel: mrfld - create separate module for pci part
authorVinod Koul <vinod.koul@intel.com>
Tue, 4 Nov 2014 10:55:16 +0000 (16:25 +0530)
committerMark Brown <broonie@kernel.org>
Thu, 6 Nov 2014 12:36:17 +0000 (12:36 +0000)
Now the SST_IPC will support both ACPI and PCI, separate into core module
and PCI module. This also move probe function into PCI module and exports
the required symbols from core module

Signed-off-by: Subhransu S. Prusty <subhransu.s.prusty@intel.com>
Signed-off-by: Vinod Koul <vinod.koul@intel.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
sound/soc/intel/Kconfig
sound/soc/intel/sst/Makefile
sound/soc/intel/sst/sst.c
sound/soc/intel/sst/sst.h
sound/soc/intel/sst/sst_pci.c [new file with mode: 0644]
sound/soc/intel/sst/sst_pvt.c

index ae7f87221a3c44d1432b142088e54280c6d07e6f..c963a5d34111a9017535d078486e8ab4b0937130 100644 (file)
@@ -3,7 +3,7 @@ config SND_MFLD_MACHINE
        depends on INTEL_SCU_IPC
        select SND_SOC_SN95031
        select SND_SST_MFLD_PLATFORM
-       select SND_SST_IPC
+       select SND_SST_IPC_PCI
        help
           This adds support for ASoC machine driver for Intel(R) MID Medfield platform
           used as alsa device in audio substem in Intel(R) MID devices
@@ -16,6 +16,10 @@ config SND_SST_MFLD_PLATFORM
 config SND_SST_IPC
        tristate
 
+config SND_SST_IPC_PCI
+       tristate
+       select SND_SST_IPC
+
 config SND_SOC_INTEL_SST
        tristate "ASoC support for Intel(R) Smart Sound Technology"
        select SND_SOC_INTEL_SST_ACPI if ACPI
index 4d0e79b1f8cecc2eeb4f481f27df0526f6396feb..b8aa1d35df74f02632e25d66054b2abe59da3ce9 100644 (file)
@@ -1,3 +1,7 @@
-snd-intel-sst-objs := sst.o sst_ipc.o sst_stream.o sst_drv_interface.o sst_loader.o sst_pvt.o
+snd-intel-sst-core-objs := sst.o sst_ipc.o sst_stream.o sst_drv_interface.o sst_loader.o sst_pvt.o
+snd-intel-sst-pci-objs += sst_pci.o
+
+
+obj-$(CONFIG_SND_SST_IPC) += snd-intel-sst-core.o
+obj-$(CONFIG_SND_SST_IPC_PCI) += snd-intel-sst-pci.o
 
-obj-$(CONFIG_SND_SST_IPC) += snd-intel-sst.o
index 2bfb404ea7c15399d3db2c5cc63b314357667bd2..8753754859890141885e2b504eb61bd801ecb8a4 100644 (file)
  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  */
 #include <linux/module.h>
-#include <linux/pci.h>
 #include <linux/fs.h>
 #include <linux/interrupt.h>
 #include <linux/firmware.h>
 #include <linux/pm_runtime.h>
 #include <linux/pm_qos.h>
 #include <linux/async.h>
-#include <linux/delay.h>
-#include <linux/acpi.h>
 #include <sound/core.h>
-#include <sound/pcm.h>
 #include <sound/soc.h>
-#include <sound/compress_driver.h>
-#include <asm/intel-mid.h>
 #include <asm/platform_sst_audio.h>
 #include "../sst-mfld-platform.h"
 #include "sst.h"
@@ -242,6 +236,7 @@ int sst_alloc_drv_context(struct intel_sst_drv **ctx,
 
        return 0;
 }
+EXPORT_SYMBOL_GPL(sst_alloc_drv_context);
 
 int sst_context_init(struct intel_sst_drv *ctx)
 {
@@ -260,6 +255,7 @@ int sst_context_init(struct intel_sst_drv *ctx)
                return -EINVAL;
 
        sst_init_locks(ctx);
+       sst_set_fw_state_locked(ctx, SST_RESET);
 
        /* pvt_id 0 reserved for async messages */
        ctx->pvt_id = 1;
@@ -307,12 +303,22 @@ int sst_context_init(struct intel_sst_drv *ctx)
        }
        pm_qos_add_request(ctx->qos, PM_QOS_CPU_DMA_LATENCY,
                                PM_QOS_DEFAULT_VALUE);
+
+       dev_dbg(ctx->dev, "Requesting FW %s now...\n", ctx->firmware_name);
+       ret = request_firmware_nowait(THIS_MODULE, true, ctx->firmware_name,
+                                     ctx->dev, GFP_KERNEL, ctx, sst_firmware_load_cb);
+       if (ret) {
+               dev_err(ctx->dev, "Firmware download failed:%d\n", ret);
+               goto do_free_mem;
+       }
+       sst_register(ctx->dev);
        return 0;
 
 do_free_mem:
        destroy_workqueue(ctx->post_msg_wq);
        return ret;
 }
+EXPORT_SYMBOL_GPL(sst_context_init);
 
 void sst_context_cleanup(struct intel_sst_drv *ctx)
 {
@@ -331,6 +337,7 @@ void sst_context_cleanup(struct intel_sst_drv *ctx)
        sst_memcpy_free_resources(ctx);
        ctx = NULL;
 }
+EXPORT_SYMBOL_GPL(sst_context_cleanup);
 
 void sst_configure_runtime_pm(struct intel_sst_drv *ctx)
 {
@@ -339,175 +346,7 @@ void sst_configure_runtime_pm(struct intel_sst_drv *ctx)
        pm_runtime_allow(ctx->dev);
        pm_runtime_put_noidle(ctx->dev);
 }
-
-static int sst_platform_get_resources(struct intel_sst_drv *ctx)
-{
-       int ddr_base, ret = 0;
-       struct pci_dev *pci = ctx->pci;
-       ret = pci_request_regions(pci, SST_DRV_NAME);
-       if (ret)
-               return ret;
-
-       /* map registers */
-       /* DDR base */
-       if (ctx->dev_id == SST_MRFLD_PCI_ID) {
-               ctx->ddr_base = pci_resource_start(pci, 0);
-               /* check that the relocated IMR base matches with FW Binary */
-               ddr_base = relocate_imr_addr_mrfld(ctx->ddr_base);
-               if (!ctx->pdata->lib_info) {
-                       dev_err(ctx->dev, "lib_info pointer NULL\n");
-                       ret = -EINVAL;
-                       goto do_release_regions;
-               }
-               if (ddr_base != ctx->pdata->lib_info->mod_base) {
-                       dev_err(ctx->dev,
-                                       "FW LSP DDR BASE does not match with IFWI\n");
-                       ret = -EINVAL;
-                       goto do_release_regions;
-               }
-               ctx->ddr_end = pci_resource_end(pci, 0);
-
-               ctx->ddr = pcim_iomap(pci, 0,
-                                       pci_resource_len(pci, 0));
-               if (!ctx->ddr) {
-                       ret = -EINVAL;
-                       goto do_release_regions;
-               }
-               dev_dbg(ctx->dev, "sst: DDR Ptr %p\n", ctx->ddr);
-       } else {
-               ctx->ddr = NULL;
-       }
-       /* SHIM */
-       ctx->shim_phy_add = pci_resource_start(pci, 1);
-       ctx->shim = pcim_iomap(pci, 1, pci_resource_len(pci, 1));
-       if (!ctx->shim) {
-               ret = -EINVAL;
-               goto do_release_regions;
-       }
-       dev_dbg(ctx->dev, "SST Shim Ptr %p\n", ctx->shim);
-
-       /* Shared SRAM */
-       ctx->mailbox_add = pci_resource_start(pci, 2);
-       ctx->mailbox = pcim_iomap(pci, 2, pci_resource_len(pci, 2));
-       if (!ctx->mailbox) {
-               ret = -EINVAL;
-               goto do_release_regions;
-       }
-       dev_dbg(ctx->dev, "SRAM Ptr %p\n", ctx->mailbox);
-
-       /* IRAM */
-       ctx->iram_end = pci_resource_end(pci, 3);
-       ctx->iram_base = pci_resource_start(pci, 3);
-       ctx->iram = pcim_iomap(pci, 3, pci_resource_len(pci, 3));
-       if (!ctx->iram) {
-               ret = -EINVAL;
-               goto do_release_regions;
-       }
-       dev_dbg(ctx->dev, "IRAM Ptr %p\n", ctx->iram);
-
-       /* DRAM */
-       ctx->dram_end = pci_resource_end(pci, 4);
-       ctx->dram_base = pci_resource_start(pci, 4);
-       ctx->dram = pcim_iomap(pci, 4, pci_resource_len(pci, 4));
-       if (!ctx->dram) {
-               ret = -EINVAL;
-               goto do_release_regions;
-       }
-       dev_dbg(ctx->dev, "DRAM Ptr %p\n", ctx->dram);
-do_release_regions:
-       pci_release_regions(pci);
-       return 0;
-}
-/*
-* intel_sst_probe - PCI probe function
-*
-* @pci:        PCI device structure
-* @pci_id: PCI device ID structure
-*
-*/
-static int intel_sst_probe(struct pci_dev *pci,
-                       const struct pci_device_id *pci_id)
-{
-       int ret = 0;
-       struct intel_sst_drv *sst_drv_ctx;
-       struct sst_platform_info *sst_pdata = pci->dev.platform_data;
-
-       dev_dbg(&pci->dev, "Probe for DID %x\n", pci->device);
-
-       ret = sst_alloc_drv_context(&sst_drv_ctx, &pci->dev, pci->device);
-       if (ret < 0)
-               return ret;
-
-       sst_drv_ctx->pdata = sst_pdata;
-       sst_drv_ctx->irq_num = pci->irq;
-
-       ret = sst_context_init(sst_drv_ctx);
-       if (ret < 0)
-               goto do_free_drv_ctx;
-
-
-       /* Init the device */
-       ret = pcim_enable_device(pci);
-       if (ret) {
-               dev_err(sst_drv_ctx->dev,
-                       "device can't be enabled. Returned err: %d\n", ret);
-               goto do_destroy_wq;
-       }
-       sst_drv_ctx->pci = pci_dev_get(pci);
-
-       ret = sst_platform_get_resources(sst_drv_ctx);
-       if (ret < 0)
-               goto do_destroy_wq;
-
-       sst_set_fw_state_locked(sst_drv_ctx, SST_RESET);
-       snprintf(sst_drv_ctx->firmware_name, sizeof(sst_drv_ctx->firmware_name),
-                       "%s%04x%s", "fw_sst_",
-                       sst_drv_ctx->dev_id, ".bin");
-       dev_dbg(sst_drv_ctx->dev,
-               "Requesting FW %s now...\n", sst_drv_ctx->firmware_name);
-       ret = request_firmware_nowait(THIS_MODULE, 1,
-                       sst_drv_ctx->firmware_name, sst_drv_ctx->dev,
-                       GFP_KERNEL, sst_drv_ctx, sst_firmware_load_cb);
-
-       if (ret) {
-               dev_err(sst_drv_ctx->dev,
-                       "Firmware load failed with error: %d\n", ret);
-               goto do_release_regions;
-       }
-
-
-       pci_set_drvdata(pci, sst_drv_ctx);
-       sst_configure_runtime_pm(sst_drv_ctx);
-       sst_register(sst_drv_ctx->dev);
-
-       return ret;
-
-do_release_regions:
-       pci_release_regions(pci);
-do_destroy_wq:
-       destroy_workqueue(sst_drv_ctx->post_msg_wq);
-do_free_drv_ctx:
-       dev_err(sst_drv_ctx->dev, "Probe failed with %d\n", ret);
-       return ret;
-}
-
-/**
-* intel_sst_remove - PCI remove function
-*
-* @pci:        PCI device structure
-*
-* This function is called by OS when a device is unloaded
-* This frees the interrupt etc
-*/
-static void intel_sst_remove(struct pci_dev *pci)
-{
-       struct intel_sst_drv *sst_drv_ctx = pci_get_drvdata(pci);
-
-       sst_context_cleanup(sst_drv_ctx);
-       pci_dev_put(sst_drv_ctx->pci);
-       pci_release_regions(pci);
-       pci_set_drvdata(pci, NULL);
-}
+EXPORT_SYMBOL_GPL(sst_configure_runtime_pm);
 
 static int intel_sst_runtime_suspend(struct device *dev)
 {
@@ -546,27 +385,8 @@ static int intel_sst_runtime_resume(struct device *dev)
        return ret;
 }
 
-static const struct dev_pm_ops intel_sst_pm = {
+const struct dev_pm_ops intel_sst_pm = {
        .runtime_suspend = intel_sst_runtime_suspend,
        .runtime_resume = intel_sst_runtime_resume,
 };
-
-/* PCI Routines */
-static struct pci_device_id intel_sst_ids[] = {
-       { PCI_VDEVICE(INTEL, SST_MRFLD_PCI_ID), 0},
-       { 0, }
-};
-
-static struct pci_driver sst_driver = {
-       .name = SST_DRV_NAME,
-       .id_table = intel_sst_ids,
-       .probe = intel_sst_probe,
-       .remove = intel_sst_remove,
-#ifdef CONFIG_PM
-       .driver = {
-               .pm = &intel_sst_pm,
-       },
-#endif
-};
-
-module_pci_driver(sst_driver);
+EXPORT_SYMBOL_GPL(intel_sst_pm);
index b65b9c0d87503ecf52bfcd335dd45bc9ec518023..3ee555e31716a3664d1bc0a9a7b8bf45894dcb4e 100644 (file)
@@ -40,6 +40,7 @@
 #define MRFLD_FW_FEATURE_BASE_OFFSET 0x4
 #define MRFLD_FW_BSS_RESET_BIT 0
 
+extern const struct dev_pm_ops intel_sst_pm;
 enum sst_states {
        SST_FW_LOADING = 1,
        SST_FW_RUNNING,
@@ -537,4 +538,9 @@ void sst_fill_header_dsp(struct ipc_dsp_hdr *dsp, int msg,
 int sst_register(struct device *);
 int sst_unregister(struct device *);
 
+int sst_alloc_drv_context(struct intel_sst_drv **ctx,
+               struct device *dev, unsigned int dev_id);
+int sst_context_init(struct intel_sst_drv *ctx);
+void sst_context_cleanup(struct intel_sst_drv *ctx);
+void sst_configure_runtime_pm(struct intel_sst_drv *ctx);
 #endif
diff --git a/sound/soc/intel/sst/sst_pci.c b/sound/soc/intel/sst/sst_pci.c
new file mode 100644 (file)
index 0000000..3a0b3bf
--- /dev/null
@@ -0,0 +1,209 @@
+/*
+ *  sst_pci.c - SST (LPE) driver init file for pci enumeration.
+ *
+ *  Copyright (C) 2008-14      Intel Corp
+ *  Authors:   Vinod Koul <vinod.koul@intel.com>
+ *             Harsha Priya <priya.harsha@intel.com>
+ *             Dharageswari R <dharageswari.r@intel.com>
+ *             KP Jeeja <jeeja.kp@intel.com>
+ *  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; version 2 of the License.
+ *
+ *  This program is distributed in the hope that it will be useful, but
+ *  WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  General Public License for more details.
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ */
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/fs.h>
+#include <linux/firmware.h>
+#include <linux/pm_runtime.h>
+#include <sound/core.h>
+#include <sound/soc.h>
+#include <asm/platform_sst_audio.h>
+#include "../sst-mfld-platform.h"
+#include "sst.h"
+
+static int sst_platform_get_resources(struct intel_sst_drv *ctx)
+{
+       int ddr_base, ret = 0;
+       struct pci_dev *pci = ctx->pci;
+
+       ret = pci_request_regions(pci, SST_DRV_NAME);
+       if (ret)
+               return ret;
+
+       /* map registers */
+       /* DDR base */
+       if (ctx->dev_id == SST_MRFLD_PCI_ID) {
+               ctx->ddr_base = pci_resource_start(pci, 0);
+               /* check that the relocated IMR base matches with FW Binary */
+               ddr_base = relocate_imr_addr_mrfld(ctx->ddr_base);
+               if (!ctx->pdata->lib_info) {
+                       dev_err(ctx->dev, "lib_info pointer NULL\n");
+                       ret = -EINVAL;
+                       goto do_release_regions;
+               }
+               if (ddr_base != ctx->pdata->lib_info->mod_base) {
+                       dev_err(ctx->dev,
+                                       "FW LSP DDR BASE does not match with IFWI\n");
+                       ret = -EINVAL;
+                       goto do_release_regions;
+               }
+               ctx->ddr_end = pci_resource_end(pci, 0);
+
+               ctx->ddr = pcim_iomap(pci, 0,
+                                       pci_resource_len(pci, 0));
+               if (!ctx->ddr) {
+                       ret = -EINVAL;
+                       goto do_release_regions;
+               }
+               dev_dbg(ctx->dev, "sst: DDR Ptr %p\n", ctx->ddr);
+       } else {
+               ctx->ddr = NULL;
+       }
+       /* SHIM */
+       ctx->shim_phy_add = pci_resource_start(pci, 1);
+       ctx->shim = pcim_iomap(pci, 1, pci_resource_len(pci, 1));
+       if (!ctx->shim) {
+               ret = -EINVAL;
+               goto do_release_regions;
+       }
+       dev_dbg(ctx->dev, "SST Shim Ptr %p\n", ctx->shim);
+
+       /* Shared SRAM */
+       ctx->mailbox_add = pci_resource_start(pci, 2);
+       ctx->mailbox = pcim_iomap(pci, 2, pci_resource_len(pci, 2));
+       if (!ctx->mailbox) {
+               ret = -EINVAL;
+               goto do_release_regions;
+       }
+       dev_dbg(ctx->dev, "SRAM Ptr %p\n", ctx->mailbox);
+
+       /* IRAM */
+       ctx->iram_end = pci_resource_end(pci, 3);
+       ctx->iram_base = pci_resource_start(pci, 3);
+       ctx->iram = pcim_iomap(pci, 3, pci_resource_len(pci, 3));
+       if (!ctx->iram) {
+               ret = -EINVAL;
+               goto do_release_regions;
+       }
+       dev_dbg(ctx->dev, "IRAM Ptr %p\n", ctx->iram);
+
+       /* DRAM */
+       ctx->dram_end = pci_resource_end(pci, 4);
+       ctx->dram_base = pci_resource_start(pci, 4);
+       ctx->dram = pcim_iomap(pci, 4, pci_resource_len(pci, 4));
+       if (!ctx->dram) {
+               ret = -EINVAL;
+               goto do_release_regions;
+       }
+       dev_dbg(ctx->dev, "DRAM Ptr %p\n", ctx->dram);
+do_release_regions:
+       pci_release_regions(pci);
+       return 0;
+}
+
+/*
+ * intel_sst_probe - PCI probe function
+ *
+ * @pci:       PCI device structure
+ * @pci_id: PCI device ID structure
+ *
+ */
+static int intel_sst_probe(struct pci_dev *pci,
+                       const struct pci_device_id *pci_id)
+{
+       int ret = 0;
+       struct intel_sst_drv *sst_drv_ctx;
+       struct sst_platform_info *sst_pdata = pci->dev.platform_data;
+
+       dev_dbg(&pci->dev, "Probe for DID %x\n", pci->device);
+       ret = sst_alloc_drv_context(&sst_drv_ctx, &pci->dev, pci->device);
+       if (ret < 0)
+               return ret;
+
+       sst_drv_ctx->pdata = sst_pdata;
+       sst_drv_ctx->irq_num = pci->irq;
+       snprintf(sst_drv_ctx->firmware_name, sizeof(sst_drv_ctx->firmware_name),
+                       "%s%04x%s", "fw_sst_",
+                       sst_drv_ctx->dev_id, ".bin");
+
+       ret = sst_context_init(sst_drv_ctx);
+       if (ret < 0)
+               return ret;
+
+       /* Init the device */
+       ret = pcim_enable_device(pci);
+       if (ret) {
+               dev_err(sst_drv_ctx->dev,
+                       "device can't be enabled. Returned err: %d\n", ret);
+               goto do_free_drv_ctx;
+       }
+       sst_drv_ctx->pci = pci_dev_get(pci);
+       ret = sst_platform_get_resources(sst_drv_ctx);
+       if (ret < 0)
+               goto do_free_drv_ctx;
+
+       pci_set_drvdata(pci, sst_drv_ctx);
+       sst_configure_runtime_pm(sst_drv_ctx);
+
+       return ret;
+
+do_free_drv_ctx:
+       sst_context_cleanup(sst_drv_ctx);
+       dev_err(sst_drv_ctx->dev, "Probe failed with %d\n", ret);
+       return ret;
+}
+
+/**
+ * intel_sst_remove - PCI remove function
+ *
+ * @pci:       PCI device structure
+ *
+ * This function is called by OS when a device is unloaded
+ * This frees the interrupt etc
+ */
+static void intel_sst_remove(struct pci_dev *pci)
+{
+       struct intel_sst_drv *sst_drv_ctx = pci_get_drvdata(pci);
+
+       sst_context_cleanup(sst_drv_ctx);
+       pci_dev_put(sst_drv_ctx->pci);
+       pci_release_regions(pci);
+       pci_set_drvdata(pci, NULL);
+}
+
+/* PCI Routines */
+static struct pci_device_id intel_sst_ids[] = {
+       { PCI_VDEVICE(INTEL, SST_MRFLD_PCI_ID), 0},
+       { 0, }
+};
+
+static struct pci_driver sst_driver = {
+       .name = SST_DRV_NAME,
+       .id_table = intel_sst_ids,
+       .probe = intel_sst_probe,
+       .remove = intel_sst_remove,
+#ifdef CONFIG_PM
+       .driver = {
+               .pm = &intel_sst_pm,
+       },
+#endif
+};
+
+module_pci_driver(sst_driver);
+
+MODULE_DESCRIPTION("Intel (R) SST(R) Audio Engine PCI Driver");
+MODULE_AUTHOR("Vinod Koul <vinod.koul@intel.com>");
+MODULE_AUTHOR("Harsha Priya <priya.harsha@intel.com>");
+MODULE_AUTHOR("Dharageswari R <dharageswari.r@intel.com>");
+MODULE_AUTHOR("KP Jeeja <jeeja.kp@intel.com>");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("sst");
index 1c2e081fd813908217fa3874fc0b37862fe4c055..9a5df193651653fc5ba7a1813de319f2601fd206 100644 (file)
@@ -433,6 +433,7 @@ u32 relocate_imr_addr_mrfld(u32 base_addr)
        base_addr = MRFLD_FW_VIRTUAL_BASE + (base_addr % (512 * 1024 * 1024));
        return base_addr;
 }
+EXPORT_SYMBOL_GPL(relocate_imr_addr_mrfld);
 
 void sst_add_to_dispatch_list_and_post(struct intel_sst_drv *sst,
                                                struct ipc_post *msg)