Loading include/sound/wcd-dsp-mgr.h +12 −6 Original line number Diff line number Diff line Loading @@ -65,9 +65,14 @@ enum wdsp_event_type { WDSP_EVENT_RESUME, }; enum wdsp_intr { enum wdsp_signal { /* Hardware generated interrupts signalled to manager */ WDSP_IPC1_INTR, WDSP_ERR_INTR, /* Other signals */ WDSP_CDC_DOWN_SIGNAL, WDSP_CDC_UP_SIGNAL, }; /* Loading @@ -92,7 +97,7 @@ struct wdsp_img_section { u8 *data; }; struct wdsp_err_intr_arg { struct wdsp_err_signal_arg { bool mem_dumps_enabled; u32 remote_start_addr; size_t dump_size; Loading @@ -104,8 +109,9 @@ struct wdsp_err_intr_arg { * their own ops to manager driver * @get_dev_for_cmpnt: components can use this to get handle * to struct device * of any other component * @intr_handler: callback to notify manager driver that interrupt * has occurred. * @signal_handler: callback to notify manager driver that signal * has occurred. Cannot be called from interrupt * context as this can sleep * @vote_for_dsp: notifies manager that dsp should be booted up * @suspend: notifies manager that one component wants to suspend. * Manager will make sure to suspend all components in order Loading @@ -120,8 +126,8 @@ struct wdsp_mgr_ops { struct wdsp_cmpnt_ops *ops); struct device *(*get_dev_for_cmpnt)(struct device *wdsp_dev, enum wdsp_cmpnt_type type); int (*intr_handler)(struct device *wdsp_dev, enum wdsp_intr intr, void *arg); int (*signal_handler)(struct device *wdsp_dev, enum wdsp_signal signal, void *arg); int (*vote_for_dsp)(struct device *wdsp_dev, bool vote); int (*suspend)(struct device *wdsp_dev); int (*resume)(struct device *wdsp_dev); Loading sound/soc/codecs/wcd-dsp-mgr.c +42 −20 Original line number Diff line number Diff line Loading @@ -136,7 +136,7 @@ struct wdsp_ramdump_data { void *rd_v_addr; /* Data provided through error interrupt */ struct wdsp_err_intr_arg err_data; struct wdsp_err_signal_arg err_data; }; struct wdsp_mgr_priv { Loading Loading @@ -608,7 +608,7 @@ static struct device *wdsp_get_dev_for_cmpnt(struct device *wdsp_dev, static void wdsp_collect_ramdumps(struct wdsp_mgr_priv *wdsp) { struct wdsp_img_section img_section; struct wdsp_err_intr_arg *data = &wdsp->dump_data.err_data; struct wdsp_err_signal_arg *data = &wdsp->dump_data.err_data; struct ramdump_segment rd_seg; int ret = 0; Loading Loading @@ -684,17 +684,18 @@ static void wdsp_ssr_work_fn(struct work_struct *work) WDSP_MGR_MUTEX_LOCK(wdsp, wdsp->ssr_mutex); /* Issue ramdumps and shutdown only if DSP is currently booted */ if (WDSP_STATUS_IS_SET(wdsp, WDSP_STATUS_BOOTED)) { wdsp_collect_ramdumps(wdsp); /* In case of CDC_DOWN event, the DSP is already shutdown */ if (wdsp->ssr_type != WDSP_SSR_TYPE_CDC_DOWN) { ret = wdsp_unicast_event(wdsp, WDSP_CMPNT_CONTROL, WDSP_EVENT_DO_SHUTDOWN, NULL); if (IS_ERR_VALUE(ret)) WDSP_ERR(wdsp, "Failed WDSP shutdown, err = %d", ret); } wdsp_broadcast_event_downseq(wdsp, WDSP_EVENT_POST_SHUTDOWN, NULL); wdsp_broadcast_event_downseq(wdsp, WDSP_EVENT_POST_SHUTDOWN, NULL); WDSP_CLEAR_STATUS(wdsp, WDSP_STATUS_BOOTED); } WDSP_MGR_MUTEX_UNLOCK(wdsp, wdsp->ssr_mutex); ret = wait_for_completion_timeout(&wdsp->ready_compl, Loading Loading @@ -739,7 +740,7 @@ static int wdsp_ssr_handler(struct wdsp_mgr_priv *wdsp, void *arg, enum wdsp_ssr_type ssr_type) { enum wdsp_ssr_type current_ssr_type; struct wdsp_err_intr_arg *err_data; struct wdsp_err_signal_arg *err_data; WDSP_MGR_MUTEX_LOCK(wdsp, wdsp->ssr_mutex); Loading @@ -750,7 +751,7 @@ static int wdsp_ssr_handler(struct wdsp_mgr_priv *wdsp, void *arg, wdsp->ssr_type = ssr_type; if (arg) { err_data = (struct wdsp_err_intr_arg *) arg; err_data = (struct wdsp_err_signal_arg *) arg; memcpy(&wdsp->dump_data.err_data, err_data, sizeof(*err_data)); } else { Loading @@ -761,16 +762,29 @@ static int wdsp_ssr_handler(struct wdsp_mgr_priv *wdsp, void *arg, switch (ssr_type) { case WDSP_SSR_TYPE_WDSP_DOWN: case WDSP_SSR_TYPE_CDC_DOWN: __wdsp_clr_ready_locked(wdsp, WDSP_SSR_STATUS_WDSP_READY); if (ssr_type == WDSP_SSR_TYPE_CDC_DOWN) __wdsp_clr_ready_locked(wdsp, WDSP_SSR_STATUS_CDC_READY); wdsp_broadcast_event_downseq(wdsp, WDSP_EVENT_PRE_SHUTDOWN, NULL); schedule_work(&wdsp->ssr_work); break; case WDSP_SSR_TYPE_CDC_DOWN: __wdsp_clr_ready_locked(wdsp, WDSP_SSR_STATUS_CDC_READY); /* * If DSP is booted when CDC_DOWN is received, it needs * to be shutdown. */ if (WDSP_STATUS_IS_SET(wdsp, WDSP_STATUS_BOOTED)) { __wdsp_clr_ready_locked(wdsp, WDSP_SSR_STATUS_WDSP_READY); wdsp_broadcast_event_downseq(wdsp, WDSP_EVENT_PRE_SHUTDOWN, NULL); } schedule_work(&wdsp->ssr_work); break; case WDSP_SSR_TYPE_CDC_UP: __wdsp_set_ready_locked(wdsp, WDSP_SSR_STATUS_CDC_READY, true); break; Loading @@ -787,8 +801,8 @@ static int wdsp_ssr_handler(struct wdsp_mgr_priv *wdsp, void *arg, return 0; } static int wdsp_intr_handler(struct device *wdsp_dev, enum wdsp_intr intr, void *arg) static int wdsp_signal_handler(struct device *wdsp_dev, enum wdsp_signal signal, void *arg) { struct wdsp_mgr_priv *wdsp; int ret; Loading @@ -799,7 +813,9 @@ static int wdsp_intr_handler(struct device *wdsp_dev, wdsp = dev_get_drvdata(wdsp_dev); WDSP_MGR_MUTEX_LOCK(wdsp, wdsp->api_mutex); switch (intr) { WDSP_DBG(wdsp, "Raised signal %d", signal); switch (signal) { case WDSP_IPC1_INTR: ret = wdsp_unicast_event(wdsp, WDSP_CMPNT_IPC, WDSP_EVENT_IPC1_INTR, NULL); Loading @@ -807,14 +823,20 @@ static int wdsp_intr_handler(struct device *wdsp_dev, case WDSP_ERR_INTR: ret = wdsp_ssr_handler(wdsp, arg, WDSP_SSR_TYPE_WDSP_DOWN); break; case WDSP_CDC_DOWN_SIGNAL: ret = wdsp_ssr_handler(wdsp, arg, WDSP_SSR_TYPE_CDC_DOWN); break; case WDSP_CDC_UP_SIGNAL: ret = wdsp_ssr_handler(wdsp, arg, WDSP_SSR_TYPE_CDC_UP); break; default: ret = -EINVAL; break; } if (IS_ERR_VALUE(ret)) WDSP_ERR(wdsp, "handling intr %d failed with error %d", intr, ret); WDSP_ERR(wdsp, "handling signal %d failed with error %d", signal, ret); WDSP_MGR_MUTEX_UNLOCK(wdsp, wdsp->api_mutex); return ret; Loading Loading @@ -870,7 +892,7 @@ static int wdsp_resume(struct device *wdsp_dev) static struct wdsp_mgr_ops wdsp_ops = { .register_cmpnt_ops = wdsp_register_cmpnt_ops, .get_dev_for_cmpnt = wdsp_get_dev_for_cmpnt, .intr_handler = wdsp_intr_handler, .signal_handler = wdsp_signal_handler, .vote_for_dsp = wdsp_vote_for_dsp, .suspend = wdsp_suspend, .resume = wdsp_resume, Loading sound/soc/codecs/wcd934x/wcd934x-dsp-cntl.c +8 −8 Original line number Diff line number Diff line Loading @@ -646,8 +646,8 @@ static irqreturn_t wcd_cntl_ipc_irq(int irq, void *data) complete(&cntl->boot_complete); if (cntl->m_dev && cntl->m_ops && cntl->m_ops->intr_handler) ret = cntl->m_ops->intr_handler(cntl->m_dev, WDSP_IPC1_INTR, cntl->m_ops->signal_handler) ret = cntl->m_ops->signal_handler(cntl->m_dev, WDSP_IPC1_INTR, NULL); else ret = -EINVAL; Loading @@ -663,7 +663,7 @@ static irqreturn_t wcd_cntl_err_irq(int irq, void *data) { struct wcd_dsp_cntl *cntl = data; struct snd_soc_codec *codec = cntl->codec; struct wdsp_err_intr_arg arg; struct wdsp_err_signal_arg arg; u16 status = 0; u8 reg_val; int ret = 0; Loading @@ -678,11 +678,11 @@ static irqreturn_t wcd_cntl_err_irq(int irq, void *data) __func__, status); if ((status & cntl->irqs.fatal_irqs) && (cntl->m_dev && cntl->m_ops && cntl->m_ops->intr_handler)) { (cntl->m_dev && cntl->m_ops && cntl->m_ops->signal_handler)) { arg.mem_dumps_enabled = cntl->ramdump_enable; arg.remote_start_addr = WCD_934X_RAMDUMP_START_ADDR; arg.dump_size = WCD_934X_RAMDUMP_SIZE; ret = cntl->m_ops->intr_handler(cntl->m_dev, WDSP_ERR_INTR, ret = cntl->m_ops->signal_handler(cntl->m_dev, WDSP_ERR_INTR, &arg); if (IS_ERR_VALUE(ret)) dev_err(cntl->codec->dev, Loading @@ -690,7 +690,7 @@ static irqreturn_t wcd_cntl_err_irq(int irq, void *data) __func__, status & cntl->irqs.fatal_irqs); wcd_cntl_change_online_state(cntl, 0); } else { dev_err(cntl->codec->dev, "%s: Invalid intr_handler\n", dev_err(cntl->codec->dev, "%s: Invalid signal_handler\n", __func__); } Loading Loading
include/sound/wcd-dsp-mgr.h +12 −6 Original line number Diff line number Diff line Loading @@ -65,9 +65,14 @@ enum wdsp_event_type { WDSP_EVENT_RESUME, }; enum wdsp_intr { enum wdsp_signal { /* Hardware generated interrupts signalled to manager */ WDSP_IPC1_INTR, WDSP_ERR_INTR, /* Other signals */ WDSP_CDC_DOWN_SIGNAL, WDSP_CDC_UP_SIGNAL, }; /* Loading @@ -92,7 +97,7 @@ struct wdsp_img_section { u8 *data; }; struct wdsp_err_intr_arg { struct wdsp_err_signal_arg { bool mem_dumps_enabled; u32 remote_start_addr; size_t dump_size; Loading @@ -104,8 +109,9 @@ struct wdsp_err_intr_arg { * their own ops to manager driver * @get_dev_for_cmpnt: components can use this to get handle * to struct device * of any other component * @intr_handler: callback to notify manager driver that interrupt * has occurred. * @signal_handler: callback to notify manager driver that signal * has occurred. Cannot be called from interrupt * context as this can sleep * @vote_for_dsp: notifies manager that dsp should be booted up * @suspend: notifies manager that one component wants to suspend. * Manager will make sure to suspend all components in order Loading @@ -120,8 +126,8 @@ struct wdsp_mgr_ops { struct wdsp_cmpnt_ops *ops); struct device *(*get_dev_for_cmpnt)(struct device *wdsp_dev, enum wdsp_cmpnt_type type); int (*intr_handler)(struct device *wdsp_dev, enum wdsp_intr intr, void *arg); int (*signal_handler)(struct device *wdsp_dev, enum wdsp_signal signal, void *arg); int (*vote_for_dsp)(struct device *wdsp_dev, bool vote); int (*suspend)(struct device *wdsp_dev); int (*resume)(struct device *wdsp_dev); Loading
sound/soc/codecs/wcd-dsp-mgr.c +42 −20 Original line number Diff line number Diff line Loading @@ -136,7 +136,7 @@ struct wdsp_ramdump_data { void *rd_v_addr; /* Data provided through error interrupt */ struct wdsp_err_intr_arg err_data; struct wdsp_err_signal_arg err_data; }; struct wdsp_mgr_priv { Loading Loading @@ -608,7 +608,7 @@ static struct device *wdsp_get_dev_for_cmpnt(struct device *wdsp_dev, static void wdsp_collect_ramdumps(struct wdsp_mgr_priv *wdsp) { struct wdsp_img_section img_section; struct wdsp_err_intr_arg *data = &wdsp->dump_data.err_data; struct wdsp_err_signal_arg *data = &wdsp->dump_data.err_data; struct ramdump_segment rd_seg; int ret = 0; Loading Loading @@ -684,17 +684,18 @@ static void wdsp_ssr_work_fn(struct work_struct *work) WDSP_MGR_MUTEX_LOCK(wdsp, wdsp->ssr_mutex); /* Issue ramdumps and shutdown only if DSP is currently booted */ if (WDSP_STATUS_IS_SET(wdsp, WDSP_STATUS_BOOTED)) { wdsp_collect_ramdumps(wdsp); /* In case of CDC_DOWN event, the DSP is already shutdown */ if (wdsp->ssr_type != WDSP_SSR_TYPE_CDC_DOWN) { ret = wdsp_unicast_event(wdsp, WDSP_CMPNT_CONTROL, WDSP_EVENT_DO_SHUTDOWN, NULL); if (IS_ERR_VALUE(ret)) WDSP_ERR(wdsp, "Failed WDSP shutdown, err = %d", ret); } wdsp_broadcast_event_downseq(wdsp, WDSP_EVENT_POST_SHUTDOWN, NULL); wdsp_broadcast_event_downseq(wdsp, WDSP_EVENT_POST_SHUTDOWN, NULL); WDSP_CLEAR_STATUS(wdsp, WDSP_STATUS_BOOTED); } WDSP_MGR_MUTEX_UNLOCK(wdsp, wdsp->ssr_mutex); ret = wait_for_completion_timeout(&wdsp->ready_compl, Loading Loading @@ -739,7 +740,7 @@ static int wdsp_ssr_handler(struct wdsp_mgr_priv *wdsp, void *arg, enum wdsp_ssr_type ssr_type) { enum wdsp_ssr_type current_ssr_type; struct wdsp_err_intr_arg *err_data; struct wdsp_err_signal_arg *err_data; WDSP_MGR_MUTEX_LOCK(wdsp, wdsp->ssr_mutex); Loading @@ -750,7 +751,7 @@ static int wdsp_ssr_handler(struct wdsp_mgr_priv *wdsp, void *arg, wdsp->ssr_type = ssr_type; if (arg) { err_data = (struct wdsp_err_intr_arg *) arg; err_data = (struct wdsp_err_signal_arg *) arg; memcpy(&wdsp->dump_data.err_data, err_data, sizeof(*err_data)); } else { Loading @@ -761,16 +762,29 @@ static int wdsp_ssr_handler(struct wdsp_mgr_priv *wdsp, void *arg, switch (ssr_type) { case WDSP_SSR_TYPE_WDSP_DOWN: case WDSP_SSR_TYPE_CDC_DOWN: __wdsp_clr_ready_locked(wdsp, WDSP_SSR_STATUS_WDSP_READY); if (ssr_type == WDSP_SSR_TYPE_CDC_DOWN) __wdsp_clr_ready_locked(wdsp, WDSP_SSR_STATUS_CDC_READY); wdsp_broadcast_event_downseq(wdsp, WDSP_EVENT_PRE_SHUTDOWN, NULL); schedule_work(&wdsp->ssr_work); break; case WDSP_SSR_TYPE_CDC_DOWN: __wdsp_clr_ready_locked(wdsp, WDSP_SSR_STATUS_CDC_READY); /* * If DSP is booted when CDC_DOWN is received, it needs * to be shutdown. */ if (WDSP_STATUS_IS_SET(wdsp, WDSP_STATUS_BOOTED)) { __wdsp_clr_ready_locked(wdsp, WDSP_SSR_STATUS_WDSP_READY); wdsp_broadcast_event_downseq(wdsp, WDSP_EVENT_PRE_SHUTDOWN, NULL); } schedule_work(&wdsp->ssr_work); break; case WDSP_SSR_TYPE_CDC_UP: __wdsp_set_ready_locked(wdsp, WDSP_SSR_STATUS_CDC_READY, true); break; Loading @@ -787,8 +801,8 @@ static int wdsp_ssr_handler(struct wdsp_mgr_priv *wdsp, void *arg, return 0; } static int wdsp_intr_handler(struct device *wdsp_dev, enum wdsp_intr intr, void *arg) static int wdsp_signal_handler(struct device *wdsp_dev, enum wdsp_signal signal, void *arg) { struct wdsp_mgr_priv *wdsp; int ret; Loading @@ -799,7 +813,9 @@ static int wdsp_intr_handler(struct device *wdsp_dev, wdsp = dev_get_drvdata(wdsp_dev); WDSP_MGR_MUTEX_LOCK(wdsp, wdsp->api_mutex); switch (intr) { WDSP_DBG(wdsp, "Raised signal %d", signal); switch (signal) { case WDSP_IPC1_INTR: ret = wdsp_unicast_event(wdsp, WDSP_CMPNT_IPC, WDSP_EVENT_IPC1_INTR, NULL); Loading @@ -807,14 +823,20 @@ static int wdsp_intr_handler(struct device *wdsp_dev, case WDSP_ERR_INTR: ret = wdsp_ssr_handler(wdsp, arg, WDSP_SSR_TYPE_WDSP_DOWN); break; case WDSP_CDC_DOWN_SIGNAL: ret = wdsp_ssr_handler(wdsp, arg, WDSP_SSR_TYPE_CDC_DOWN); break; case WDSP_CDC_UP_SIGNAL: ret = wdsp_ssr_handler(wdsp, arg, WDSP_SSR_TYPE_CDC_UP); break; default: ret = -EINVAL; break; } if (IS_ERR_VALUE(ret)) WDSP_ERR(wdsp, "handling intr %d failed with error %d", intr, ret); WDSP_ERR(wdsp, "handling signal %d failed with error %d", signal, ret); WDSP_MGR_MUTEX_UNLOCK(wdsp, wdsp->api_mutex); return ret; Loading Loading @@ -870,7 +892,7 @@ static int wdsp_resume(struct device *wdsp_dev) static struct wdsp_mgr_ops wdsp_ops = { .register_cmpnt_ops = wdsp_register_cmpnt_ops, .get_dev_for_cmpnt = wdsp_get_dev_for_cmpnt, .intr_handler = wdsp_intr_handler, .signal_handler = wdsp_signal_handler, .vote_for_dsp = wdsp_vote_for_dsp, .suspend = wdsp_suspend, .resume = wdsp_resume, Loading
sound/soc/codecs/wcd934x/wcd934x-dsp-cntl.c +8 −8 Original line number Diff line number Diff line Loading @@ -646,8 +646,8 @@ static irqreturn_t wcd_cntl_ipc_irq(int irq, void *data) complete(&cntl->boot_complete); if (cntl->m_dev && cntl->m_ops && cntl->m_ops->intr_handler) ret = cntl->m_ops->intr_handler(cntl->m_dev, WDSP_IPC1_INTR, cntl->m_ops->signal_handler) ret = cntl->m_ops->signal_handler(cntl->m_dev, WDSP_IPC1_INTR, NULL); else ret = -EINVAL; Loading @@ -663,7 +663,7 @@ static irqreturn_t wcd_cntl_err_irq(int irq, void *data) { struct wcd_dsp_cntl *cntl = data; struct snd_soc_codec *codec = cntl->codec; struct wdsp_err_intr_arg arg; struct wdsp_err_signal_arg arg; u16 status = 0; u8 reg_val; int ret = 0; Loading @@ -678,11 +678,11 @@ static irqreturn_t wcd_cntl_err_irq(int irq, void *data) __func__, status); if ((status & cntl->irqs.fatal_irqs) && (cntl->m_dev && cntl->m_ops && cntl->m_ops->intr_handler)) { (cntl->m_dev && cntl->m_ops && cntl->m_ops->signal_handler)) { arg.mem_dumps_enabled = cntl->ramdump_enable; arg.remote_start_addr = WCD_934X_RAMDUMP_START_ADDR; arg.dump_size = WCD_934X_RAMDUMP_SIZE; ret = cntl->m_ops->intr_handler(cntl->m_dev, WDSP_ERR_INTR, ret = cntl->m_ops->signal_handler(cntl->m_dev, WDSP_ERR_INTR, &arg); if (IS_ERR_VALUE(ret)) dev_err(cntl->codec->dev, Loading @@ -690,7 +690,7 @@ static irqreturn_t wcd_cntl_err_irq(int irq, void *data) __func__, status & cntl->irqs.fatal_irqs); wcd_cntl_change_online_state(cntl, 0); } else { dev_err(cntl->codec->dev, "%s: Invalid intr_handler\n", dev_err(cntl->codec->dev, "%s: Invalid signal_handler\n", __func__); } Loading