Message ID | 1687955688-20809-21-git-send-email-quic_mojha@quicinc.com |
---|---|
State | New |
Headers | show |
Series | [v4,01/21] docs: qcom: Add qualcomm minidump guide | expand |
On Wed, Jun 28, 2023 at 06:04:47PM +0530, Mukesh Ojha wrote: > Currently on Qualcomm SoC, download_mode is enabled if > CONFIG_QCOM_SCM_DOWNLOAD_MODE_DEFAULT is selected. > > Refactor the code such that it supports multiple download > modes and drop CONFIG_QCOM_SCM_DOWNLOAD_MODE_DEFAULT config > instead, give interface to set the download mode from > module parameter. > > Signed-off-by: Mukesh Ojha <quic_mojha@quicinc.com> > --- > drivers/firmware/Kconfig | 11 --------- > drivers/firmware/qcom_scm.c | 56 +++++++++++++++++++++++++++++++++++++++------ > 2 files changed, 49 insertions(+), 18 deletions(-) > > diff --git a/drivers/firmware/Kconfig b/drivers/firmware/Kconfig > index b59e3041fd62..ff7e9f330559 100644 > --- a/drivers/firmware/Kconfig > +++ b/drivers/firmware/Kconfig > @@ -215,17 +215,6 @@ config MTK_ADSP_IPC > config QCOM_SCM > tristate > > -config QCOM_SCM_DOWNLOAD_MODE_DEFAULT > - bool "Qualcomm download mode enabled by default" > - depends on QCOM_SCM > - help > - A device with "download mode" enabled will upon an unexpected > - warm-restart enter a special debug mode that allows the user to > - "download" memory content over USB for offline postmortem analysis. > - The feature can be enabled/disabled on the kernel command line. > - > - Say Y here to enable "download mode" by default. > - > config SYSFB > bool > select BOOT_VESA_SUPPORT > diff --git a/drivers/firmware/qcom_scm.c b/drivers/firmware/qcom_scm.c > index a9ff77d16c42..946cb0f76a17 100644 > --- a/drivers/firmware/qcom_scm.c > +++ b/drivers/firmware/qcom_scm.c > @@ -18,13 +18,13 @@ > #include <linux/of_irq.h> > #include <linux/of_platform.h> > #include <linux/clk.h> > +#include <linux/kstrtox.h> > #include <linux/reset-controller.h> > #include <linux/arm-smccc.h> > > #include "qcom_scm.h" > > -static bool download_mode = IS_ENABLED(CONFIG_QCOM_SCM_DOWNLOAD_MODE_DEFAULT); > -module_param(download_mode, bool, 0); > +static u32 download_mode; > > #define SCM_HAS_CORE_CLK BIT(0) > #define SCM_HAS_IFACE_CLK BIT(1) > @@ -82,6 +82,11 @@ static const char * const qcom_scm_convention_names[] = { > [SMC_CONVENTION_LEGACY] = "smc legacy", > }; > > +static const char * const download_mode_name[] = { > + [QCOM_DOWNLOAD_NODUMP] = "off", > + [QCOM_DOWNLOAD_FULLDUMP] = "full", > +}; > + > static struct qcom_scm *__scm; > > static int qcom_scm_clk_enable(void) > @@ -442,8 +447,9 @@ static int __qcom_scm_set_dload_mode(struct device *dev, bool enable) > return qcom_scm_call_atomic(__scm->dev, &desc, NULL); > } > > -static void qcom_scm_set_download_mode(bool enable) > +static void qcom_scm_set_download_mode(u32 download_mode) > { > + bool enable = !!download_mode; > bool avail; > int val; > int ret = 0; > @@ -454,7 +460,7 @@ static void qcom_scm_set_download_mode(bool enable) > if (avail) { > ret = __qcom_scm_set_dload_mode(__scm->dev, enable); > } else if (__scm->dload_mode_addr) { > - val = (enable ? QCOM_DOWNLOAD_FULLDUMP : QCOM_DOWNLOAD_NODUMP); > + val = download_mode; > val <<= QCOM_DOWNLOAD_MODE_SHIFT; > ret = qcom_scm_io_update_field(__scm->dload_mode_addr, > QCOM_DOWNLOAD_MODE_MASK, val); > @@ -1425,6 +1431,42 @@ static irqreturn_t qcom_scm_irq_handler(int irq, void *data) > return IRQ_HANDLED; > } > > +static int get_download_mode(char *buffer, const struct kernel_param *kp) > +{ > + if (download_mode >= ARRAY_SIZE(download_mode_name)) > + return sysfs_emit(buffer, "unknown mode\n"); > + > + return sysfs_emit(buffer, "%s\n", download_mode_name[download_mode]); > +} > + > +static int set_download_mode(const char *val, const struct kernel_param *kp) > +{ > + u32 old = download_mode; > + int ret; > + > + ret = sysfs_match_string(download_mode_name, val); > + if (ret < 0) { > + download_mode = old; > + pr_err("qcom_scm: unknown download mode: %s\n", val); > + return -EINVAL; > + } minor nit: %s/-EINVAL/ret > + > + download_mode = ret; > + if (__scm) > + qcom_scm_set_download_mode(download_mode); > + > + return 0; > +} > + > +static const struct kernel_param_ops download_mode_param_ops = { > + .get = get_download_mode, > + .set = set_download_mode, > +}; > + > +module_param_cb(download_mode, &download_mode_param_ops, NULL, 0644); > +MODULE_PARM_DESC(download_mode, > + "download mode: off/full are acceptable values"); > + Since we are adding a sysfs file under /sys/module/qcom_scm/ , does it need to be documented under ABI? Thanks, Pavan
On Fri, Jun 30, 2023 at 8:25 AM Pavan Kondeti <quic_pkondeti@quicinc.com> wrote: > On Wed, Jun 28, 2023 at 06:04:47PM +0530, Mukesh Ojha wrote: ... > > +static int set_download_mode(const char *val, const struct kernel_param *kp) > > +{ > > + u32 old = download_mode; > > + int ret; > > + > > + ret = sysfs_match_string(download_mode_name, val); > > + if (ret < 0) { > > + download_mode = old; Why is this old variable needed at all? > > + pr_err("qcom_scm: unknown download mode: %s\n", val); > > + return -EINVAL; > > + } > > minor nit: %s/-EINVAL/ret > > > + download_mode = ret; > > + if (__scm) > > + qcom_scm_set_download_mode(download_mode); > > + > > + return 0; > > +}
diff --git a/drivers/firmware/Kconfig b/drivers/firmware/Kconfig index b59e3041fd62..ff7e9f330559 100644 --- a/drivers/firmware/Kconfig +++ b/drivers/firmware/Kconfig @@ -215,17 +215,6 @@ config MTK_ADSP_IPC config QCOM_SCM tristate -config QCOM_SCM_DOWNLOAD_MODE_DEFAULT - bool "Qualcomm download mode enabled by default" - depends on QCOM_SCM - help - A device with "download mode" enabled will upon an unexpected - warm-restart enter a special debug mode that allows the user to - "download" memory content over USB for offline postmortem analysis. - The feature can be enabled/disabled on the kernel command line. - - Say Y here to enable "download mode" by default. - config SYSFB bool select BOOT_VESA_SUPPORT diff --git a/drivers/firmware/qcom_scm.c b/drivers/firmware/qcom_scm.c index a9ff77d16c42..946cb0f76a17 100644 --- a/drivers/firmware/qcom_scm.c +++ b/drivers/firmware/qcom_scm.c @@ -18,13 +18,13 @@ #include <linux/of_irq.h> #include <linux/of_platform.h> #include <linux/clk.h> +#include <linux/kstrtox.h> #include <linux/reset-controller.h> #include <linux/arm-smccc.h> #include "qcom_scm.h" -static bool download_mode = IS_ENABLED(CONFIG_QCOM_SCM_DOWNLOAD_MODE_DEFAULT); -module_param(download_mode, bool, 0); +static u32 download_mode; #define SCM_HAS_CORE_CLK BIT(0) #define SCM_HAS_IFACE_CLK BIT(1) @@ -82,6 +82,11 @@ static const char * const qcom_scm_convention_names[] = { [SMC_CONVENTION_LEGACY] = "smc legacy", }; +static const char * const download_mode_name[] = { + [QCOM_DOWNLOAD_NODUMP] = "off", + [QCOM_DOWNLOAD_FULLDUMP] = "full", +}; + static struct qcom_scm *__scm; static int qcom_scm_clk_enable(void) @@ -442,8 +447,9 @@ static int __qcom_scm_set_dload_mode(struct device *dev, bool enable) return qcom_scm_call_atomic(__scm->dev, &desc, NULL); } -static void qcom_scm_set_download_mode(bool enable) +static void qcom_scm_set_download_mode(u32 download_mode) { + bool enable = !!download_mode; bool avail; int val; int ret = 0; @@ -454,7 +460,7 @@ static void qcom_scm_set_download_mode(bool enable) if (avail) { ret = __qcom_scm_set_dload_mode(__scm->dev, enable); } else if (__scm->dload_mode_addr) { - val = (enable ? QCOM_DOWNLOAD_FULLDUMP : QCOM_DOWNLOAD_NODUMP); + val = download_mode; val <<= QCOM_DOWNLOAD_MODE_SHIFT; ret = qcom_scm_io_update_field(__scm->dload_mode_addr, QCOM_DOWNLOAD_MODE_MASK, val); @@ -1425,6 +1431,42 @@ static irqreturn_t qcom_scm_irq_handler(int irq, void *data) return IRQ_HANDLED; } +static int get_download_mode(char *buffer, const struct kernel_param *kp) +{ + if (download_mode >= ARRAY_SIZE(download_mode_name)) + return sysfs_emit(buffer, "unknown mode\n"); + + return sysfs_emit(buffer, "%s\n", download_mode_name[download_mode]); +} + +static int set_download_mode(const char *val, const struct kernel_param *kp) +{ + u32 old = download_mode; + int ret; + + ret = sysfs_match_string(download_mode_name, val); + if (ret < 0) { + download_mode = old; + pr_err("qcom_scm: unknown download mode: %s\n", val); + return -EINVAL; + } + + download_mode = ret; + if (__scm) + qcom_scm_set_download_mode(download_mode); + + return 0; +} + +static const struct kernel_param_ops download_mode_param_ops = { + .get = get_download_mode, + .set = set_download_mode, +}; + +module_param_cb(download_mode, &download_mode_param_ops, NULL, 0644); +MODULE_PARM_DESC(download_mode, + "download mode: off/full are acceptable values"); + static int qcom_scm_probe(struct platform_device *pdev) { struct qcom_scm *scm; @@ -1518,12 +1560,12 @@ static int qcom_scm_probe(struct platform_device *pdev) __get_convention(); /* - * If requested enable "download mode", from this point on warmboot + * If "download mode" is requested, from this point on warmboot * will cause the boot stages to enter download mode, unless * disabled below by a clean shutdown/reboot. */ if (download_mode) - qcom_scm_set_download_mode(true); + qcom_scm_set_download_mode(download_mode); return 0; } @@ -1531,7 +1573,7 @@ static int qcom_scm_probe(struct platform_device *pdev) static void qcom_scm_shutdown(struct platform_device *pdev) { /* Clean shutdown, disable download mode to allow normal restart */ - qcom_scm_set_download_mode(false); + qcom_scm_set_download_mode(QCOM_DOWNLOAD_NODUMP); } static const struct of_device_id qcom_scm_dt_match[] = {
Currently on Qualcomm SoC, download_mode is enabled if CONFIG_QCOM_SCM_DOWNLOAD_MODE_DEFAULT is selected. Refactor the code such that it supports multiple download modes and drop CONFIG_QCOM_SCM_DOWNLOAD_MODE_DEFAULT config instead, give interface to set the download mode from module parameter. Signed-off-by: Mukesh Ojha <quic_mojha@quicinc.com> --- drivers/firmware/Kconfig | 11 --------- drivers/firmware/qcom_scm.c | 56 +++++++++++++++++++++++++++++++++++++++------ 2 files changed, 49 insertions(+), 18 deletions(-)