Loading dsp/adsp-loader.c +58 −22 Original line number Diff line number Diff line Loading @@ -55,6 +55,51 @@ static struct work_struct adsp_ldr_work; static struct platform_device *adsp_private; static void adsp_loader_unload(struct platform_device *pdev); static int adsp_restart_subsys(void) { struct subsys_device *adsp_dev = NULL; struct platform_device *pdev = adsp_private; struct adsp_loader_private *priv = NULL; int rc = -EINVAL; priv = platform_get_drvdata(pdev); if (!priv) return rc; adsp_dev = (struct subsys_device *)priv->pil_h; if (!adsp_dev) return rc; /* subsystem_restart_dev has worker queue to handle */ rc = subsystem_restart_dev(adsp_dev); if (rc) { dev_err(&pdev->dev, "subsystem_restart_dev failed\n"); return rc; } pr_debug("%s :: Restart Success %d\n", __func__, rc); return rc; } static void adsp_load_state_notify_cb(enum apr_subsys_state state, void *phandle) { struct platform_device *pdev = adsp_private; struct adsp_loader_private *priv = NULL; priv = platform_get_drvdata(pdev); if (!priv) return; if (phandle != adsp_private) { pr_err("%s:callback is not for adsp-loader client\n", __func__); return; } pr_debug("%s:: Received cb for ADSP restart\n", __func__); if (state == APR_SUBSYS_UNKNOWN) adsp_restart_subsys(); else pr_debug("%s:Ignore restart request for ADSP", __func__); } static void adsp_load_fw(struct work_struct *adsp_ldr_work) { struct platform_device *pdev = adsp_private; Loading @@ -63,6 +108,7 @@ static void adsp_load_fw(struct work_struct *adsp_ldr_work) int rc = 0; u32 adsp_state; const char *img_name; void *padsp_restart_cb = &adsp_load_state_notify_cb; if (!pdev) { dev_err(&pdev->dev, "%s: Platform device null\n", __func__); Loading Loading @@ -119,7 +165,7 @@ static void adsp_load_fw(struct work_struct *adsp_ldr_work) } dev_dbg(&pdev->dev, "%s: Q6/MDSP image is loaded\n", __func__); return; goto success; } load_adsp: Loading Loading @@ -153,10 +199,13 @@ static void adsp_load_fw(struct work_struct *adsp_ldr_work) } dev_dbg(&pdev->dev, "%s: Q6/ADSP image is loaded\n", __func__); return; apr_register_adsp_state_cb(padsp_restart_cb, adsp_private); goto success; } fail: dev_err(&pdev->dev, "%s: Q6 image loading failed\n", __func__); success: return; } static void adsp_loader_do(struct platform_device *pdev) Loading @@ -170,37 +219,24 @@ static ssize_t adsp_ssr_store(struct kobject *kobj, size_t count) { int ssr_command = 0; struct subsys_device *adsp_dev = NULL; struct platform_device *pdev = adsp_private; struct adsp_loader_private *priv = NULL; int rc; int rc = -EINVAL; dev_dbg(&pdev->dev, "%s: going to call adsp ssr\n ", __func__); if (kstrtoint(buf, 10, &ssr_command) < 0) return -EINVAL; if (ssr_command != SSR_RESET_CMD) return -EINVAL; priv = platform_get_drvdata(pdev); if (!priv) return -EINVAL; return rc; adsp_dev = (struct subsys_device *)priv->pil_h; if (!adsp_dev) if (kstrtoint(buf, 10, &ssr_command) < 0) return -EINVAL; dev_err(&pdev->dev, "requesting for ADSP restart\n"); /* subsystem_restart_dev has worker queue to handle */ rc = subsystem_restart_dev(adsp_dev); if (rc) { dev_err(&pdev->dev, "subsystem_restart_dev failed\n"); return rc; } if (ssr_command != SSR_RESET_CMD) return -EINVAL; dev_dbg(&pdev->dev, "ADSP restarted\n"); adsp_restart_subsys(); dev_dbg(&pdev->dev, "%s :: ADSP restarted\n", __func__); return count; } Loading include/ipc/apr.h +10 −1 Original line number Diff line number Diff line /* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2010-2017, 2019, The Linux Foundation. All rights reserved. * Copyright (c) 2010-2017, 2019, 2020, The Linux Foundation. All rights reserved. */ #ifndef __APR_H_ #define __APR_H_ Loading @@ -12,6 +12,7 @@ enum apr_subsys_state { APR_SUBSYS_DOWN, APR_SUBSYS_UP, APR_SUBSYS_LOADED, APR_SUBSYS_UNKNOWN, }; struct apr_q6 { Loading @@ -19,6 +20,13 @@ struct apr_q6 { atomic_t q6_state; atomic_t modem_state; struct mutex lock; /* * ToDo - Multiple client support to be added. * And checking for state UNKNOWN currently. */ void (*state_notify_cb)(enum apr_subsys_state state, void *client_handle); void *client_handle; }; struct apr_hdr { Loading Loading @@ -186,4 +194,5 @@ const char *apr_get_lpass_subsys_name(void); uint16_t apr_get_reset_domain(uint16_t proc); int apr_start_rx_rt(void *handle); int apr_end_rx_rt(void *handle); void apr_register_adsp_state_cb(void *adsp_cb, void *client_handle); #endif ipc/apr.c +35 −3 Original line number Diff line number Diff line // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2010-2014, 2016-2019 The Linux Foundation. All rights reserved. * Copyright (c) 2010-2014, 2016-2020 The Linux Foundation. All rights reserved. */ #include <linux/kernel.h> Loading Loading @@ -32,9 +32,14 @@ #define APR_PKT_IPC_LOG_PAGE_CNT 2 static int apr_pkt_cnt_adsp_restart = 20; module_param(apr_pkt_cnt_adsp_restart, int, 0664); MODULE_PARM_DESC(apr_pkt_cnt_adsp_restart, "set apr pktcount for adsp restart feature"); static struct apr_q6 q6; static struct apr_client client[APR_DEST_MAX][APR_CLIENT_MAX]; static void *apr_pkt_ctx; static int apr_send_pkt_count; static wait_queue_head_t modem_wait; static bool is_modem_up; static char *subsys_name = NULL; Loading @@ -61,6 +66,8 @@ struct apr_private { static struct apr_private *apr_priv; static bool apr_cf_debug; static struct work_struct apr_cb_work; static void state_notify_cb(struct work_struct *work); #ifdef CONFIG_DEBUG_FS static struct dentry *debugfs_apr_debug; Loading Loading @@ -313,6 +320,7 @@ static void apr_adsp_up(void) schedule_work(&apr_priv->add_chld_dev_work); spin_unlock(&apr_priv->apr_lock); snd_event_notify(apr_priv->dev, SND_EVENT_UP); cancel_work_sync(&apr_cb_work); } int apr_load_adsp_image(void) Loading Loading @@ -426,6 +434,17 @@ int apr_send_pkt(void *handle, uint32_t *buf) __func__); rc = -ENETRESET; } if (rc == -EAGAIN || rc == -ETIMEDOUT) { apr_send_pkt_count++; pr_err("%s:: send pkt timedout apr_send_pkt_count %d\n", __func__, apr_send_pkt_count); } } if (apr_send_pkt_count == apr_pkt_cnt_adsp_restart) { pr_debug("%s:: schedule work for adsp loader restart cb\n", __func__); schedule_work(&apr_cb_work); apr_send_pkt_count = 0; } spin_unlock_irqrestore(&svc->w_lock, flags); Loading Loading @@ -800,6 +819,19 @@ static void apr_reset_deregister(struct work_struct *work) kfree(apr_reset); } static void state_notify_cb(struct work_struct *work) { if (q6.state_notify_cb) q6.state_notify_cb(APR_SUBSYS_UNKNOWN, q6.client_handle); } void apr_register_adsp_state_cb(void *adsp_cb, void *client_handle) { q6.state_notify_cb = adsp_cb; q6.client_handle = client_handle; } EXPORT_SYMBOL(apr_register_adsp_state_cb); /** * apr_start_rx_rt - Clients call to vote for thread * priority upgrade whenever needed. Loading Loading @@ -1212,7 +1244,7 @@ static int apr_probe(struct platform_device *pdev) __func__, ret); ret = 0; } INIT_WORK(&apr_cb_work, state_notify_cb); return apr_debug_init(); } Loading Loading
dsp/adsp-loader.c +58 −22 Original line number Diff line number Diff line Loading @@ -55,6 +55,51 @@ static struct work_struct adsp_ldr_work; static struct platform_device *adsp_private; static void adsp_loader_unload(struct platform_device *pdev); static int adsp_restart_subsys(void) { struct subsys_device *adsp_dev = NULL; struct platform_device *pdev = adsp_private; struct adsp_loader_private *priv = NULL; int rc = -EINVAL; priv = platform_get_drvdata(pdev); if (!priv) return rc; adsp_dev = (struct subsys_device *)priv->pil_h; if (!adsp_dev) return rc; /* subsystem_restart_dev has worker queue to handle */ rc = subsystem_restart_dev(adsp_dev); if (rc) { dev_err(&pdev->dev, "subsystem_restart_dev failed\n"); return rc; } pr_debug("%s :: Restart Success %d\n", __func__, rc); return rc; } static void adsp_load_state_notify_cb(enum apr_subsys_state state, void *phandle) { struct platform_device *pdev = adsp_private; struct adsp_loader_private *priv = NULL; priv = platform_get_drvdata(pdev); if (!priv) return; if (phandle != adsp_private) { pr_err("%s:callback is not for adsp-loader client\n", __func__); return; } pr_debug("%s:: Received cb for ADSP restart\n", __func__); if (state == APR_SUBSYS_UNKNOWN) adsp_restart_subsys(); else pr_debug("%s:Ignore restart request for ADSP", __func__); } static void adsp_load_fw(struct work_struct *adsp_ldr_work) { struct platform_device *pdev = adsp_private; Loading @@ -63,6 +108,7 @@ static void adsp_load_fw(struct work_struct *adsp_ldr_work) int rc = 0; u32 adsp_state; const char *img_name; void *padsp_restart_cb = &adsp_load_state_notify_cb; if (!pdev) { dev_err(&pdev->dev, "%s: Platform device null\n", __func__); Loading Loading @@ -119,7 +165,7 @@ static void adsp_load_fw(struct work_struct *adsp_ldr_work) } dev_dbg(&pdev->dev, "%s: Q6/MDSP image is loaded\n", __func__); return; goto success; } load_adsp: Loading Loading @@ -153,10 +199,13 @@ static void adsp_load_fw(struct work_struct *adsp_ldr_work) } dev_dbg(&pdev->dev, "%s: Q6/ADSP image is loaded\n", __func__); return; apr_register_adsp_state_cb(padsp_restart_cb, adsp_private); goto success; } fail: dev_err(&pdev->dev, "%s: Q6 image loading failed\n", __func__); success: return; } static void adsp_loader_do(struct platform_device *pdev) Loading @@ -170,37 +219,24 @@ static ssize_t adsp_ssr_store(struct kobject *kobj, size_t count) { int ssr_command = 0; struct subsys_device *adsp_dev = NULL; struct platform_device *pdev = adsp_private; struct adsp_loader_private *priv = NULL; int rc; int rc = -EINVAL; dev_dbg(&pdev->dev, "%s: going to call adsp ssr\n ", __func__); if (kstrtoint(buf, 10, &ssr_command) < 0) return -EINVAL; if (ssr_command != SSR_RESET_CMD) return -EINVAL; priv = platform_get_drvdata(pdev); if (!priv) return -EINVAL; return rc; adsp_dev = (struct subsys_device *)priv->pil_h; if (!adsp_dev) if (kstrtoint(buf, 10, &ssr_command) < 0) return -EINVAL; dev_err(&pdev->dev, "requesting for ADSP restart\n"); /* subsystem_restart_dev has worker queue to handle */ rc = subsystem_restart_dev(adsp_dev); if (rc) { dev_err(&pdev->dev, "subsystem_restart_dev failed\n"); return rc; } if (ssr_command != SSR_RESET_CMD) return -EINVAL; dev_dbg(&pdev->dev, "ADSP restarted\n"); adsp_restart_subsys(); dev_dbg(&pdev->dev, "%s :: ADSP restarted\n", __func__); return count; } Loading
include/ipc/apr.h +10 −1 Original line number Diff line number Diff line /* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2010-2017, 2019, The Linux Foundation. All rights reserved. * Copyright (c) 2010-2017, 2019, 2020, The Linux Foundation. All rights reserved. */ #ifndef __APR_H_ #define __APR_H_ Loading @@ -12,6 +12,7 @@ enum apr_subsys_state { APR_SUBSYS_DOWN, APR_SUBSYS_UP, APR_SUBSYS_LOADED, APR_SUBSYS_UNKNOWN, }; struct apr_q6 { Loading @@ -19,6 +20,13 @@ struct apr_q6 { atomic_t q6_state; atomic_t modem_state; struct mutex lock; /* * ToDo - Multiple client support to be added. * And checking for state UNKNOWN currently. */ void (*state_notify_cb)(enum apr_subsys_state state, void *client_handle); void *client_handle; }; struct apr_hdr { Loading Loading @@ -186,4 +194,5 @@ const char *apr_get_lpass_subsys_name(void); uint16_t apr_get_reset_domain(uint16_t proc); int apr_start_rx_rt(void *handle); int apr_end_rx_rt(void *handle); void apr_register_adsp_state_cb(void *adsp_cb, void *client_handle); #endif
ipc/apr.c +35 −3 Original line number Diff line number Diff line // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2010-2014, 2016-2019 The Linux Foundation. All rights reserved. * Copyright (c) 2010-2014, 2016-2020 The Linux Foundation. All rights reserved. */ #include <linux/kernel.h> Loading Loading @@ -32,9 +32,14 @@ #define APR_PKT_IPC_LOG_PAGE_CNT 2 static int apr_pkt_cnt_adsp_restart = 20; module_param(apr_pkt_cnt_adsp_restart, int, 0664); MODULE_PARM_DESC(apr_pkt_cnt_adsp_restart, "set apr pktcount for adsp restart feature"); static struct apr_q6 q6; static struct apr_client client[APR_DEST_MAX][APR_CLIENT_MAX]; static void *apr_pkt_ctx; static int apr_send_pkt_count; static wait_queue_head_t modem_wait; static bool is_modem_up; static char *subsys_name = NULL; Loading @@ -61,6 +66,8 @@ struct apr_private { static struct apr_private *apr_priv; static bool apr_cf_debug; static struct work_struct apr_cb_work; static void state_notify_cb(struct work_struct *work); #ifdef CONFIG_DEBUG_FS static struct dentry *debugfs_apr_debug; Loading Loading @@ -313,6 +320,7 @@ static void apr_adsp_up(void) schedule_work(&apr_priv->add_chld_dev_work); spin_unlock(&apr_priv->apr_lock); snd_event_notify(apr_priv->dev, SND_EVENT_UP); cancel_work_sync(&apr_cb_work); } int apr_load_adsp_image(void) Loading Loading @@ -426,6 +434,17 @@ int apr_send_pkt(void *handle, uint32_t *buf) __func__); rc = -ENETRESET; } if (rc == -EAGAIN || rc == -ETIMEDOUT) { apr_send_pkt_count++; pr_err("%s:: send pkt timedout apr_send_pkt_count %d\n", __func__, apr_send_pkt_count); } } if (apr_send_pkt_count == apr_pkt_cnt_adsp_restart) { pr_debug("%s:: schedule work for adsp loader restart cb\n", __func__); schedule_work(&apr_cb_work); apr_send_pkt_count = 0; } spin_unlock_irqrestore(&svc->w_lock, flags); Loading Loading @@ -800,6 +819,19 @@ static void apr_reset_deregister(struct work_struct *work) kfree(apr_reset); } static void state_notify_cb(struct work_struct *work) { if (q6.state_notify_cb) q6.state_notify_cb(APR_SUBSYS_UNKNOWN, q6.client_handle); } void apr_register_adsp_state_cb(void *adsp_cb, void *client_handle) { q6.state_notify_cb = adsp_cb; q6.client_handle = client_handle; } EXPORT_SYMBOL(apr_register_adsp_state_cb); /** * apr_start_rx_rt - Clients call to vote for thread * priority upgrade whenever needed. Loading Loading @@ -1212,7 +1244,7 @@ static int apr_probe(struct platform_device *pdev) __func__, ret); ret = 0; } INIT_WORK(&apr_cb_work, state_notify_cb); return apr_debug_init(); } Loading