Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

firmware: qcom: scm: Refactor code to support multiple dload mode

Currently on Qualcomm SoC, download_mode is enabled if
CONFIG_QCOM_SCM_DOWNLOAD_MODE_DEFAULT is selected or
passed a boolean value from command line.

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 while being backword compatible at the
same time.

Signed-off-by: Mukesh Ojha <quic_mojha@quicinc.com>
Link: https://lore.kernel.org/r/20240715155655.1811178-1-quic_mojha@quicinc.com
Signed-off-by: Bjorn Andersson <andersson@kernel.org>

authored by

Mukesh Ojha and committed by
Bjorn Andersson
c802b0a2 ed2c3752

+52 -19
-11
drivers/firmware/qcom/Kconfig
··· 41 41 42 42 endchoice 43 43 44 - config QCOM_SCM_DOWNLOAD_MODE_DEFAULT 45 - bool "Qualcomm download mode enabled by default" 46 - depends on QCOM_SCM 47 - help 48 - A device with "download mode" enabled will upon an unexpected 49 - warm-restart enter a special debug mode that allows the user to 50 - "download" memory content over USB for offline postmortem analysis. 51 - The feature can be enabled/disabled on the kernel command line. 52 - 53 - Say Y here to enable "download mode" by default. 54 - 55 44 config QCOM_QSEECOM 56 45 bool "Qualcomm QSEECOM interface driver" 57 46 depends on QCOM_SCM=y
+52 -8
drivers/firmware/qcom/qcom_scm.c
··· 18 18 #include <linux/init.h> 19 19 #include <linux/interconnect.h> 20 20 #include <linux/interrupt.h> 21 + #include <linux/kstrtox.h> 21 22 #include <linux/module.h> 22 23 #include <linux/of.h> 23 24 #include <linux/of_address.h> ··· 33 32 #include "qcom_scm.h" 34 33 #include "qcom_tzmem.h" 35 34 36 - static bool download_mode = IS_ENABLED(CONFIG_QCOM_SCM_DOWNLOAD_MODE_DEFAULT); 37 - module_param(download_mode, bool, 0); 35 + static u32 download_mode; 38 36 39 37 struct qcom_scm { 40 38 struct device *dev; ··· 132 132 [SMC_CONVENTION_ARM_32] = "smc arm 32", 133 133 [SMC_CONVENTION_ARM_64] = "smc arm 64", 134 134 [SMC_CONVENTION_LEGACY] = "smc legacy", 135 + }; 136 + 137 + static const char * const download_mode_name[] = { 138 + [QCOM_DLOAD_NODUMP] = "off", 139 + [QCOM_DLOAD_FULLDUMP] = "full", 135 140 }; 136 141 137 142 static struct qcom_scm *__scm; ··· 531 526 return qcom_scm_io_writel(addr, new); 532 527 } 533 528 534 - static void qcom_scm_set_download_mode(bool enable) 529 + static void qcom_scm_set_download_mode(u32 dload_mode) 535 530 { 536 - u32 val = enable ? QCOM_DLOAD_FULLDUMP : QCOM_DLOAD_NODUMP; 537 531 int ret = 0; 538 532 539 533 if (__scm->dload_mode_addr) { 540 534 ret = qcom_scm_io_rmw(__scm->dload_mode_addr, QCOM_DLOAD_MASK, 541 - FIELD_PREP(QCOM_DLOAD_MASK, val)); 535 + FIELD_PREP(QCOM_DLOAD_MASK, dload_mode)); 542 536 } else if (__qcom_scm_is_call_available(__scm->dev, QCOM_SCM_SVC_BOOT, 543 537 QCOM_SCM_BOOT_SET_DLOAD_MODE)) { 544 - ret = __qcom_scm_set_dload_mode(__scm->dev, enable); 538 + ret = __qcom_scm_set_dload_mode(__scm->dev, !!dload_mode); 545 539 } else { 546 540 dev_err(__scm->dev, 547 541 "No available mechanism for setting download mode\n"); ··· 1891 1887 return IRQ_HANDLED; 1892 1888 } 1893 1889 1890 + static int get_download_mode(char *buffer, const struct kernel_param *kp) 1891 + { 1892 + if (download_mode >= ARRAY_SIZE(download_mode_name)) 1893 + return sysfs_emit(buffer, "unknown mode\n"); 1894 + 1895 + return sysfs_emit(buffer, "%s\n", download_mode_name[download_mode]); 1896 + } 1897 + 1898 + static int set_download_mode(const char *val, const struct kernel_param *kp) 1899 + { 1900 + bool tmp; 1901 + int ret; 1902 + 1903 + ret = sysfs_match_string(download_mode_name, val); 1904 + if (ret < 0) { 1905 + ret = kstrtobool(val, &tmp); 1906 + if (ret < 0) { 1907 + pr_err("qcom_scm: err: %d\n", ret); 1908 + return ret; 1909 + } 1910 + 1911 + ret = tmp ? 1 : 0; 1912 + } 1913 + 1914 + download_mode = ret; 1915 + if (__scm) 1916 + qcom_scm_set_download_mode(download_mode); 1917 + 1918 + return 0; 1919 + } 1920 + 1921 + static const struct kernel_param_ops download_mode_param_ops = { 1922 + .get = get_download_mode, 1923 + .set = set_download_mode, 1924 + }; 1925 + 1926 + module_param_cb(download_mode, &download_mode_param_ops, NULL, 0644); 1927 + MODULE_PARM_DESC(download_mode, 1928 + "download mode: off/0/N for no dump mode, full/on/1/Y for full dump mode"); 1929 + 1894 1930 static int qcom_scm_probe(struct platform_device *pdev) 1895 1931 { 1896 1932 struct qcom_tzmem_pool_config pool_config; ··· 1995 1951 __get_convention(); 1996 1952 1997 1953 /* 1998 - * If requested enable "download mode", from this point on warmboot 1954 + * If "download mode" is requested, from this point on warmboot 1999 1955 * will cause the boot stages to enter download mode, unless 2000 1956 * disabled below by a clean shutdown/reboot. 2001 1957 */ ··· 2046 2002 static void qcom_scm_shutdown(struct platform_device *pdev) 2047 2003 { 2048 2004 /* Clean shutdown, disable download mode to allow normal restart */ 2049 - qcom_scm_set_download_mode(false); 2005 + qcom_scm_set_download_mode(QCOM_DLOAD_NODUMP); 2050 2006 } 2051 2007 2052 2008 static const struct of_device_id qcom_scm_dt_match[] = {