-
Notifications
You must be signed in to change notification settings - Fork 144
SOF client support (auxiliary bus) #3007
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
a87a2b5
4d512ec
44b2a43
9115f5b
476d4c0
7274b1c
6a772ce
a858cfa
49abfdc
11f3b3a
20c9323
9e32894
bcaad35
92a48c2
9e675f2
deb5a0c
cba8df9
64a91b8
5f585a8
d6a888d
6677eec
68d6c63
39459f7
9e6b984
e8bab41
5c75bc5
b3089af
b269552
fd4a66c
5e3f492
f763eea
3bd20bb
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -95,6 +95,23 @@ void snd_sof_get_status(struct snd_sof_dev *sdev, u32 panic_code, | |
| } | ||
| EXPORT_SYMBOL(snd_sof_get_status); | ||
|
|
||
| /* Helper to manage DSP state */ | ||
| void sof_set_fw_state(struct snd_sof_dev *sdev, enum snd_sof_fw_state new_state) | ||
| { | ||
| sdev->fw_state = new_state; | ||
|
|
||
| switch (new_state) { | ||
| case SOF_FW_BOOT_NOT_STARTED: | ||
| case SOF_FW_BOOT_COMPLETE: | ||
| case SOF_FW_CRASHED: | ||
| sof_client_fw_state_dispatcher(sdev); | ||
| fallthrough; | ||
| default: | ||
| break; | ||
| } | ||
| } | ||
| EXPORT_SYMBOL(sof_set_fw_state); | ||
|
|
||
| /* | ||
| * FW Boot State Transition Diagram | ||
| * | ||
|
|
@@ -308,7 +325,6 @@ int snd_sof_device_probe(struct device *dev, struct snd_sof_pdata *plat_data) | |
|
|
||
| sdev->pdata = plat_data; | ||
| sdev->first_boot = true; | ||
| sof_set_fw_state(sdev, SOF_FW_BOOT_NOT_STARTED); | ||
| #if IS_ENABLED(CONFIG_SND_SOC_SOF_DEBUG_PROBES) | ||
| sdev->extractor_stream_tag = SOF_PROBE_INVALID_NODE_ID; | ||
| #endif | ||
|
|
@@ -330,10 +346,13 @@ int snd_sof_device_probe(struct device *dev, struct snd_sof_pdata *plat_data) | |
| INIT_LIST_HEAD(&sdev->dai_list); | ||
| INIT_LIST_HEAD(&sdev->route_list); | ||
| INIT_LIST_HEAD(&sdev->ipc_client_list); | ||
| INIT_LIST_HEAD(&sdev->ipc_rx_handler_list); | ||
| INIT_LIST_HEAD(&sdev->fw_state_handler_list); | ||
| spin_lock_init(&sdev->ipc_lock); | ||
| spin_lock_init(&sdev->hw_lock); | ||
| mutex_init(&sdev->power_state_access); | ||
| mutex_init(&sdev->ipc_client_mutex); | ||
| mutex_init(&sdev->client_event_handler_mutex); | ||
|
|
||
| /* set default timeouts if none provided */ | ||
| if (plat_data->desc->ipc_timeout == 0) | ||
|
|
@@ -345,6 +364,8 @@ int snd_sof_device_probe(struct device *dev, struct snd_sof_pdata *plat_data) | |
| else | ||
| sdev->boot_timeout = plat_data->desc->boot_timeout; | ||
|
|
||
| sof_set_fw_state(sdev, SOF_FW_BOOT_NOT_STARTED); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. squash this change in previous patch?
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The main reason for moving this is the introduction of the notification for clients which uses |
||
|
|
||
| if (IS_ENABLED(CONFIG_SND_SOC_SOF_PROBE_WORK_QUEUE)) { | ||
| INIT_WORK(&sdev->probe_work, sof_probe_work); | ||
| schedule_work(&sdev->probe_work); | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -463,21 +463,25 @@ void snd_sof_ipc_msgs_rx(struct snd_sof_dev *sdev) | |
| break; | ||
| } | ||
|
|
||
| if (rx_callback) { | ||
| /* read the full message as there we have rx handler for it */ | ||
| full_msg = kmalloc(hdr.size, GFP_KERNEL); | ||
| if (!full_msg) | ||
| return; | ||
| /* read the full message as there we have rx handler for it */ | ||
| full_msg = kmalloc(hdr.size, GFP_KERNEL); | ||
| if (!full_msg) | ||
| return; | ||
|
|
||
| err = snd_sof_ipc_msg_data(sdev, NULL, full_msg, hdr.size); | ||
| if (err < 0) | ||
| dev_err(sdev->dev, "failed to read message\n"); | ||
| else | ||
| err = snd_sof_ipc_msg_data(sdev, NULL, full_msg, hdr.size); | ||
| if (err < 0) { | ||
| dev_err(sdev->dev, "failed to read message\n"); | ||
| } else { | ||
| /* Call local handler for the message */ | ||
| if (rx_callback) | ||
| rx_callback(sdev, full_msg); | ||
|
|
||
| kfree(full_msg); | ||
| /* Notify registered clients */ | ||
| sof_client_ipc_rx_dispatcher(sdev, full_msg); | ||
| } | ||
|
|
||
| kfree(full_msg); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't get why you are transposing the logic by doing ipc_msg_data() and then testing the callback.
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Before this patch I only allocated memory for the full_msg and retrieved the message from firmware if we had a handler for it. True, that it is unlikely, but it sounded the right thing to do. I could have done it with goto like this: + if (!rx_callback)
+ goto out;
+ /* read the full message as there we have rx handler for it */
+ full_msg = kmalloc(hdr.size, GFP_KERNEL);
+ if (!full_msg)
+ return;
+ err = snd_sof_ipc_msg_data(sdev, NULL, full_msg, hdr.size);
+ if (err < 0)
+ dev_err(sdev->dev, "failed to read message\n");
+ else
+ rx_callback(sdev, full_msg);
+ kfree(full_msg);
+ out:
ipc_log_header(sdev->dev, "ipc rx done", hdr.cmd);if you prefer that. Here we always need to allocate the full_msg as we don't know if there is a client waiting for the exact notification. |
||
|
|
||
| ipc_log_header(sdev->dev, "ipc rx done", hdr.cmd); | ||
| } | ||
| EXPORT_SYMBOL(snd_sof_ipc_msgs_rx); | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.