-
Notifications
You must be signed in to change notification settings - Fork 140
ASoC: SOF: Intel: BYT: refine the IPC interrupt handling #1490
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 all commits
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 |
|---|---|---|
|
|
@@ -184,13 +184,31 @@ static void byt_dump(struct snd_sof_dev *sdev, u32 flags) | |
| static irqreturn_t byt_irq_handler(int irq, void *context) | ||
| { | ||
| struct snd_sof_dev *sdev = context; | ||
| u64 ipcx, ipcd; | ||
| u64 isr; | ||
| int ret = IRQ_NONE; | ||
|
|
||
| /* Interrupt arrived, check src */ | ||
| isr = snd_sof_dsp_read64(sdev, BYT_DSP_BAR, SHIM_ISRX); | ||
| if (isr & (SHIM_ISRX_DONE | SHIM_ISRX_BUSY)) | ||
| ipcx = snd_sof_dsp_read64(sdev, BYT_DSP_BAR, SHIM_IPCX); | ||
| ipcd = snd_sof_dsp_read64(sdev, BYT_DSP_BAR, SHIM_IPCD); | ||
|
|
||
| if ((isr & SHIM_ISRX_DONE) && (ipcx & SHIM_BYT_IPCX_DONE)) { | ||
| /* reply message from DSP, Mask Done interrupt first */ | ||
| snd_sof_dsp_update_bits64_unlocked(sdev, BYT_DSP_BAR, | ||
| SHIM_IMRX, | ||
| SHIM_IMRX_DONE, | ||
| SHIM_IMRX_DONE); | ||
| ret = IRQ_WAKE_THREAD; | ||
| } | ||
|
|
||
| if ((isr & SHIM_ISRX_BUSY) && (ipcd & SHIM_BYT_IPCD_BUSY)) { | ||
| /* new message from DSP, Mask Busy interrupt first */ | ||
| snd_sof_dsp_update_bits64_unlocked(sdev, BYT_DSP_BAR, | ||
| SHIM_IMRX, | ||
| SHIM_IMRX_BUSY, | ||
| SHIM_IMRX_BUSY); | ||
| ret = IRQ_WAKE_THREAD; | ||
| } | ||
|
|
||
| return ret; | ||
| } | ||
|
|
@@ -203,16 +221,11 @@ static irqreturn_t byt_irq_thread(int irq, void *context) | |
|
|
||
| imrx = snd_sof_dsp_read64(sdev, BYT_DSP_BAR, SHIM_IMRX); | ||
| ipcx = snd_sof_dsp_read64(sdev, BYT_DSP_BAR, SHIM_IPCX); | ||
| ipcd = snd_sof_dsp_read64(sdev, BYT_DSP_BAR, SHIM_IPCD); | ||
|
|
||
| /* reply message from DSP */ | ||
| if (ipcx & SHIM_BYT_IPCX_DONE && | ||
| !(imrx & SHIM_IMRX_DONE)) { | ||
| /* Mask Done interrupt before first */ | ||
| snd_sof_dsp_update_bits64_unlocked(sdev, BYT_DSP_BAR, | ||
| SHIM_IMRX, | ||
| SHIM_IMRX_DONE, | ||
| SHIM_IMRX_DONE); | ||
|
|
||
| if ((ipcx & SHIM_BYT_IPCX_DONE) && | ||
| (imrx & SHIM_IMRX_DONE)) { | ||
|
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. why are you changing this? |
||
| spin_lock_irq(&sdev->ipc_lock); | ||
|
|
||
| /* | ||
|
|
@@ -231,15 +244,8 @@ static irqreturn_t byt_irq_thread(int irq, void *context) | |
| } | ||
|
|
||
| /* new message from DSP */ | ||
| ipcd = snd_sof_dsp_read64(sdev, BYT_DSP_BAR, SHIM_IPCD); | ||
| if (ipcd & SHIM_BYT_IPCD_BUSY && | ||
| !(imrx & SHIM_IMRX_BUSY)) { | ||
| /* Mask Busy interrupt before return */ | ||
| snd_sof_dsp_update_bits64_unlocked(sdev, BYT_DSP_BAR, | ||
| SHIM_IMRX, | ||
| SHIM_IMRX_BUSY, | ||
| SHIM_IMRX_BUSY); | ||
|
|
||
| if ((ipcd & SHIM_BYT_IPCD_BUSY) && | ||
| (imrx & SHIM_IMRX_BUSY)) { | ||
|
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. why are you changing this?
Collaborator
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. @keyonjie I get the rationale for masking the IPC's before waking the thread but you did not answer @plbossart 's question about why you are changing this. In my opinion, this check for imrx & SHIM_IMRX_BUSY or imrx & SHIM_IMRX_DONE in the thread is meaningless. You would never get to the thread if they werent true with your changes. |
||
| /* Handle messages from DSP Core */ | ||
| if ((ipcd & SOF_IPC_PANIC_MAGIC_MASK) == SOF_IPC_PANIC_MAGIC) { | ||
| snd_sof_dsp_panic(sdev, BYT_PANIC_OFFSET(ipcd) + | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not touching this PR without a document explaining the ideas.