idc: add idc_restore

Restores idc interrupt if all is ready

Signed-off-by: Adrian Bonislawski <adrian.bonislawski@intel.com>
This commit is contained in:
Adrian Bonislawski 2021-09-21 08:37:09 +02:00 committed by Liam Girdwood
parent e62855935d
commit b87352c754
5 changed files with 62 additions and 0 deletions

View File

@ -243,6 +243,39 @@ int platform_idc_init(void)
return 0; return 0;
} }
/**
* \brief Restores IDC interrupt. During D0->D0ix/D0ix->D0 flow primary core
* disables all secondary cores - this is not cold boot process, because
* memory has not been powered off. In that case, we should only enable
* idc interrupts, because all required structures alreade exist.
*/
int platform_idc_restore(void)
{
struct idc *idc = *idc_get();
int core = cpu_get_id();
int ret;
idc->irq = interrupt_get_irq(PLATFORM_IDC_INTERRUPT,
PLATFORM_IDC_INTERRUPT_NAME);
if (idc->irq < 0) {
tr_err(&idc_tr, "platform_idc_restore(): getting irq failed.");
return idc->irq;
}
ret = interrupt_register(idc->irq, idc_irq_handler, idc);
if (ret < 0) {
tr_err(&idc_tr, "platform_idc_restore(): registering irq failed.");
return ret;
}
interrupt_enable(idc->irq, idc);
/* enable BUSY interrupt */
idc_write(IPC_IDCCTL, core, idc->busy_bit_mask);
return 0;
}
/** /**
* \brief Frees IDC data and unregisters interrupt. * \brief Frees IDC data and unregisters interrupt.
*/ */

View File

@ -352,3 +352,23 @@ int idc_init(void)
return 0; return 0;
#endif #endif
} }
int idc_restore(void)
{
struct idc **idc = idc_get();
tr_info(&idc_tr, "idc_restore()");
/* idc_restore() is invoked during D0->D0ix/D0ix->D0 flow. In that
* case basic core structures e.g. idc struct should be already
* allocated (in D0->D0ix primary core disables all secondary cores, but
* memory has not been powered off).
*/
assert(*idc);
#ifndef __ZEPHYR__
return platform_idc_restore();
#endif
return 0;
}

View File

@ -132,6 +132,8 @@ void idc_free(void);
int platform_idc_init(void); int platform_idc_init(void);
int platform_idc_restore(void);
enum task_state idc_do_cmd(void *data); enum task_state idc_do_cmd(void *data);
void idc_cmd(struct idc_msg *msg); void idc_cmd(struct idc_msg *msg);

View File

@ -20,6 +20,8 @@ int idc_send_msg(struct idc_msg *msg, uint32_t mode);
int idc_init(void); int idc_init(void);
int idc_restore(void);
#else #else
static inline int idc_send_msg(struct idc_msg *msg, uint32_t mode) { return 0; } static inline int idc_send_msg(struct idc_msg *msg, uint32_t mode) { return 0; }

View File

@ -28,6 +28,11 @@ static inline int idc_init(void)
return 0; return 0;
} }
static inline int idc_restore(void)
{
return 0;
}
#endif /* __PLATFORM_DRIVERS_IDC_H__ */ #endif /* __PLATFORM_DRIVERS_IDC_H__ */
#else #else