Skip to content

Commit d811f9f

Browse files
ujfalusiplbossart
authored andcommitted
ASoC: SOF: ipc3-dtrace: Move dtrace related variables local from sof_dev
The variables and structs for DMA trace can be moved local to ipc3-dtrace.c and the storage can be allocated dynamically, stored behind the fw_trace_data pointer. Signed-off-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
1 parent 8a89c99 commit d811f9f

2 files changed

Lines changed: 93 additions & 65 deletions

File tree

sound/soc/sof/ipc3-dtrace.c

Lines changed: 93 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,23 @@
1515
#define TRACE_FILTER_ELEMENTS_PER_ENTRY 4
1616
#define TRACE_FILTER_MAX_CONFIG_STRING_LENGTH 1024
1717

18+
enum sof_dtrace_state {
19+
SOF_DTRACE_DISABLED,
20+
SOF_DTRACE_STOPPED,
21+
SOF_DTRACE_ENABLED,
22+
};
23+
24+
struct sof_dtrace_priv {
25+
struct snd_dma_buffer dmatb;
26+
struct snd_dma_buffer dmatp;
27+
int dma_trace_pages;
28+
wait_queue_head_t trace_sleep;
29+
u32 host_offset;
30+
bool dtrace_error;
31+
bool dtrace_draining;
32+
enum sof_dtrace_state dtrace_state;
33+
};
34+
1835
static int trace_filter_append_elem(struct snd_sof_dev *sdev, u32 key, u32 value,
1936
struct sof_ipc_trace_filter_elem *elem_list,
2037
int capacity, int *counter)
@@ -227,7 +244,8 @@ static int debugfs_create_trace_filter(struct snd_sof_dev *sdev)
227244
static size_t sof_dtrace_avail(struct snd_sof_dev *sdev,
228245
loff_t pos, size_t buffer_size)
229246
{
230-
loff_t host_offset = READ_ONCE(sdev->host_offset);
247+
struct sof_dtrace_priv *priv = sdev->fw_trace_data;
248+
loff_t host_offset = READ_ONCE(priv->host_offset);
231249

232250
/*
233251
* If host offset is less than local pos, it means write pointer of
@@ -247,32 +265,33 @@ static size_t sof_dtrace_avail(struct snd_sof_dev *sdev,
247265
static size_t sof_wait_dtrace_avail(struct snd_sof_dev *sdev, loff_t pos,
248266
size_t buffer_size)
249267
{
250-
wait_queue_entry_t wait;
251268
size_t ret = sof_dtrace_avail(sdev, pos, buffer_size);
269+
struct sof_dtrace_priv *priv = sdev->fw_trace_data;
270+
wait_queue_entry_t wait;
252271

253272
/* data immediately available */
254273
if (ret)
255274
return ret;
256275

257-
if (sdev->dtrace_state != SOF_DTRACE_ENABLED && sdev->dtrace_draining) {
276+
if (priv->dtrace_state != SOF_DTRACE_ENABLED && priv->dtrace_draining) {
258277
/*
259278
* tracing has ended and all traces have been
260279
* read by client, return EOF
261280
*/
262-
sdev->dtrace_draining = false;
281+
priv->dtrace_draining = false;
263282
return 0;
264283
}
265284

266285
/* wait for available trace data from FW */
267286
init_waitqueue_entry(&wait, current);
268287
set_current_state(TASK_INTERRUPTIBLE);
269-
add_wait_queue(&sdev->trace_sleep, &wait);
288+
add_wait_queue(&priv->trace_sleep, &wait);
270289

271290
if (!signal_pending(current)) {
272291
/* set timeout to max value, no error code */
273292
schedule_timeout(MAX_SCHEDULE_TIMEOUT);
274293
}
275-
remove_wait_queue(&sdev->trace_sleep, &wait);
294+
remove_wait_queue(&priv->trace_sleep, &wait);
276295

277296
return sof_dtrace_avail(sdev, pos, buffer_size);
278297
}
@@ -282,13 +301,14 @@ static ssize_t dfsentry_dtrace_read(struct file *file, char __user *buffer,
282301
{
283302
struct snd_sof_dfsentry *dfse = file->private_data;
284303
struct snd_sof_dev *sdev = dfse->sdev;
304+
struct sof_dtrace_priv *priv = sdev->fw_trace_data;
285305
unsigned long rem;
286306
loff_t lpos = *ppos;
287307
size_t avail, buffer_size = dfse->size;
288308
u64 lpos_64;
289309

290310
/* make sure we know about any failures on the DSP side */
291-
sdev->dtrace_error = false;
311+
priv->dtrace_error = false;
292312

293313
/* check pos and count */
294314
if (lpos < 0)
@@ -302,7 +322,7 @@ static ssize_t dfsentry_dtrace_read(struct file *file, char __user *buffer,
302322

303323
/* get available count based on current host offset */
304324
avail = sof_wait_dtrace_avail(sdev, lpos, buffer_size);
305-
if (sdev->dtrace_error) {
325+
if (priv->dtrace_error) {
306326
dev_err(sdev->dev, "trace IO error\n");
307327
return -EIO;
308328
}
@@ -317,7 +337,7 @@ static ssize_t dfsentry_dtrace_read(struct file *file, char __user *buffer,
317337
* Note: snd_dma_buffer_sync() is called for normal audio playback and
318338
* capture streams also.
319339
*/
320-
snd_dma_buffer_sync(&sdev->dmatb, SNDRV_DMA_SYNC_CPU);
340+
snd_dma_buffer_sync(&priv->dmatb, SNDRV_DMA_SYNC_CPU);
321341
/* copy available trace data to debugfs */
322342
rem = copy_to_user(buffer, ((u8 *)(dfse->buf) + lpos), count);
323343
if (rem)
@@ -333,10 +353,11 @@ static int dfsentry_dtrace_release(struct inode *inode, struct file *file)
333353
{
334354
struct snd_sof_dfsentry *dfse = inode->i_private;
335355
struct snd_sof_dev *sdev = dfse->sdev;
356+
struct sof_dtrace_priv *priv = sdev->fw_trace_data;
336357

337358
/* avoid duplicate traces at next open */
338-
if (sdev->dtrace_state != SOF_DTRACE_ENABLED)
339-
sdev->host_offset = 0;
359+
if (priv->dtrace_state != SOF_DTRACE_ENABLED)
360+
priv->host_offset = 0;
340361

341362
return 0;
342363
}
@@ -350,12 +371,15 @@ static const struct file_operations sof_dfs_dtrace_fops = {
350371

351372
static int debugfs_create_dtrace(struct snd_sof_dev *sdev)
352373
{
374+
struct sof_dtrace_priv *priv;
353375
struct snd_sof_dfsentry *dfse;
354376
int ret;
355377

356378
if (!sdev)
357379
return -EINVAL;
358380

381+
priv = sdev->fw_trace_data;
382+
359383
ret = debugfs_create_trace_filter(sdev);
360384
if (ret < 0)
361385
dev_warn(sdev->dev, "failed to create filter debugfs file: %d", ret);
@@ -365,8 +389,8 @@ static int debugfs_create_dtrace(struct snd_sof_dev *sdev)
365389
return -ENOMEM;
366390

367391
dfse->type = SOF_DFSENTRY_TYPE_BUF;
368-
dfse->buf = sdev->dmatb.area;
369-
dfse->size = sdev->dmatb.bytes;
392+
dfse->buf = priv->dmatb.area;
393+
dfse->size = priv->dmatb.bytes;
370394
dfse->sdev = sdev;
371395

372396
debugfs_create_file("trace", 0444, sdev->debugfs_root, dfse,
@@ -377,6 +401,7 @@ static int debugfs_create_dtrace(struct snd_sof_dev *sdev)
377401

378402
static int ipc3_dtrace_enable(struct snd_sof_dev *sdev)
379403
{
404+
struct sof_dtrace_priv *priv = sdev->fw_trace_data;
380405
struct sof_ipc_fw_ready *ready = &sdev->fw_ready;
381406
struct sof_ipc_fw_version *v = &ready->version;
382407
struct sof_ipc_dma_trace_params_ext params;
@@ -386,10 +411,10 @@ static int ipc3_dtrace_enable(struct snd_sof_dev *sdev)
386411
if (!sdev->fw_trace_is_supported)
387412
return 0;
388413

389-
if (sdev->dtrace_state == SOF_DTRACE_ENABLED || !sdev->dma_trace_pages)
414+
if (priv->dtrace_state == SOF_DTRACE_ENABLED || !priv->dma_trace_pages)
390415
return -EINVAL;
391416

392-
if (sdev->dtrace_state == SOF_DTRACE_STOPPED)
417+
if (priv->dtrace_state == SOF_DTRACE_STOPPED)
393418
goto start;
394419

395420
/* set IPC parameters */
@@ -403,15 +428,15 @@ static int ipc3_dtrace_enable(struct snd_sof_dev *sdev)
403428
params.hdr.size = sizeof(struct sof_ipc_dma_trace_params);
404429
params.hdr.cmd |= SOF_IPC_TRACE_DMA_PARAMS;
405430
}
406-
params.buffer.phy_addr = sdev->dmatp.addr;
407-
params.buffer.size = sdev->dmatb.bytes;
408-
params.buffer.pages = sdev->dma_trace_pages;
431+
params.buffer.phy_addr = priv->dmatp.addr;
432+
params.buffer.size = priv->dmatb.bytes;
433+
params.buffer.pages = priv->dma_trace_pages;
409434
params.stream_tag = 0;
410435

411-
sdev->host_offset = 0;
412-
sdev->dtrace_draining = false;
436+
priv->host_offset = 0;
437+
priv->dtrace_draining = false;
413438

414-
ret = sof_dtrace_host_init(sdev, &sdev->dmatb, &params);
439+
ret = sof_dtrace_host_init(sdev, &priv->dmatb, &params);
415440
if (ret < 0) {
416441
dev_err(sdev->dev, "Host dtrace init failed: %d\n", ret);
417442
return ret;
@@ -432,7 +457,7 @@ static int ipc3_dtrace_enable(struct snd_sof_dev *sdev)
432457
goto trace_release;
433458
}
434459

435-
sdev->dtrace_state = SOF_DTRACE_ENABLED;
460+
priv->dtrace_state = SOF_DTRACE_ENABLED;
436461

437462
return 0;
438463

@@ -443,18 +468,30 @@ static int ipc3_dtrace_enable(struct snd_sof_dev *sdev)
443468

444469
static int ipc3_dtrace_init(struct snd_sof_dev *sdev)
445470
{
471+
struct sof_dtrace_priv *priv;
446472
int ret;
447473

448474
/* dtrace is only supported with SOF_IPC */
449475
if (sdev->pdata->ipc_type != SOF_IPC)
450476
return -EOPNOTSUPP;
451477

478+
if (sdev->fw_trace_data) {
479+
dev_err(sdev->dev, "fw_trace_data has been already allocated\n");
480+
return -EBUSY;
481+
}
482+
483+
priv = devm_kzalloc(sdev->dev, sizeof(*priv), GFP_KERNEL);
484+
if (!priv)
485+
return -ENOMEM;
486+
487+
sdev->fw_trace_data = priv;
488+
452489
/* set false before start initialization */
453-
sdev->dtrace_state = SOF_DTRACE_DISABLED;
490+
priv->dtrace_state = SOF_DTRACE_DISABLED;
454491

455492
/* allocate trace page table buffer */
456493
ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, sdev->dev,
457-
PAGE_SIZE, &sdev->dmatp);
494+
PAGE_SIZE, &priv->dmatp);
458495
if (ret < 0) {
459496
dev_err(sdev->dev, "can't alloc page table for trace %d\n", ret);
460497
return ret;
@@ -463,53 +500,55 @@ static int ipc3_dtrace_init(struct snd_sof_dev *sdev)
463500
/* allocate trace data buffer */
464501
ret = snd_dma_alloc_dir_pages(SNDRV_DMA_TYPE_DEV_SG, sdev->dev,
465502
DMA_FROM_DEVICE, DMA_BUF_SIZE_FOR_TRACE,
466-
&sdev->dmatb);
503+
&priv->dmatb);
467504
if (ret < 0) {
468505
dev_err(sdev->dev, "can't alloc buffer for trace %d\n", ret);
469506
goto page_err;
470507
}
471508

472509
/* create compressed page table for audio firmware */
473-
ret = snd_sof_create_page_table(sdev->dev, &sdev->dmatb,
474-
sdev->dmatp.area, sdev->dmatb.bytes);
510+
ret = snd_sof_create_page_table(sdev->dev, &priv->dmatb,
511+
priv->dmatp.area, priv->dmatb.bytes);
475512
if (ret < 0)
476513
goto table_err;
477514

478-
sdev->dma_trace_pages = ret;
515+
priv->dma_trace_pages = ret;
479516
dev_dbg(sdev->dev, "%s: dma_trace_pages: %d\n", __func__,
480-
sdev->dma_trace_pages);
517+
priv->dma_trace_pages);
481518

482519
if (sdev->first_boot) {
483520
ret = debugfs_create_dtrace(sdev);
484521
if (ret < 0)
485522
goto table_err;
486523
}
487524

488-
init_waitqueue_head(&sdev->trace_sleep);
525+
init_waitqueue_head(&priv->trace_sleep);
489526

490527
ret = ipc3_dtrace_enable(sdev);
491528
if (ret < 0)
492529
goto table_err;
493530

494531
return 0;
495532
table_err:
496-
sdev->dma_trace_pages = 0;
497-
snd_dma_free_pages(&sdev->dmatb);
533+
priv->dma_trace_pages = 0;
534+
snd_dma_free_pages(&priv->dmatb);
498535
page_err:
499-
snd_dma_free_pages(&sdev->dmatp);
536+
snd_dma_free_pages(&priv->dmatp);
500537
return ret;
501538
}
502539

503540
int ipc3_dtrace_posn_update(struct snd_sof_dev *sdev,
504541
struct sof_ipc_dma_trace_posn *posn)
505542
{
543+
struct sof_dtrace_priv *priv = sdev->fw_trace_data;
544+
506545
if (!sdev->fw_trace_is_supported)
507546
return 0;
508547

509-
if (sdev->dtrace_state == SOF_DTRACE_ENABLED &&
510-
sdev->host_offset != posn->host_offset) {
511-
sdev->host_offset = posn->host_offset;
512-
wake_up(&sdev->trace_sleep);
548+
if (priv->dtrace_state == SOF_DTRACE_ENABLED &&
549+
priv->host_offset != posn->host_offset) {
550+
priv->host_offset = posn->host_offset;
551+
wake_up(&priv->trace_sleep);
513552
}
514553

515554
if (posn->overflow != 0)
@@ -523,27 +562,30 @@ int ipc3_dtrace_posn_update(struct snd_sof_dev *sdev,
523562
/* an error has occurred within the DSP that prevents further trace */
524563
static void ipc3_dtrace_fw_crashed(struct snd_sof_dev *sdev)
525564
{
526-
if (sdev->dtrace_state == SOF_DTRACE_ENABLED) {
527-
sdev->dtrace_error = true;
528-
wake_up(&sdev->trace_sleep);
565+
struct sof_dtrace_priv *priv = sdev->fw_trace_data;
566+
567+
if (priv->dtrace_state == SOF_DTRACE_ENABLED) {
568+
priv->dtrace_error = true;
569+
wake_up(&priv->trace_sleep);
529570
}
530571
}
531572

532573
static void ipc3_dtrace_release(struct snd_sof_dev *sdev, bool only_stop)
533574
{
575+
struct sof_dtrace_priv *priv = sdev->fw_trace_data;
534576
struct sof_ipc_fw_ready *ready = &sdev->fw_ready;
535577
struct sof_ipc_fw_version *v = &ready->version;
536578
struct sof_ipc_cmd_hdr hdr;
537579
struct sof_ipc_reply ipc_reply;
538580
int ret;
539581

540-
if (!sdev->fw_trace_is_supported || sdev->dtrace_state == SOF_DTRACE_DISABLED)
582+
if (!sdev->fw_trace_is_supported || priv->dtrace_state == SOF_DTRACE_DISABLED)
541583
return;
542584

543585
ret = sof_dtrace_host_trigger(sdev, SNDRV_PCM_TRIGGER_STOP);
544586
if (ret < 0)
545587
dev_err(sdev->dev, "Host dtrace trigger stop failed: %d\n", ret);
546-
sdev->dtrace_state = SOF_DTRACE_STOPPED;
588+
priv->dtrace_state = SOF_DTRACE_STOPPED;
547589

548590
/*
549591
* stop and free trace DMA in the DSP. TRACE_DMA_FREE is only supported from
@@ -566,11 +608,11 @@ static void ipc3_dtrace_release(struct snd_sof_dev *sdev, bool only_stop)
566608
if (ret < 0)
567609
dev_err(sdev->dev, "Host dtrace release failed %d\n", ret);
568610

569-
sdev->dtrace_state = SOF_DTRACE_DISABLED;
611+
priv->dtrace_state = SOF_DTRACE_DISABLED;
570612

571613
out:
572-
sdev->dtrace_draining = true;
573-
wake_up(&sdev->trace_sleep);
614+
priv->dtrace_draining = true;
615+
wake_up(&priv->trace_sleep);
574616
}
575617

576618
static void ipc3_dtrace_suspend(struct snd_sof_dev *sdev, pm_message_t pm_state)
@@ -585,13 +627,15 @@ static int ipc3_dtrace_resume(struct snd_sof_dev *sdev)
585627

586628
static void ipc3_dtrace_free(struct snd_sof_dev *sdev)
587629
{
630+
struct sof_dtrace_priv *priv = sdev->fw_trace_data;
631+
588632
/* release trace */
589633
ipc3_dtrace_release(sdev, false);
590634

591-
if (sdev->dma_trace_pages) {
592-
snd_dma_free_pages(&sdev->dmatb);
593-
snd_dma_free_pages(&sdev->dmatp);
594-
sdev->dma_trace_pages = 0;
635+
if (priv->dma_trace_pages) {
636+
snd_dma_free_pages(&priv->dmatb);
637+
snd_dma_free_pages(&priv->dmatp);
638+
priv->dma_trace_pages = 0;
595639
}
596640
}
597641

0 commit comments

Comments
 (0)