aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSubhransu S. Prusty <subhransu.s.prusty@intel.com>2014-10-30 06:51:48 -0400
committerMark Brown <broonie@kernel.org>2014-10-31 12:57:32 -0400
commit250454d8fe65680b26f2917b806e2caf49126a01 (patch)
treec297bba913e1911fa8ae69bbecbfcabd6b6b3c45
parent2559d9928f36f3c0bfb4ded9bb47d47b36337b09 (diff)
ASoC: Intel: modularize driver probe and remove
The driver probe which initializes driver and remove which cleans up can be shared with APCI as well, so move them to common init_context and cleanup_context routines which can be used by ACPI as well 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>
-rw-r--r--sound/soc/intel/sst/sst.c165
1 files changed, 94 insertions, 71 deletions
diff --git a/sound/soc/intel/sst/sst.c b/sound/soc/intel/sst/sst.c
index 55bb1f7764f9..09d367aeaa15 100644
--- a/sound/soc/intel/sst/sst.c
+++ b/sound/soc/intel/sst/sst.c
@@ -243,6 +243,94 @@ int sst_alloc_drv_context(struct intel_sst_drv **ctx,
243 return 0; 243 return 0;
244} 244}
245 245
246int sst_context_init(struct intel_sst_drv *ctx)
247{
248 int ret = 0, i;
249
250 if (!ctx->pdata)
251 return -EINVAL;
252
253 if (!ctx->pdata->probe_data)
254 return -EINVAL;
255
256 memcpy(&ctx->info, ctx->pdata->probe_data, sizeof(ctx->info));
257
258 ret = sst_driver_ops(ctx);
259 if (ret != 0)
260 return -EINVAL;
261
262 sst_init_locks(ctx);
263
264 /* pvt_id 0 reserved for async messages */
265 ctx->pvt_id = 1;
266 ctx->stream_cnt = 0;
267 ctx->fw_in_mem = NULL;
268 /* we use memcpy, so set to 0 */
269 ctx->use_dma = 0;
270 ctx->use_lli = 0;
271
272 if (sst_workqueue_init(ctx))
273 return -EINVAL;
274
275 ctx->mailbox_recv_offset = ctx->pdata->ipc_info->mbox_recv_off;
276 ctx->ipc_reg.ipcx = SST_IPCX + ctx->pdata->ipc_info->ipc_offset;
277 ctx->ipc_reg.ipcd = SST_IPCD + ctx->pdata->ipc_info->ipc_offset;
278
279 dev_info(ctx->dev, "Got drv data max stream %d\n",
280 ctx->info.max_streams);
281
282 for (i = 1; i <= ctx->info.max_streams; i++) {
283 struct stream_info *stream = &ctx->streams[i];
284
285 memset(stream, 0, sizeof(*stream));
286 stream->pipe_id = PIPE_RSVD;
287 mutex_init(&stream->lock);
288 }
289
290 /* Register the ISR */
291 ret = devm_request_threaded_irq(ctx->dev, ctx->irq_num, ctx->ops->interrupt,
292 ctx->ops->irq_thread, 0, SST_DRV_NAME,
293 ctx);
294 if (ret)
295 goto do_free_mem;
296
297 dev_dbg(ctx->dev, "Registered IRQ %#x\n", ctx->irq_num);
298
299 /* default intr are unmasked so set this as masked */
300 sst_shim_write64(ctx->shim, SST_IMRX, 0xFFFF0038);
301
302 ctx->qos = devm_kzalloc(ctx->dev,
303 sizeof(struct pm_qos_request), GFP_KERNEL);
304 if (!ctx->qos) {
305 ret = -ENOMEM;
306 goto do_free_mem;
307 }
308 pm_qos_add_request(ctx->qos, PM_QOS_CPU_DMA_LATENCY,
309 PM_QOS_DEFAULT_VALUE);
310 return 0;
311
312do_free_mem:
313 destroy_workqueue(ctx->post_msg_wq);
314 return ret;
315}
316
317void sst_context_cleanup(struct intel_sst_drv *ctx)
318{
319 pm_runtime_get_noresume(ctx->dev);
320 pm_runtime_forbid(ctx->dev);
321 sst_unregister(ctx->dev);
322 sst_set_fw_state_locked(ctx, SST_SHUTDOWN);
323 flush_scheduled_work();
324 destroy_workqueue(ctx->post_msg_wq);
325 pm_qos_remove_request(ctx->qos);
326 kfree(ctx->fw_sg_list.src);
327 kfree(ctx->fw_sg_list.dst);
328 ctx->fw_sg_list.list_len = 0;
329 kfree(ctx->fw_in_mem);
330 ctx->fw_in_mem = NULL;
331 sst_memcpy_free_resources(ctx);
332 ctx = NULL;
333}
246 334
247/* 335/*
248* intel_sst_probe - PCI probe function 336* intel_sst_probe - PCI probe function
@@ -254,9 +342,8 @@ int sst_alloc_drv_context(struct intel_sst_drv **ctx,
254static int intel_sst_probe(struct pci_dev *pci, 342static int intel_sst_probe(struct pci_dev *pci,
255 const struct pci_device_id *pci_id) 343 const struct pci_device_id *pci_id)
256{ 344{
257 int i, ret = 0; 345 int ret = 0;
258 struct intel_sst_drv *sst_drv_ctx; 346 struct intel_sst_drv *sst_drv_ctx;
259 struct intel_sst_ops *ops;
260 struct sst_platform_info *sst_pdata = pci->dev.platform_data; 347 struct sst_platform_info *sst_pdata = pci->dev.platform_data;
261 int ddr_base; 348 int ddr_base;
262 349
@@ -266,43 +353,12 @@ static int intel_sst_probe(struct pci_dev *pci,
266 if (ret < 0) 353 if (ret < 0)
267 return ret; 354 return ret;
268 355
269 if (!sst_pdata)
270 return -EINVAL;
271
272 sst_drv_ctx->pdata = sst_pdata; 356 sst_drv_ctx->pdata = sst_pdata;
273 if (!sst_drv_ctx->pdata->probe_data)
274 return -EINVAL;
275
276 memcpy(&sst_drv_ctx->info, sst_drv_ctx->pdata->probe_data,
277 sizeof(sst_drv_ctx->info));
278
279 if (0 != sst_driver_ops(sst_drv_ctx))
280 return -EINVAL;
281
282 ops = sst_drv_ctx->ops;
283 sst_init_locks(sst_drv_ctx);
284
285 /* pvt_id 0 reserved for async messages */
286 sst_drv_ctx->pvt_id = 1;
287 sst_drv_ctx->stream_cnt = 0;
288 sst_drv_ctx->fw_in_mem = NULL;
289
290 /* we use memcpy, so set to 0 */
291 sst_drv_ctx->use_dma = 0;
292 sst_drv_ctx->use_lli = 0;
293
294 if (sst_workqueue_init(sst_drv_ctx))
295 return -EINVAL;
296 357
297 dev_info(sst_drv_ctx->dev, "Got drv data max stream %d\n", 358 ret = sst_context_init(sst_drv_ctx);
298 sst_drv_ctx->info.max_streams); 359 if (ret < 0)
299 for (i = 1; i <= sst_drv_ctx->info.max_streams; i++) { 360 goto do_free_drv_ctx;
300 struct stream_info *stream = &sst_drv_ctx->streams[i];
301 361
302 memset(stream, 0, sizeof(*stream));
303 stream->pipe_id = PIPE_RSVD;
304 mutex_init(&stream->lock);
305 }
306 362
307 /* Init the device */ 363 /* Init the device */
308 ret = pcim_enable_device(pci); 364 ret = pcim_enable_device(pci);
@@ -402,18 +458,6 @@ static int intel_sst_probe(struct pci_dev *pci,
402 } 458 }
403 459
404 sst_drv_ctx->irq_num = pci->irq; 460 sst_drv_ctx->irq_num = pci->irq;
405 /* Register the ISR */
406 ret = devm_request_threaded_irq(&pci->dev, pci->irq,
407 sst_drv_ctx->ops->interrupt,
408 sst_drv_ctx->ops->irq_thread, 0, SST_DRV_NAME,
409 sst_drv_ctx);
410 if (ret)
411 goto do_release_regions;
412 dev_dbg(sst_drv_ctx->dev, "Registered IRQ 0x%x\n", pci->irq);
413
414 /* default intr are unmasked so set this as masked */
415 if (sst_drv_ctx->dev_id == SST_MRFLD_PCI_ID)
416 sst_shim_write64(sst_drv_ctx->shim, SST_IMRX, 0xFFFF0038);
417 461
418 pci_set_drvdata(pci, sst_drv_ctx); 462 pci_set_drvdata(pci, sst_drv_ctx);
419 pm_runtime_set_autosuspend_delay(sst_drv_ctx->dev, SST_SUSPEND_DELAY); 463 pm_runtime_set_autosuspend_delay(sst_drv_ctx->dev, SST_SUSPEND_DELAY);
@@ -421,14 +465,6 @@ static int intel_sst_probe(struct pci_dev *pci,
421 pm_runtime_allow(sst_drv_ctx->dev); 465 pm_runtime_allow(sst_drv_ctx->dev);
422 pm_runtime_put_noidle(sst_drv_ctx->dev); 466 pm_runtime_put_noidle(sst_drv_ctx->dev);
423 sst_register(sst_drv_ctx->dev); 467 sst_register(sst_drv_ctx->dev);
424 sst_drv_ctx->qos = devm_kzalloc(&pci->dev,
425 sizeof(struct pm_qos_request), GFP_KERNEL);
426 if (!sst_drv_ctx->qos) {
427 ret = -ENOMEM;
428 goto do_release_regions;
429 }
430 pm_qos_add_request(sst_drv_ctx->qos, PM_QOS_CPU_DMA_LATENCY,
431 PM_QOS_DEFAULT_VALUE);
432 468
433 return ret; 469 return ret;
434 470
@@ -436,6 +472,7 @@ do_release_regions:
436 pci_release_regions(pci); 472 pci_release_regions(pci);
437do_free_mem: 473do_free_mem:
438 destroy_workqueue(sst_drv_ctx->post_msg_wq); 474 destroy_workqueue(sst_drv_ctx->post_msg_wq);
475do_free_drv_ctx:
439 dev_err(sst_drv_ctx->dev, "Probe failed with %d\n", ret); 476 dev_err(sst_drv_ctx->dev, "Probe failed with %d\n", ret);
440 return ret; 477 return ret;
441} 478}
@@ -452,22 +489,8 @@ static void intel_sst_remove(struct pci_dev *pci)
452{ 489{
453 struct intel_sst_drv *sst_drv_ctx = pci_get_drvdata(pci); 490 struct intel_sst_drv *sst_drv_ctx = pci_get_drvdata(pci);
454 491
455 pm_runtime_get_noresume(sst_drv_ctx->dev); 492 sst_context_cleanup(sst_drv_ctx);
456 pm_runtime_forbid(sst_drv_ctx->dev);
457 sst_unregister(sst_drv_ctx->dev);
458 pci_dev_put(sst_drv_ctx->pci); 493 pci_dev_put(sst_drv_ctx->pci);
459 sst_set_fw_state_locked(sst_drv_ctx, SST_SHUTDOWN);
460
461 flush_scheduled_work();
462 destroy_workqueue(sst_drv_ctx->post_msg_wq);
463 pm_qos_remove_request(sst_drv_ctx->qos);
464 kfree(sst_drv_ctx->fw_sg_list.src);
465 kfree(sst_drv_ctx->fw_sg_list.dst);
466 sst_drv_ctx->fw_sg_list.list_len = 0;
467 kfree(sst_drv_ctx->fw_in_mem);
468 sst_drv_ctx->fw_in_mem = NULL;
469 sst_memcpy_free_resources(sst_drv_ctx);
470 sst_drv_ctx = NULL;
471 pci_release_regions(pci); 494 pci_release_regions(pci);
472 pci_set_drvdata(pci, NULL); 495 pci_set_drvdata(pci, NULL);
473} 496}