From 548fe51740d0f3294e548f654c099e5aefbf4cb7 Mon Sep 17 00:00:00 2001 From: Madhav Bhatt Date: Thu, 17 Apr 2025 02:45:43 -0700 Subject: [PATCH 001/114] firmware: xilinx: Add debugfs support for PM_GET_NODE_STATUS Add new debug interface to support PM_GET_NODE_STATUS to get the node information like requirements and usage. The debugfs firmware driver interface is only meant for testing and debugging EEMI APIs. Hence, it is by-default disabled in production systems. Signed-off-by: Madhav Bhatt Link: https://lore.kernel.org/r/20250417094543.3873507-1-madhav.bhatt@amd.com Signed-off-by: Michal Simek --- drivers/firmware/xilinx/zynqmp-debug.c | 13 ++++++++ drivers/firmware/xilinx/zynqmp.c | 41 +++++++++++++++++++++++++- include/linux/firmware/xlnx-zynqmp.h | 12 +++++++- 3 files changed, 64 insertions(+), 2 deletions(-) diff --git a/drivers/firmware/xilinx/zynqmp-debug.c b/drivers/firmware/xilinx/zynqmp-debug.c index 22853ae0efdf..36efb827f3da 100644 --- a/drivers/firmware/xilinx/zynqmp-debug.c +++ b/drivers/firmware/xilinx/zynqmp-debug.c @@ -3,6 +3,7 @@ * Xilinx Zynq MPSoC Firmware layer for debugfs APIs * * Copyright (C) 2014-2018 Xilinx, Inc. + * Copyright (C) 2022 - 2025 Advanced Micro Devices, Inc. * * Michal Simek * Davorin Mista @@ -38,6 +39,7 @@ static struct pm_api_info pm_api_list[] = { PM_API(PM_RELEASE_NODE), PM_API(PM_SET_REQUIREMENT), PM_API(PM_GET_API_VERSION), + PM_API(PM_GET_NODE_STATUS), PM_API(PM_REGISTER_NOTIFIER), PM_API(PM_RESET_ASSERT), PM_API(PM_RESET_GET_STATUS), @@ -167,6 +169,17 @@ static int process_api_request(u32 pm_id, u64 *pm_api_arg, u32 *pm_api_ret) pm_api_arg[3] ? pm_api_arg[3] : ZYNQMP_PM_REQUEST_ACK_BLOCKING); break; + case PM_GET_NODE_STATUS: + ret = zynqmp_pm_get_node_status(pm_api_arg[0], + &pm_api_ret[0], + &pm_api_ret[1], + &pm_api_ret[2]); + if (!ret) + sprintf(debugfs_buf, + "GET_NODE_STATUS:\n\tNodeId: %llu\n\tStatus: %u\n\tRequirements: %u\n\tUsage: %u\n", + pm_api_arg[0], pm_api_ret[0], + pm_api_ret[1], pm_api_ret[2]); + break; case PM_REGISTER_NOTIFIER: ret = zynqmp_pm_register_notifier(pm_api_arg[0], pm_api_arg[1] ? diff --git a/drivers/firmware/xilinx/zynqmp.c b/drivers/firmware/xilinx/zynqmp.c index 02da3e48bc8f..a17c806cd117 100644 --- a/drivers/firmware/xilinx/zynqmp.c +++ b/drivers/firmware/xilinx/zynqmp.c @@ -3,7 +3,7 @@ * Xilinx Zynq MPSoC Firmware layer * * Copyright (C) 2014-2022 Xilinx, Inc. - * Copyright (C) 2022 - 2024, Advanced Micro Devices, Inc. + * Copyright (C) 2022 - 2025 Advanced Micro Devices, Inc. * * Michal Simek * Davorin Mista @@ -1413,6 +1413,45 @@ int zynqmp_pm_set_tcm_config(u32 node_id, enum rpu_tcm_comb tcm_mode) } EXPORT_SYMBOL_GPL(zynqmp_pm_set_tcm_config); +/** + * zynqmp_pm_get_node_status - PM call to request a node's current power state + * @node: ID of the component or sub-system in question + * @status: Current operating state of the requested node + * @requirements: Current requirements asserted on the node, + * used for slave nodes only. + * @usage: Usage information, used for slave nodes only: + * PM_USAGE_NO_MASTER - No master is currently using + * the node + * PM_USAGE_CURRENT_MASTER - Only requesting master is + * currently using the node + * PM_USAGE_OTHER_MASTER - Only other masters are + * currently using the node + * PM_USAGE_BOTH_MASTERS - Both the current and at least + * one other master is currently + * using the node + * + * Return: Returns status, either success or error+reason + */ +int zynqmp_pm_get_node_status(const u32 node, u32 *const status, + u32 *const requirements, u32 *const usage) +{ + u32 ret_payload[PAYLOAD_ARG_CNT]; + int ret; + + if (!status || !requirements || !usage) + return -EINVAL; + + ret = zynqmp_pm_invoke_fn(PM_GET_NODE_STATUS, ret_payload, 1, node); + if (ret_payload[0] == XST_PM_SUCCESS) { + *status = ret_payload[1]; + *requirements = ret_payload[2]; + *usage = ret_payload[3]; + } + + return ret; +} +EXPORT_SYMBOL_GPL(zynqmp_pm_get_node_status); + /** * zynqmp_pm_force_pwrdwn - PM call to request for another PU or subsystem to * be powered down forcefully diff --git a/include/linux/firmware/xlnx-zynqmp.h b/include/linux/firmware/xlnx-zynqmp.h index ae48d619c4e0..4699f50465f2 100644 --- a/include/linux/firmware/xlnx-zynqmp.h +++ b/include/linux/firmware/xlnx-zynqmp.h @@ -3,7 +3,7 @@ * Xilinx Zynq MPSoC Firmware layer * * Copyright (C) 2014-2021 Xilinx - * Copyright (C) 2022 - 2024, Advanced Micro Devices, Inc. + * Copyright (C) 2022 - 2025 Advanced Micro Devices, Inc. * * Michal Simek * Davorin Mista @@ -164,6 +164,7 @@ enum pm_api_cb_id { enum pm_api_id { PM_API_FEATURES = 0, PM_GET_API_VERSION = 1, + PM_GET_NODE_STATUS = 3, PM_REGISTER_NOTIFIER = 5, PM_FORCE_POWERDOWN = 8, PM_REQUEST_WAKEUP = 10, @@ -629,6 +630,8 @@ int zynqmp_pm_request_wake(const u32 node, int zynqmp_pm_get_rpu_mode(u32 node_id, enum rpu_oper_mode *rpu_mode); int zynqmp_pm_set_rpu_mode(u32 node_id, enum rpu_oper_mode rpu_mode); int zynqmp_pm_set_tcm_config(u32 node_id, enum rpu_tcm_comb tcm_mode); +int zynqmp_pm_get_node_status(const u32 node, u32 *const status, + u32 *const requirements, u32 *const usage); int zynqmp_pm_set_sd_config(u32 node, enum pm_sd_config_type config, u32 value); int zynqmp_pm_set_gem_config(u32 node, enum pm_gem_config_type config, u32 value); @@ -931,6 +934,13 @@ static inline int zynqmp_pm_set_tcm_config(u32 node_id, enum rpu_tcm_comb tcm_mo return -ENODEV; } +static inline int zynqmp_pm_get_node_status(const u32 node, u32 *const status, + u32 *const requirements, + u32 *const usage) +{ + return -ENODEV; +} + static inline int zynqmp_pm_set_sd_config(u32 node, enum pm_sd_config_type config, u32 value) From ff1c629cea271f7cdfbbb57aba8456e4396faade Mon Sep 17 00:00:00 2001 From: Jay Buddhabhatti Date: Tue, 1 Jul 2025 05:38:49 -0700 Subject: [PATCH 002/114] firmware: xilinx: Add Versal NET platform compatible string Introduce a compatible string for the Versal NET platform which enables platform identification based on the compatible property for platform specific configurations. Signed-off-by: Jay Buddhabhatti Link: https://lore.kernel.org/r/20250701123851.1314531-2-jay.buddhabhatti@amd.com Signed-off-by: Michal Simek --- drivers/firmware/xilinx/zynqmp.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/firmware/xilinx/zynqmp.c b/drivers/firmware/xilinx/zynqmp.c index a17c806cd117..53b8c88b4178 100644 --- a/drivers/firmware/xilinx/zynqmp.c +++ b/drivers/firmware/xilinx/zynqmp.c @@ -2155,6 +2155,7 @@ static void zynqmp_firmware_sync_state(struct device *dev) static const struct of_device_id zynqmp_firmware_of_match[] = { {.compatible = "xlnx,zynqmp-firmware"}, {.compatible = "xlnx,versal-firmware"}, + {.compatible = "xlnx,versal-net-firmware"}, {}, }; MODULE_DEVICE_TABLE(of, zynqmp_firmware_of_match); From e66f4c35e375346943bfe2a0990e97253f74440f Mon Sep 17 00:00:00 2001 From: Jay Buddhabhatti Date: Tue, 1 Jul 2025 05:38:50 -0700 Subject: [PATCH 003/114] drivers: firmware: xilinx: Add unique family code for all platforms The family code is currently derived from the PMC_TAP_IDCODE register value, but there are issues where Versal, Versal NET, and future platforms share the same family code. Additionally for some platforms have identical subfamily code, making it challenging to differentiate between platforms based on the family and subfamily codes. To resolve this, a new family code member is added to the platform data, initialized with unique values. This change enables better platform distinction via the compatible string. Signed-off-by: Jay Buddhabhatti Link: https://lore.kernel.org/r/20250701123851.1314531-3-jay.buddhabhatti@amd.com Signed-off-by: Michal Simek --- drivers/firmware/xilinx/zynqmp.c | 32 +++++++++++++++++++++++++--- include/linux/firmware/xlnx-zynqmp.h | 5 +++++ 2 files changed, 34 insertions(+), 3 deletions(-) diff --git a/drivers/firmware/xilinx/zynqmp.c b/drivers/firmware/xilinx/zynqmp.c index 53b8c88b4178..2d250a16d3dd 100644 --- a/drivers/firmware/xilinx/zynqmp.c +++ b/drivers/firmware/xilinx/zynqmp.c @@ -72,6 +72,15 @@ struct pm_api_feature_data { struct hlist_node hentry; }; +struct platform_fw_data { + /* + * Family code for platform. + */ + const u32 family_code; +}; + +static struct platform_fw_data *active_platform_fw_data; + static const struct mfd_cell firmware_devs[] = { { .name = "zynqmp_power_controller", @@ -2052,6 +2061,11 @@ static int zynqmp_firmware_probe(struct platform_device *pdev) if (ret) return ret; + /* Get platform-specific firmware data from device tree match */ + active_platform_fw_data = (struct platform_fw_data *)device_get_match_data(dev); + if (!active_platform_fw_data) + return -EINVAL; + /* Get SiP SVC version number */ ret = zynqmp_pm_get_sip_svc_version(&sip_svc_version); if (ret) @@ -2152,10 +2166,22 @@ static void zynqmp_firmware_sync_state(struct device *dev) dev_warn(dev, "failed to release power management to firmware\n"); } +static const struct platform_fw_data platform_fw_data_versal = { + .family_code = PM_VERSAL_FAMILY_CODE, +}; + +static const struct platform_fw_data platform_fw_data_versal_net = { + .family_code = PM_VERSAL_NET_FAMILY_CODE, +}; + +static const struct platform_fw_data platform_fw_data_zynqmp = { + .family_code = PM_ZYNQMP_FAMILY_CODE, +}; + static const struct of_device_id zynqmp_firmware_of_match[] = { - {.compatible = "xlnx,zynqmp-firmware"}, - {.compatible = "xlnx,versal-firmware"}, - {.compatible = "xlnx,versal-net-firmware"}, + {.compatible = "xlnx,zynqmp-firmware", .data = &platform_fw_data_zynqmp}, + {.compatible = "xlnx,versal-firmware", .data = &platform_fw_data_versal}, + {.compatible = "xlnx,versal-net-firmware", .data = &platform_fw_data_versal_net}, {}, }; MODULE_DEVICE_TABLE(of, zynqmp_firmware_of_match); diff --git a/include/linux/firmware/xlnx-zynqmp.h b/include/linux/firmware/xlnx-zynqmp.h index 4699f50465f2..6458ef4e04e2 100644 --- a/include/linux/firmware/xlnx-zynqmp.h +++ b/include/linux/firmware/xlnx-zynqmp.h @@ -54,6 +54,11 @@ #define ZYNQMP_FAMILY_CODE 0x23 #define VERSAL_FAMILY_CODE 0x26 +/* Family codes */ +#define PM_ZYNQMP_FAMILY_CODE 0x1 /* ZynqMP family code */ +#define PM_VERSAL_FAMILY_CODE 0x2 /* Versal family code */ +#define PM_VERSAL_NET_FAMILY_CODE 0x3 /* Versal NET family code */ + /* When all subfamily of platform need to support */ #define ALL_SUB_FAMILY_CODE 0x00 #define VERSAL_SUB_FAMILY_CODE 0x01 From 25e3ae0ce364fa725a6eea68d63d6a2ee09e019f Mon Sep 17 00:00:00 2001 From: Jay Buddhabhatti Date: Tue, 1 Jul 2025 05:38:51 -0700 Subject: [PATCH 004/114] drivers: firmware: xilinx: Switch to new family code in zynqmp_pm_get_family_info() Currently, the family code and subfamily code are derived from the PMC_TAP_IDCODE register. Versal, Versal NET share the same family code. Also some platforms share the same subfamily code, making it difficult to distinguish between platforms. Update zynqmp_pm_get_family_info() to use IDs derived from the compatible string instead of silicon ID codes derived from PMC_TAP_IDCODE register. Signed-off-by: Jay Buddhabhatti Link: https://lore.kernel.org/r/20250701123851.1314531-4-jay.buddhabhatti@amd.com Signed-off-by: Michal Simek --- drivers/firmware/xilinx/zynqmp.c | 42 ++++++++++--------------- drivers/pinctrl/pinctrl-zynqmp.c | 7 ++--- drivers/soc/xilinx/xlnx_event_manager.c | 8 ++--- drivers/soc/xilinx/zynqmp_power.c | 10 +++--- include/linux/firmware/xlnx-zynqmp.h | 15 ++------- 5 files changed, 31 insertions(+), 51 deletions(-) diff --git a/drivers/firmware/xilinx/zynqmp.c b/drivers/firmware/xilinx/zynqmp.c index 2d250a16d3dd..835a50c5af46 100644 --- a/drivers/firmware/xilinx/zynqmp.c +++ b/drivers/firmware/xilinx/zynqmp.c @@ -473,8 +473,6 @@ int zynqmp_pm_invoke_fn(u32 pm_api_id, u32 *ret_payload, u32 num_args, ...) static u32 pm_api_version; static u32 pm_tz_version; -static u32 pm_family_code; -static u32 pm_sub_family_code; int zynqmp_pm_register_sgi(u32 sgi_num, u32 reset) { @@ -541,32 +539,18 @@ EXPORT_SYMBOL_GPL(zynqmp_pm_get_chipid); /** * zynqmp_pm_get_family_info() - Get family info of platform * @family: Returned family code value - * @subfamily: Returned sub-family code value * * Return: Returns status, either success or error+reason */ -int zynqmp_pm_get_family_info(u32 *family, u32 *subfamily) +int zynqmp_pm_get_family_info(u32 *family) { - u32 ret_payload[PAYLOAD_ARG_CNT]; - u32 idcode; - int ret; + if (!active_platform_fw_data) + return -ENODEV; - /* Check is family or sub-family code already received */ - if (pm_family_code && pm_sub_family_code) { - *family = pm_family_code; - *subfamily = pm_sub_family_code; - return 0; - } + if (!family) + return -EINVAL; - ret = zynqmp_pm_invoke_fn(PM_GET_CHIPID, ret_payload, 0); - if (ret < 0) - return ret; - - idcode = ret_payload[1]; - pm_family_code = FIELD_GET(FAMILY_CODE_MASK, idcode); - pm_sub_family_code = FIELD_GET(SUB_FAMILY_CODE_MASK, idcode); - *family = pm_family_code; - *subfamily = pm_sub_family_code; + *family = active_platform_fw_data->family_code; return 0; } @@ -1247,8 +1231,13 @@ int zynqmp_pm_pinctrl_set_config(const u32 pin, const u32 param, u32 value) { int ret; + u32 pm_family_code; - if (pm_family_code == ZYNQMP_FAMILY_CODE && + ret = zynqmp_pm_get_family_info(&pm_family_code); + if (ret) + return ret; + + if (pm_family_code == PM_ZYNQMP_FAMILY_CODE && param == PM_PINCTRL_CONFIG_TRI_STATE) { ret = zynqmp_pm_feature(PM_PINCTRL_CONFIG_PARAM_SET); if (ret < PM_PINCTRL_PARAM_SET_VERSION) { @@ -2055,6 +2044,7 @@ static int zynqmp_firmware_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct zynqmp_devinfo *devinfo; + u32 pm_family_code; int ret; ret = get_set_conduit_method(dev->of_node); @@ -2098,8 +2088,8 @@ static int zynqmp_firmware_probe(struct platform_device *pdev) pr_info("%s Platform Management API v%d.%d\n", __func__, pm_api_version >> 16, pm_api_version & 0xFFFF); - /* Get the Family code and sub family code of platform */ - ret = zynqmp_pm_get_family_info(&pm_family_code, &pm_sub_family_code); + /* Get the Family code of platform */ + ret = zynqmp_pm_get_family_info(&pm_family_code); if (ret < 0) return ret; @@ -2126,7 +2116,7 @@ static int zynqmp_firmware_probe(struct platform_device *pdev) zynqmp_pm_api_debugfs_init(); - if (pm_family_code == VERSAL_FAMILY_CODE) { + if (pm_family_code != PM_ZYNQMP_FAMILY_CODE) { em_dev = platform_device_register_data(&pdev->dev, "xlnx_event_manager", -1, NULL, 0); if (IS_ERR(em_dev)) diff --git a/drivers/pinctrl/pinctrl-zynqmp.c b/drivers/pinctrl/pinctrl-zynqmp.c index fddf0fef4b13..71eaac81deb1 100644 --- a/drivers/pinctrl/pinctrl-zynqmp.c +++ b/drivers/pinctrl/pinctrl-zynqmp.c @@ -100,7 +100,6 @@ struct zynqmp_pctrl_group { static struct pinctrl_desc zynqmp_desc; static u32 family_code; -static u32 sub_family_code; static int zynqmp_pctrl_get_groups_count(struct pinctrl_dev *pctldev) { @@ -605,7 +604,7 @@ static int zynqmp_pinctrl_prepare_func_groups(struct device *dev, u32 fid, return -ENOMEM; for (pin = 0; pin < groups[resp[i]].npins; pin++) { - if (family_code == ZYNQMP_FAMILY_CODE) + if (family_code == PM_ZYNQMP_FAMILY_CODE) __set_bit(groups[resp[i]].pins[pin], used_pins); else __set_bit((u8)groups[resp[i]].pins[pin] - 1, used_pins); @@ -958,11 +957,11 @@ static int zynqmp_pinctrl_probe(struct platform_device *pdev) if (!pctrl) return -ENOMEM; - ret = zynqmp_pm_get_family_info(&family_code, &sub_family_code); + ret = zynqmp_pm_get_family_info(&family_code); if (ret < 0) return ret; - if (family_code == ZYNQMP_FAMILY_CODE) { + if (family_code == PM_ZYNQMP_FAMILY_CODE) { ret = zynqmp_pinctrl_prepare_pin_desc(&pdev->dev, &zynqmp_desc.pins, &zynqmp_desc.npins); } else { diff --git a/drivers/soc/xilinx/xlnx_event_manager.c b/drivers/soc/xilinx/xlnx_event_manager.c index a572d15f6161..6fdf4d14b7e7 100644 --- a/drivers/soc/xilinx/xlnx_event_manager.c +++ b/drivers/soc/xilinx/xlnx_event_manager.c @@ -77,17 +77,17 @@ struct registered_event_data { static bool xlnx_is_error_event(const u32 node_id) { - u32 pm_family_code, pm_sub_family_code; + u32 pm_family_code; - zynqmp_pm_get_family_info(&pm_family_code, &pm_sub_family_code); + zynqmp_pm_get_family_info(&pm_family_code); - if (pm_sub_family_code == VERSAL_SUB_FAMILY_CODE) { + if (pm_family_code == PM_VERSAL_FAMILY_CODE) { if (node_id == VERSAL_EVENT_ERROR_PMC_ERR1 || node_id == VERSAL_EVENT_ERROR_PMC_ERR2 || node_id == VERSAL_EVENT_ERROR_PSM_ERR1 || node_id == VERSAL_EVENT_ERROR_PSM_ERR2) return true; - } else { + } else if (pm_family_code == PM_VERSAL_NET_FAMILY_CODE) { if (node_id == VERSAL_NET_EVENT_ERROR_PMC_ERR1 || node_id == VERSAL_NET_EVENT_ERROR_PMC_ERR2 || node_id == VERSAL_NET_EVENT_ERROR_PMC_ERR3 || diff --git a/drivers/soc/xilinx/zynqmp_power.c b/drivers/soc/xilinx/zynqmp_power.c index ae59bf16659a..9b7b2858b22a 100644 --- a/drivers/soc/xilinx/zynqmp_power.c +++ b/drivers/soc/xilinx/zynqmp_power.c @@ -285,7 +285,7 @@ static int register_event(struct device *dev, const enum pm_api_cb_id cb_type, c static int zynqmp_pm_probe(struct platform_device *pdev) { int ret, irq; - u32 pm_api_version, pm_family_code, pm_sub_family_code, node_id; + u32 pm_api_version, pm_family_code, node_id; struct mbox_client *client; ret = zynqmp_pm_get_api_version(&pm_api_version); @@ -315,14 +315,16 @@ static int zynqmp_pm_probe(struct platform_device *pdev) INIT_WORK(&zynqmp_pm_init_suspend_work->callback_work, zynqmp_pm_init_suspend_work_fn); - ret = zynqmp_pm_get_family_info(&pm_family_code, &pm_sub_family_code); + ret = zynqmp_pm_get_family_info(&pm_family_code); if (ret < 0) return ret; - if (pm_sub_family_code == VERSALNET_SUB_FAMILY_CODE) + if (pm_family_code == PM_VERSAL_NET_FAMILY_CODE) node_id = PM_DEV_ACPU_0_0; - else + else if (pm_family_code == PM_VERSAL_FAMILY_CODE) node_id = PM_DEV_ACPU_0; + else + return -ENODEV; ret = register_event(&pdev->dev, PM_NOTIFY_CB, node_id, EVENT_SUBSYSTEM_RESTART, false, subsystem_restart_event_callback); diff --git a/include/linux/firmware/xlnx-zynqmp.h b/include/linux/firmware/xlnx-zynqmp.h index 6458ef4e04e2..be6817ac5120 100644 --- a/include/linux/firmware/xlnx-zynqmp.h +++ b/include/linux/firmware/xlnx-zynqmp.h @@ -51,22 +51,11 @@ #define PM_PINCTRL_PARAM_SET_VERSION 2 -#define ZYNQMP_FAMILY_CODE 0x23 -#define VERSAL_FAMILY_CODE 0x26 - /* Family codes */ #define PM_ZYNQMP_FAMILY_CODE 0x1 /* ZynqMP family code */ #define PM_VERSAL_FAMILY_CODE 0x2 /* Versal family code */ #define PM_VERSAL_NET_FAMILY_CODE 0x3 /* Versal NET family code */ -/* When all subfamily of platform need to support */ -#define ALL_SUB_FAMILY_CODE 0x00 -#define VERSAL_SUB_FAMILY_CODE 0x01 -#define VERSALNET_SUB_FAMILY_CODE 0x03 - -#define FAMILY_CODE_MASK GENMASK(27, 21) -#define SUB_FAMILY_CODE_MASK GENMASK(20, 19) - #define API_ID_MASK GENMASK(7, 0) #define MODULE_ID_MASK GENMASK(11, 8) #define PLM_MODULE_ID_MASK GENMASK(15, 8) @@ -570,7 +559,7 @@ int zynqmp_pm_invoke_fw_fn(u32 pm_api_id, u32 *ret_payload, u32 num_args, ...); #if IS_REACHABLE(CONFIG_ZYNQMP_FIRMWARE) int zynqmp_pm_get_api_version(u32 *version); int zynqmp_pm_get_chipid(u32 *idcode, u32 *version); -int zynqmp_pm_get_family_info(u32 *family, u32 *subfamily); +int zynqmp_pm_get_family_info(u32 *family); int zynqmp_pm_query_data(struct zynqmp_pm_query_data qdata, u32 *out); int zynqmp_pm_clock_enable(u32 clock_id); int zynqmp_pm_clock_disable(u32 clock_id); @@ -651,7 +640,7 @@ static inline int zynqmp_pm_get_chipid(u32 *idcode, u32 *version) return -ENODEV; } -static inline int zynqmp_pm_get_family_info(u32 *family, u32 *subfamily) +static inline int zynqmp_pm_get_family_info(u32 *family) { return -ENODEV; } From da722f1c9d605dffaabe2526e3e4cae3ff53401d Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Thu, 11 Sep 2025 11:43:12 +0200 Subject: [PATCH 005/114] memory: tegra124-emc: Simplify return of emc_init() emc_init() returns always success, so just drop the return value to simplify it. Reviewed-by: Jon Hunter Signed-off-by: Krzysztof Kozlowski --- drivers/memory/tegra/tegra124-emc.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/drivers/memory/tegra/tegra124-emc.c b/drivers/memory/tegra/tegra124-emc.c index 03f1daa2d132..9aad02901613 100644 --- a/drivers/memory/tegra/tegra124-emc.c +++ b/drivers/memory/tegra/tegra124-emc.c @@ -896,7 +896,7 @@ static void emc_read_current_timing(struct tegra_emc *emc, timing->emc_mode_reset = 0; } -static int emc_init(struct tegra_emc *emc) +static void emc_init(struct tegra_emc *emc) { emc->dram_type = readl(emc->regs + EMC_FBIO_CFG5); @@ -913,8 +913,6 @@ static int emc_init(struct tegra_emc *emc) emc->dram_num = tegra_mc_get_emem_device_count(emc->mc); emc_read_current_timing(emc, &emc->last_timing); - - return 0; } static int load_one_timing_from_dt(struct tegra_emc *emc, @@ -1472,11 +1470,7 @@ static int tegra_emc_probe(struct platform_device *pdev) ram_code); } - err = emc_init(emc); - if (err) { - dev_err(&pdev->dev, "EMC initialization failed: %d\n", err); - return err; - } + emc_init(emc); platform_set_drvdata(pdev, emc); From 1c9cce8a0e0bd4f383a04655bd3a4f650fc1f20f Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Thu, 11 Sep 2025 11:43:13 +0200 Subject: [PATCH 006/114] memory: tegra124-emc: Do not print error on icc_node_create() failure MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit icc_node_create() is alloc-like function, so no need to print error messages on its failure. Dropping one label makes the code a bit simpler. Reviewed-by: Jon Hunter Signed-off-by: Krzysztof Kozlowski --- drivers/memory/tegra/tegra124-emc.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/drivers/memory/tegra/tegra124-emc.c b/drivers/memory/tegra/tegra124-emc.c index 9aad02901613..f3372bd78ce8 100644 --- a/drivers/memory/tegra/tegra124-emc.c +++ b/drivers/memory/tegra/tegra124-emc.c @@ -1350,10 +1350,8 @@ static int tegra_emc_interconnect_init(struct tegra_emc *emc) /* create External Memory Controller node */ node = icc_node_create(TEGRA_ICC_EMC); - if (IS_ERR(node)) { - err = PTR_ERR(node); - goto err_msg; - } + if (IS_ERR(node)) + return PTR_ERR(node); node->name = "External Memory Controller"; icc_node_add(node, &emc->provider); @@ -1381,7 +1379,6 @@ static int tegra_emc_interconnect_init(struct tegra_emc *emc) remove_nodes: icc_nodes_remove(&emc->provider); -err_msg: dev_err(emc->dev, "failed to initialize ICC: %d\n", err); return err; From 515498a3f58485321a1fa03b4eb5e6208a816e06 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Thu, 11 Sep 2025 11:43:14 +0200 Subject: [PATCH 007/114] memory: tegra186-emc: Do not print error on icc_node_create() failure MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit icc_node_create() is alloc-like function, so no need to print error messages on its failure. Dropping one label makes the code a bit simpler. Reviewed-by: Jon Hunter Signed-off-by: Krzysztof Kozlowski --- drivers/memory/tegra/tegra186-emc.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/drivers/memory/tegra/tegra186-emc.c b/drivers/memory/tegra/tegra186-emc.c index d6cd90c7ad53..00baa7ab8921 100644 --- a/drivers/memory/tegra/tegra186-emc.c +++ b/drivers/memory/tegra/tegra186-emc.c @@ -273,10 +273,8 @@ static int tegra_emc_interconnect_init(struct tegra186_emc *emc) /* create External Memory Controller node */ node = icc_node_create(TEGRA_ICC_EMC); - if (IS_ERR(node)) { - err = PTR_ERR(node); - goto err_msg; - } + if (IS_ERR(node)) + return PTR_ERR(node); node->name = "External Memory Controller"; icc_node_add(node, &emc->provider); @@ -304,7 +302,6 @@ static int tegra_emc_interconnect_init(struct tegra186_emc *emc) remove_nodes: icc_nodes_remove(&emc->provider); -err_msg: dev_err(emc->dev, "failed to initialize ICC: %d\n", err); return err; From e215d91d66a2c8c7ed8524ce6b261340149c10f0 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Thu, 11 Sep 2025 11:43:15 +0200 Subject: [PATCH 008/114] memory: tegra20-emc: Do not print error on icc_node_create() failure MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit icc_node_create() is alloc-like function, so no need to print error messages on its failure. Dropping one label makes the code a bit simpler. Reviewed-by: Jon Hunter Signed-off-by: Krzysztof Kozlowski --- drivers/memory/tegra/tegra20-emc.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/drivers/memory/tegra/tegra20-emc.c b/drivers/memory/tegra/tegra20-emc.c index 44ac55feacd3..a34636a1c4c5 100644 --- a/drivers/memory/tegra/tegra20-emc.c +++ b/drivers/memory/tegra/tegra20-emc.c @@ -1022,10 +1022,8 @@ static int tegra_emc_interconnect_init(struct tegra_emc *emc) /* create External Memory Controller node */ node = icc_node_create(TEGRA_ICC_EMC); - if (IS_ERR(node)) { - err = PTR_ERR(node); - goto err_msg; - } + if (IS_ERR(node)) + return PTR_ERR(node); node->name = "External Memory Controller"; icc_node_add(node, &emc->provider); @@ -1053,7 +1051,6 @@ static int tegra_emc_interconnect_init(struct tegra_emc *emc) remove_nodes: icc_nodes_remove(&emc->provider); -err_msg: dev_err(emc->dev, "failed to initialize ICC: %d\n", err); return err; From c0ca941c93527a9e96f3ba58c0970cdf94670203 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Thu, 11 Sep 2025 11:43:16 +0200 Subject: [PATCH 009/114] memory: tegra30-emc: Do not print error on icc_node_create() failure MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit icc_node_create() is alloc-like function, so no need to print error messages on its failure. Dropping one label makes the code a bit simpler. Reviewed-by: Jon Hunter Signed-off-by: Krzysztof Kozlowski --- drivers/memory/tegra/tegra30-emc.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/drivers/memory/tegra/tegra30-emc.c b/drivers/memory/tegra/tegra30-emc.c index 921dce1b8bc6..c96aa63a5aa0 100644 --- a/drivers/memory/tegra/tegra30-emc.c +++ b/drivers/memory/tegra/tegra30-emc.c @@ -1534,10 +1534,8 @@ static int tegra_emc_interconnect_init(struct tegra_emc *emc) /* create External Memory Controller node */ node = icc_node_create(TEGRA_ICC_EMC); - if (IS_ERR(node)) { - err = PTR_ERR(node); - goto err_msg; - } + if (IS_ERR(node)) + return PTR_ERR(node); node->name = "External Memory Controller"; icc_node_add(node, &emc->provider); @@ -1565,7 +1563,6 @@ static int tegra_emc_interconnect_init(struct tegra_emc *emc) remove_nodes: icc_nodes_remove(&emc->provider); -err_msg: dev_err(emc->dev, "failed to initialize ICC: %d\n", err); return err; From db2bd7ab1ae8c1f32a553b6eb36d6fecea41aab5 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Thu, 11 Sep 2025 11:43:17 +0200 Subject: [PATCH 010/114] memory: tegra30-emc: Simplify and handle deferred probe with dev_err_probe() Certain calls, like clk_get, can cause probe deferral and driver should handle it. Use dev_err_probe() to fix that and also change other non-deferred errors cases to make the code simpler. Reviewed-by: Jon Hunter Signed-off-by: Krzysztof Kozlowski --- drivers/memory/tegra/tegra30-emc.c | 22 ++++++++-------------- 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/drivers/memory/tegra/tegra30-emc.c b/drivers/memory/tegra/tegra30-emc.c index c96aa63a5aa0..cca386af423e 100644 --- a/drivers/memory/tegra/tegra30-emc.c +++ b/drivers/memory/tegra/tegra30-emc.c @@ -1563,9 +1563,8 @@ static int tegra_emc_interconnect_init(struct tegra_emc *emc) remove_nodes: icc_nodes_remove(&emc->provider); - dev_err(emc->dev, "failed to initialize ICC: %d\n", err); - return err; + return dev_err_probe(emc->dev, err, "failed to initialize ICC\n"); } static void devm_tegra_emc_unset_callback(void *data) @@ -1592,16 +1591,13 @@ static int tegra_emc_init_clk(struct tegra_emc *emc) return err; emc->clk = devm_clk_get(emc->dev, NULL); - if (IS_ERR(emc->clk)) { - dev_err(emc->dev, "failed to get EMC clock: %pe\n", emc->clk); - return PTR_ERR(emc->clk); - } + if (IS_ERR(emc->clk)) + return dev_err_probe(emc->dev, PTR_ERR(emc->clk), + "failed to get EMC clock\n"); err = clk_notifier_register(emc->clk, &emc->clk_nb); - if (err) { - dev_err(emc->dev, "failed to register clk notifier: %d\n", err); - return err; - } + if (err) + return dev_err_probe(emc->dev, err, "failed to register clk notifier\n"); err = devm_add_action_or_reset(emc->dev, devm_tegra_emc_unreg_clk_notifier, emc); @@ -1654,10 +1650,8 @@ static int tegra_emc_probe(struct platform_device *pdev) err = devm_request_irq(&pdev->dev, emc->irq, tegra_emc_isr, 0, dev_name(&pdev->dev), emc); - if (err) { - dev_err(&pdev->dev, "failed to request irq: %d\n", err); - return err; - } + if (err) + return dev_err_probe(&pdev->dev, err, "failed to request irq\n"); err = tegra_emc_init_clk(emc); if (err) From 57c9f6e29ccd44db882b943df2e72a4e54ebe0e3 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Thu, 11 Sep 2025 11:43:18 +0200 Subject: [PATCH 011/114] memory: tegra20-emc: Simplify and handle deferred probe with dev_err_probe() Certain calls, like clk_get, can cause probe deferral and driver should handle it. Use dev_err_probe() to fix that and also change other non-deferred errors cases to make the code simpler. Also fix missing new line in error message of devm_devfreq_add_device(). Reviewed-by: Jon Hunter Signed-off-by: Krzysztof Kozlowski --- drivers/memory/tegra/tegra20-emc.c | 23 +++++++++-------------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/drivers/memory/tegra/tegra20-emc.c b/drivers/memory/tegra/tegra20-emc.c index a34636a1c4c5..18e266dde5d2 100644 --- a/drivers/memory/tegra/tegra20-emc.c +++ b/drivers/memory/tegra/tegra20-emc.c @@ -1051,9 +1051,8 @@ static int tegra_emc_interconnect_init(struct tegra_emc *emc) remove_nodes: icc_nodes_remove(&emc->provider); - dev_err(emc->dev, "failed to initialize ICC: %d\n", err); - return err; + return dev_err_probe(emc->dev, err, "failed to initialize ICC\n"); } static void devm_tegra_emc_unset_callback(void *data) @@ -1080,16 +1079,13 @@ static int tegra_emc_init_clk(struct tegra_emc *emc) return err; emc->clk = devm_clk_get(emc->dev, NULL); - if (IS_ERR(emc->clk)) { - dev_err(emc->dev, "failed to get EMC clock: %pe\n", emc->clk); - return PTR_ERR(emc->clk); - } + if (IS_ERR(emc->clk)) + return dev_err_probe(emc->dev, PTR_ERR(emc->clk), + "failed to get EMC clock\n"); err = clk_notifier_register(emc->clk, &emc->clk_nb); - if (err) { - dev_err(emc->dev, "failed to register clk notifier: %d\n", err); - return err; - } + if (err) + return dev_err_probe(emc->dev, err, "failed to register clk notifier\n"); err = devm_add_action_or_reset(emc->dev, devm_tegra_emc_unreg_clk_notifier, emc); @@ -1172,10 +1168,9 @@ static int tegra_emc_devfreq_init(struct tegra_emc *emc) devfreq = devm_devfreq_add_device(emc->dev, &tegra_emc_devfreq_profile, DEVFREQ_GOV_SIMPLE_ONDEMAND, &emc->ondemand_data); - if (IS_ERR(devfreq)) { - dev_err(emc->dev, "failed to initialize devfreq: %pe", devfreq); - return PTR_ERR(devfreq); - } + if (IS_ERR(devfreq)) + return dev_err_probe(emc->dev, PTR_ERR(devfreq), + "failed to initialize devfreq\n"); return 0; } From a52ddb98a674b01b6b5f2da1ed70a9f30d539f6b Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Thu, 11 Sep 2025 11:43:19 +0200 Subject: [PATCH 012/114] memory: tegra186-emc: Simplify and handle deferred probe with dev_err_probe() Certain calls, like clk_get, can cause probe deferral and driver should handle it. Use dev_err_probe() to fix that and also change other non-deferred errors cases to make the code simpler. Reviewed-by: Jon Hunter Signed-off-by: Krzysztof Kozlowski --- drivers/memory/tegra/tegra186-emc.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/drivers/memory/tegra/tegra186-emc.c b/drivers/memory/tegra/tegra186-emc.c index 00baa7ab8921..a0de80afe3e9 100644 --- a/drivers/memory/tegra/tegra186-emc.c +++ b/drivers/memory/tegra/tegra186-emc.c @@ -302,9 +302,8 @@ static int tegra_emc_interconnect_init(struct tegra186_emc *emc) remove_nodes: icc_nodes_remove(&emc->provider); - dev_err(emc->dev, "failed to initialize ICC: %d\n", err); - return err; + return dev_err_probe(emc->dev, err, "failed to initialize ICC\n"); } static int tegra186_emc_probe(struct platform_device *pdev) @@ -319,14 +318,13 @@ static int tegra186_emc_probe(struct platform_device *pdev) emc->bpmp = tegra_bpmp_get(&pdev->dev); if (IS_ERR(emc->bpmp)) - return dev_err_probe(&pdev->dev, PTR_ERR(emc->bpmp), "failed to get BPMP\n"); + return dev_err_probe(&pdev->dev, PTR_ERR(emc->bpmp), + "failed to get BPMP\n"); emc->clk = devm_clk_get(&pdev->dev, "emc"); - if (IS_ERR(emc->clk)) { - err = PTR_ERR(emc->clk); - dev_err(&pdev->dev, "failed to get EMC clock: %d\n", err); - goto put_bpmp; - } + if (IS_ERR(emc->clk)) + return dev_err_probe(&pdev->dev, PTR_ERR(emc->clk), + "failed to get EMC clock\n"); platform_set_drvdata(pdev, emc); emc->dev = &pdev->dev; From f398631b769c43fd3c575ad6270bb0109a04b85a Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Thu, 11 Sep 2025 11:43:20 +0200 Subject: [PATCH 013/114] memory: tegra124-emc: Simplify and handle deferred probe with dev_err_probe() Certain calls, like clk_get, can cause probe deferral and driver should handle it. Use dev_err_probe() to fix that and also change other non-deferred errors cases to make the code simpler. Reviewed-by: Jon Hunter Signed-off-by: Krzysztof Kozlowski --- drivers/memory/tegra/tegra124-emc.c | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/drivers/memory/tegra/tegra124-emc.c b/drivers/memory/tegra/tegra124-emc.c index f3372bd78ce8..f4d703103d9c 100644 --- a/drivers/memory/tegra/tegra124-emc.c +++ b/drivers/memory/tegra/tegra124-emc.c @@ -1379,9 +1379,8 @@ static int tegra_emc_interconnect_init(struct tegra_emc *emc) remove_nodes: icc_nodes_remove(&emc->provider); - dev_err(emc->dev, "failed to initialize ICC: %d\n", err); - return err; + return dev_err_probe(emc->dev, err, "failed to initialize ICC\n"); } static int tegra_emc_opp_table_init(struct tegra_emc *emc) @@ -1390,18 +1389,18 @@ static int tegra_emc_opp_table_init(struct tegra_emc *emc) int opp_token, err; err = dev_pm_opp_set_supported_hw(emc->dev, &hw_version, 1); - if (err < 0) { - dev_err(emc->dev, "failed to set OPP supported HW: %d\n", err); - return err; - } + if (err < 0) + return dev_err_probe(emc->dev, err, "failed to set OPP supported HW\n"); + opp_token = err; err = dev_pm_opp_of_add_table(emc->dev); if (err) { if (err == -ENODEV) - dev_err(emc->dev, "OPP table not found, please update your device tree\n"); + dev_err_probe(emc->dev, err, + "OPP table not found, please update your device tree\n"); else - dev_err(emc->dev, "failed to add OPP table: %d\n", err); + dev_err_probe(emc->dev, err, "failed to add OPP table\n"); goto put_hw_table; } @@ -1412,7 +1411,7 @@ static int tegra_emc_opp_table_init(struct tegra_emc *emc) /* first dummy rate-set initializes voltage state */ err = dev_pm_opp_set_rate(emc->dev, clk_get_rate(emc->clk)); if (err) { - dev_err(emc->dev, "failed to initialize OPP clock: %d\n", err); + dev_err_probe(emc->dev, err, "failed to initialize OPP clock\n"); goto remove_table; } @@ -1480,11 +1479,9 @@ static int tegra_emc_probe(struct platform_device *pdev) return err; emc->clk = devm_clk_get(&pdev->dev, "emc"); - if (IS_ERR(emc->clk)) { - err = PTR_ERR(emc->clk); - dev_err(&pdev->dev, "failed to get EMC clock: %d\n", err); - return err; - } + if (IS_ERR(emc->clk)) + return dev_err_probe(&pdev->dev, PTR_ERR(emc->clk), + "failed to get EMC clock\n"); err = tegra_emc_opp_table_init(emc); if (err) From e6e50496b7e77613ed5b610877f34e1197ce62da Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Thu, 11 Sep 2025 11:43:21 +0200 Subject: [PATCH 014/114] memory: tegra124-emc: Add the SoC model prefix to functions Replace "tegra_emc" with "tegra124_emc" in all functions to: 1. Avoid name clashing with other Tegra EMC drivers which makes it easier to jump to function definitions, 2. Decode the calltraces a bit easier, 3. Unify with other Tegra MC and EMC drivers, which use the SoC model prefixes. No functional impact. Reviewed-by: Jon Hunter Signed-off-by: Krzysztof Kozlowski --- drivers/memory/tegra/tegra124-emc.c | 98 ++++++++++++++--------------- 1 file changed, 49 insertions(+), 49 deletions(-) diff --git a/drivers/memory/tegra/tegra124-emc.c b/drivers/memory/tegra/tegra124-emc.c index f4d703103d9c..9978ff911c47 100644 --- a/drivers/memory/tegra/tegra124-emc.c +++ b/drivers/memory/tegra/tegra124-emc.c @@ -571,8 +571,8 @@ static void emc_seq_wait_clkchange(struct tegra_emc *emc) dev_err(emc->dev, "clock change timed out\n"); } -static struct emc_timing *tegra_emc_find_timing(struct tegra_emc *emc, - unsigned long rate) +static struct emc_timing *tegra124_emc_find_timing(struct tegra_emc *emc, + unsigned long rate) { struct emc_timing *timing = NULL; unsigned int i; @@ -592,10 +592,10 @@ static struct emc_timing *tegra_emc_find_timing(struct tegra_emc *emc, return timing; } -static int tegra_emc_prepare_timing_change(struct tegra_emc *emc, - unsigned long rate) +static int tegra124_emc_prepare_timing_change(struct tegra_emc *emc, + unsigned long rate) { - struct emc_timing *timing = tegra_emc_find_timing(emc, rate); + struct emc_timing *timing = tegra124_emc_find_timing(emc, rate); struct emc_timing *last = &emc->last_timing; enum emc_dll_change dll_change; unsigned int pre_wait = 0; @@ -820,10 +820,10 @@ static int tegra_emc_prepare_timing_change(struct tegra_emc *emc, return 0; } -static void tegra_emc_complete_timing_change(struct tegra_emc *emc, - unsigned long rate) +static void tegra124_emc_complete_timing_change(struct tegra_emc *emc, + unsigned long rate) { - struct emc_timing *timing = tegra_emc_find_timing(emc, rate); + struct emc_timing *timing = tegra124_emc_find_timing(emc, rate); struct emc_timing *last = &emc->last_timing; u32 val; @@ -986,8 +986,8 @@ static int cmp_timings(const void *_a, const void *_b) return 1; } -static int tegra_emc_load_timings_from_dt(struct tegra_emc *emc, - struct device_node *node) +static int tegra124_emc_load_timings_from_dt(struct tegra_emc *emc, + struct device_node *node) { int child_count = of_get_child_count(node); struct emc_timing *timing; @@ -1015,15 +1015,15 @@ static int tegra_emc_load_timings_from_dt(struct tegra_emc *emc, return 0; } -static const struct of_device_id tegra_emc_of_match[] = { +static const struct of_device_id tegra124_emc_of_match[] = { { .compatible = "nvidia,tegra124-emc" }, { .compatible = "nvidia,tegra132-emc" }, {} }; -MODULE_DEVICE_TABLE(of, tegra_emc_of_match); +MODULE_DEVICE_TABLE(of, tegra124_emc_of_match); static struct device_node * -tegra_emc_find_node_by_ram_code(struct device_node *node, u32 ram_code) +tegra124_emc_find_node_by_ram_code(struct device_node *node, u32 ram_code) { struct device_node *np; int err; @@ -1041,7 +1041,7 @@ tegra_emc_find_node_by_ram_code(struct device_node *node, u32 ram_code) return NULL; } -static void tegra_emc_rate_requests_init(struct tegra_emc *emc) +static void tegra124_emc_rate_requests_init(struct tegra_emc *emc) { unsigned int i; @@ -1143,7 +1143,7 @@ static int emc_set_max_rate(struct tegra_emc *emc, unsigned long rate, * valid range. */ -static bool tegra_emc_validate_rate(struct tegra_emc *emc, unsigned long rate) +static bool tegra124_emc_validate_rate(struct tegra_emc *emc, unsigned long rate) { unsigned int i; @@ -1154,8 +1154,8 @@ static bool tegra_emc_validate_rate(struct tegra_emc *emc, unsigned long rate) return false; } -static int tegra_emc_debug_available_rates_show(struct seq_file *s, - void *data) +static int tegra124_emc_debug_available_rates_show(struct seq_file *s, + void *data) { struct tegra_emc *emc = s->private; const char *prefix = ""; @@ -1171,9 +1171,9 @@ static int tegra_emc_debug_available_rates_show(struct seq_file *s, return 0; } -DEFINE_SHOW_ATTRIBUTE(tegra_emc_debug_available_rates); +DEFINE_SHOW_ATTRIBUTE(tegra124_emc_debug_available_rates); -static int tegra_emc_debug_min_rate_get(void *data, u64 *rate) +static int tegra124_emc_debug_min_rate_get(void *data, u64 *rate) { struct tegra_emc *emc = data; @@ -1182,12 +1182,12 @@ static int tegra_emc_debug_min_rate_get(void *data, u64 *rate) return 0; } -static int tegra_emc_debug_min_rate_set(void *data, u64 rate) +static int tegra124_emc_debug_min_rate_set(void *data, u64 rate) { struct tegra_emc *emc = data; int err; - if (!tegra_emc_validate_rate(emc, rate)) + if (!tegra124_emc_validate_rate(emc, rate)) return -EINVAL; err = emc_set_min_rate(emc, rate, EMC_RATE_DEBUG); @@ -1199,11 +1199,11 @@ static int tegra_emc_debug_min_rate_set(void *data, u64 rate) return 0; } -DEFINE_DEBUGFS_ATTRIBUTE(tegra_emc_debug_min_rate_fops, - tegra_emc_debug_min_rate_get, - tegra_emc_debug_min_rate_set, "%llu\n"); +DEFINE_DEBUGFS_ATTRIBUTE(tegra124_emc_debug_min_rate_fops, + tegra124_emc_debug_min_rate_get, + tegra124_emc_debug_min_rate_set, "%llu\n"); -static int tegra_emc_debug_max_rate_get(void *data, u64 *rate) +static int tegra124_emc_debug_max_rate_get(void *data, u64 *rate) { struct tegra_emc *emc = data; @@ -1212,12 +1212,12 @@ static int tegra_emc_debug_max_rate_get(void *data, u64 *rate) return 0; } -static int tegra_emc_debug_max_rate_set(void *data, u64 rate) +static int tegra124_emc_debug_max_rate_set(void *data, u64 rate) { struct tegra_emc *emc = data; int err; - if (!tegra_emc_validate_rate(emc, rate)) + if (!tegra124_emc_validate_rate(emc, rate)) return -EINVAL; err = emc_set_max_rate(emc, rate, EMC_RATE_DEBUG); @@ -1229,9 +1229,9 @@ static int tegra_emc_debug_max_rate_set(void *data, u64 rate) return 0; } -DEFINE_DEBUGFS_ATTRIBUTE(tegra_emc_debug_max_rate_fops, - tegra_emc_debug_max_rate_get, - tegra_emc_debug_max_rate_set, "%llu\n"); +DEFINE_DEBUGFS_ATTRIBUTE(tegra124_emc_debug_max_rate_fops, + tegra124_emc_debug_max_rate_get, + tegra124_emc_debug_max_rate_set, "%llu\n"); static void emc_debugfs_init(struct device *dev, struct tegra_emc *emc) { @@ -1266,11 +1266,11 @@ static void emc_debugfs_init(struct device *dev, struct tegra_emc *emc) emc->debugfs.root = debugfs_create_dir("emc", NULL); debugfs_create_file("available_rates", 0444, emc->debugfs.root, emc, - &tegra_emc_debug_available_rates_fops); + &tegra124_emc_debug_available_rates_fops); debugfs_create_file("min_rate", 0644, emc->debugfs.root, - emc, &tegra_emc_debug_min_rate_fops); + emc, &tegra124_emc_debug_min_rate_fops); debugfs_create_file("max_rate", 0644, emc->debugfs.root, - emc, &tegra_emc_debug_max_rate_fops); + emc, &tegra124_emc_debug_max_rate_fops); } static inline struct tegra_emc * @@ -1334,7 +1334,7 @@ static int emc_icc_set(struct icc_node *src, struct icc_node *dst) return 0; } -static int tegra_emc_interconnect_init(struct tegra_emc *emc) +static int tegra124_emc_interconnect_init(struct tegra_emc *emc) { const struct tegra_mc_soc *soc = emc->mc->soc; struct icc_node *node; @@ -1383,7 +1383,7 @@ static int tegra_emc_interconnect_init(struct tegra_emc *emc) return dev_err_probe(emc->dev, err, "failed to initialize ICC\n"); } -static int tegra_emc_opp_table_init(struct tegra_emc *emc) +static int tegra124_emc_opp_table_init(struct tegra_emc *emc) { u32 hw_version = BIT(tegra_sku_info.soc_speedo_id); int opp_token, err; @@ -1425,12 +1425,12 @@ static int tegra_emc_opp_table_init(struct tegra_emc *emc) return err; } -static void devm_tegra_emc_unset_callback(void *data) +static void devm_tegra124_emc_unset_callback(void *data) { tegra124_clk_set_emc_callbacks(NULL, NULL); } -static int tegra_emc_probe(struct platform_device *pdev) +static int tegra124_emc_probe(struct platform_device *pdev) { struct device_node *np; struct tegra_emc *emc; @@ -1454,9 +1454,9 @@ static int tegra_emc_probe(struct platform_device *pdev) ram_code = tegra_read_ram_code(); - np = tegra_emc_find_node_by_ram_code(pdev->dev.of_node, ram_code); + np = tegra124_emc_find_node_by_ram_code(pdev->dev.of_node, ram_code); if (np) { - err = tegra_emc_load_timings_from_dt(emc, np); + err = tegra124_emc_load_timings_from_dt(emc, np); of_node_put(np); if (err) return err; @@ -1470,10 +1470,10 @@ static int tegra_emc_probe(struct platform_device *pdev) platform_set_drvdata(pdev, emc); - tegra124_clk_set_emc_callbacks(tegra_emc_prepare_timing_change, - tegra_emc_complete_timing_change); + tegra124_clk_set_emc_callbacks(tegra124_emc_prepare_timing_change, + tegra124_emc_complete_timing_change); - err = devm_add_action_or_reset(&pdev->dev, devm_tegra_emc_unset_callback, + err = devm_add_action_or_reset(&pdev->dev, devm_tegra124_emc_unset_callback, NULL); if (err) return err; @@ -1483,16 +1483,16 @@ static int tegra_emc_probe(struct platform_device *pdev) return dev_err_probe(&pdev->dev, PTR_ERR(emc->clk), "failed to get EMC clock\n"); - err = tegra_emc_opp_table_init(emc); + err = tegra124_emc_opp_table_init(emc); if (err) return err; - tegra_emc_rate_requests_init(emc); + tegra124_emc_rate_requests_init(emc); if (IS_ENABLED(CONFIG_DEBUG_FS)) emc_debugfs_init(&pdev->dev, emc); - tegra_emc_interconnect_init(emc); + tegra124_emc_interconnect_init(emc); /* * Don't allow the kernel module to be unloaded. Unloading adds some @@ -1504,16 +1504,16 @@ static int tegra_emc_probe(struct platform_device *pdev) return 0; }; -static struct platform_driver tegra_emc_driver = { - .probe = tegra_emc_probe, +static struct platform_driver tegra124_emc_driver = { + .probe = tegra124_emc_probe, .driver = { .name = "tegra-emc", - .of_match_table = tegra_emc_of_match, + .of_match_table = tegra124_emc_of_match, .suppress_bind_attrs = true, .sync_state = icc_sync_state, }, }; -module_platform_driver(tegra_emc_driver); +module_platform_driver(tegra124_emc_driver); MODULE_AUTHOR("Mikko Perttunen "); MODULE_DESCRIPTION("NVIDIA Tegra124 EMC driver"); From 4ebcacbb4447cd3b05289e1e0e199a5e8ea0c6de Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Thu, 11 Sep 2025 11:43:22 +0200 Subject: [PATCH 015/114] memory: tegra186-emc: Add the SoC model prefix to functions Replace "tegra_emc" with "tegra186_emc" in all functions to: 1. Avoid name clashing with other Tegra EMC drivers which makes it easier to jump to function definitions, 2. Decode the calltraces a bit easier, 3. Unify with other Tegra MC and EMC drivers, which use the SoC model prefixes. No functional impact. Reviewed-by: Jon Hunter Signed-off-by: Krzysztof Kozlowski --- drivers/memory/tegra/tegra186-emc.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/memory/tegra/tegra186-emc.c b/drivers/memory/tegra/tegra186-emc.c index a0de80afe3e9..9959ad5804b4 100644 --- a/drivers/memory/tegra/tegra186-emc.c +++ b/drivers/memory/tegra/tegra186-emc.c @@ -218,20 +218,20 @@ static int tegra186_emc_get_emc_dvfs_latency(struct tegra186_emc *emc) } /* - * tegra_emc_icc_set_bw() - Set BW api for EMC provider + * tegra186_emc_icc_set_bw() - Set BW api for EMC provider * @src: ICC node for External Memory Controller (EMC) * @dst: ICC node for External Memory (DRAM) * * Do nothing here as info to BPMP-FW is now passed in the BW set function * of the MC driver. BPMP-FW sets the final Freq based on the passed values. */ -static int tegra_emc_icc_set_bw(struct icc_node *src, struct icc_node *dst) +static int tegra186_emc_icc_set_bw(struct icc_node *src, struct icc_node *dst) { return 0; } static struct icc_node * -tegra_emc_of_icc_xlate(const struct of_phandle_args *spec, void *data) +tegra186_emc_of_icc_xlate(const struct of_phandle_args *spec, void *data) { struct icc_provider *provider = data; struct icc_node *node; @@ -247,7 +247,7 @@ tegra_emc_of_icc_xlate(const struct of_phandle_args *spec, void *data) return ERR_PTR(-EPROBE_DEFER); } -static int tegra_emc_icc_get_init_bw(struct icc_node *node, u32 *avg, u32 *peak) +static int tegra186_emc_icc_get_init_bw(struct icc_node *node, u32 *avg, u32 *peak) { *avg = 0; *peak = 0; @@ -255,7 +255,7 @@ static int tegra_emc_icc_get_init_bw(struct icc_node *node, u32 *avg, u32 *peak) return 0; } -static int tegra_emc_interconnect_init(struct tegra186_emc *emc) +static int tegra186_emc_interconnect_init(struct tegra186_emc *emc) { struct tegra_mc *mc = dev_get_drvdata(emc->dev->parent); const struct tegra_mc_soc *soc = mc->soc; @@ -263,11 +263,11 @@ static int tegra_emc_interconnect_init(struct tegra186_emc *emc) int err; emc->provider.dev = emc->dev; - emc->provider.set = tegra_emc_icc_set_bw; + emc->provider.set = tegra186_emc_icc_set_bw; emc->provider.data = &emc->provider; emc->provider.aggregate = soc->icc_ops->aggregate; - emc->provider.xlate = tegra_emc_of_icc_xlate; - emc->provider.get_bw = tegra_emc_icc_get_init_bw; + emc->provider.xlate = tegra186_emc_of_icc_xlate; + emc->provider.get_bw = tegra186_emc_icc_get_init_bw; icc_provider_init(&emc->provider); @@ -354,7 +354,7 @@ static int tegra186_emc_probe(struct platform_device *pdev) * EINVAL instead of passing the request to BPMP-FW later when the BW * request is made by client with 'icc_set_bw()' call. */ - err = tegra_emc_interconnect_init(emc); + err = tegra186_emc_interconnect_init(emc); if (err) { mc->bpmp = NULL; goto put_bpmp; From 5c8c19417c9777aba1bc9a1d93c95edec48d8b19 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Thu, 11 Sep 2025 11:43:23 +0200 Subject: [PATCH 016/114] memory: tegra20-emc: Add the SoC model prefix to functions Replace "tegra_emc" with "tegra20_emc" in all functions to: 1. Avoid name clashing with other Tegra EMC drivers which makes it easier to jump to function definitions, 2. Decode the calltraces a bit easier, 3. Unify with other Tegra MC and EMC drivers, which use the SoC model prefixes. No functional impact. Reviewed-by: Jon Hunter Signed-off-by: Krzysztof Kozlowski --- drivers/memory/tegra/tegra20-emc.c | 120 ++++++++++++++--------------- 1 file changed, 60 insertions(+), 60 deletions(-) diff --git a/drivers/memory/tegra/tegra20-emc.c b/drivers/memory/tegra/tegra20-emc.c index 18e266dde5d2..398cb8ae2e38 100644 --- a/drivers/memory/tegra/tegra20-emc.c +++ b/drivers/memory/tegra/tegra20-emc.c @@ -232,7 +232,7 @@ struct tegra_emc { bool mrr_error; }; -static irqreturn_t tegra_emc_isr(int irq, void *data) +static irqreturn_t tegra20_emc_isr(int irq, void *data) { struct tegra_emc *emc = data; u32 intmask = EMC_REFRESH_OVERFLOW_INT; @@ -253,8 +253,8 @@ static irqreturn_t tegra_emc_isr(int irq, void *data) return IRQ_HANDLED; } -static struct emc_timing *tegra_emc_find_timing(struct tegra_emc *emc, - unsigned long rate) +static struct emc_timing *tegra20_emc_find_timing(struct tegra_emc *emc, + unsigned long rate) { struct emc_timing *timing = NULL; unsigned int i; @@ -276,7 +276,7 @@ static struct emc_timing *tegra_emc_find_timing(struct tegra_emc *emc, static int emc_prepare_timing_change(struct tegra_emc *emc, unsigned long rate) { - struct emc_timing *timing = tegra_emc_find_timing(emc, rate); + struct emc_timing *timing = tegra20_emc_find_timing(emc, rate); unsigned int i; if (!timing) @@ -321,8 +321,8 @@ static int emc_complete_timing_change(struct tegra_emc *emc, bool flush) return 0; } -static int tegra_emc_clk_change_notify(struct notifier_block *nb, - unsigned long msg, void *data) +static int tegra20_emc_clk_change_notify(struct notifier_block *nb, + unsigned long msg, void *data) { struct tegra_emc *emc = container_of(nb, struct tegra_emc, clk_nb); struct clk_notifier_data *cnd = data; @@ -407,8 +407,8 @@ static int cmp_timings(const void *_a, const void *_b) return 0; } -static int tegra_emc_load_timings_from_dt(struct tegra_emc *emc, - struct device_node *node) +static int tegra20_emc_load_timings_from_dt(struct tegra_emc *emc, + struct device_node *node) { struct emc_timing *timing; int child_count; @@ -452,7 +452,7 @@ static int tegra_emc_load_timings_from_dt(struct tegra_emc *emc, } static struct device_node * -tegra_emc_find_node_by_ram_code(struct tegra_emc *emc) +tegra20_emc_find_node_by_ram_code(struct tegra_emc *emc) { struct device *dev = emc->dev; struct device_node *np; @@ -710,7 +710,7 @@ static long emc_round_rate(unsigned long rate, return timing->rate; } -static void tegra_emc_rate_requests_init(struct tegra_emc *emc) +static void tegra20_emc_rate_requests_init(struct tegra_emc *emc) { unsigned int i; @@ -812,7 +812,7 @@ static int emc_set_max_rate(struct tegra_emc *emc, unsigned long rate, * valid range. */ -static bool tegra_emc_validate_rate(struct tegra_emc *emc, unsigned long rate) +static bool tegra20_emc_validate_rate(struct tegra_emc *emc, unsigned long rate) { unsigned int i; @@ -823,7 +823,7 @@ static bool tegra_emc_validate_rate(struct tegra_emc *emc, unsigned long rate) return false; } -static int tegra_emc_debug_available_rates_show(struct seq_file *s, void *data) +static int tegra20_emc_debug_available_rates_show(struct seq_file *s, void *data) { struct tegra_emc *emc = s->private; const char *prefix = ""; @@ -838,9 +838,9 @@ static int tegra_emc_debug_available_rates_show(struct seq_file *s, void *data) return 0; } -DEFINE_SHOW_ATTRIBUTE(tegra_emc_debug_available_rates); +DEFINE_SHOW_ATTRIBUTE(tegra20_emc_debug_available_rates); -static int tegra_emc_debug_min_rate_get(void *data, u64 *rate) +static int tegra20_emc_debug_min_rate_get(void *data, u64 *rate) { struct tegra_emc *emc = data; @@ -849,12 +849,12 @@ static int tegra_emc_debug_min_rate_get(void *data, u64 *rate) return 0; } -static int tegra_emc_debug_min_rate_set(void *data, u64 rate) +static int tegra20_emc_debug_min_rate_set(void *data, u64 rate) { struct tegra_emc *emc = data; int err; - if (!tegra_emc_validate_rate(emc, rate)) + if (!tegra20_emc_validate_rate(emc, rate)) return -EINVAL; err = emc_set_min_rate(emc, rate, EMC_RATE_DEBUG); @@ -866,11 +866,11 @@ static int tegra_emc_debug_min_rate_set(void *data, u64 rate) return 0; } -DEFINE_SIMPLE_ATTRIBUTE(tegra_emc_debug_min_rate_fops, - tegra_emc_debug_min_rate_get, - tegra_emc_debug_min_rate_set, "%llu\n"); +DEFINE_SIMPLE_ATTRIBUTE(tegra20_emc_debug_min_rate_fops, + tegra20_emc_debug_min_rate_get, + tegra20_emc_debug_min_rate_set, "%llu\n"); -static int tegra_emc_debug_max_rate_get(void *data, u64 *rate) +static int tegra20_emc_debug_max_rate_get(void *data, u64 *rate) { struct tegra_emc *emc = data; @@ -879,12 +879,12 @@ static int tegra_emc_debug_max_rate_get(void *data, u64 *rate) return 0; } -static int tegra_emc_debug_max_rate_set(void *data, u64 rate) +static int tegra20_emc_debug_max_rate_set(void *data, u64 rate) { struct tegra_emc *emc = data; int err; - if (!tegra_emc_validate_rate(emc, rate)) + if (!tegra20_emc_validate_rate(emc, rate)) return -EINVAL; err = emc_set_max_rate(emc, rate, EMC_RATE_DEBUG); @@ -896,11 +896,11 @@ static int tegra_emc_debug_max_rate_set(void *data, u64 rate) return 0; } -DEFINE_SIMPLE_ATTRIBUTE(tegra_emc_debug_max_rate_fops, - tegra_emc_debug_max_rate_get, - tegra_emc_debug_max_rate_set, "%llu\n"); +DEFINE_SIMPLE_ATTRIBUTE(tegra20_emc_debug_max_rate_fops, + tegra20_emc_debug_max_rate_get, + tegra20_emc_debug_max_rate_set, "%llu\n"); -static void tegra_emc_debugfs_init(struct tegra_emc *emc) +static void tegra20_emc_debugfs_init(struct tegra_emc *emc) { struct device *dev = emc->dev; unsigned int i; @@ -933,11 +933,11 @@ static void tegra_emc_debugfs_init(struct tegra_emc *emc) emc->debugfs.root = debugfs_create_dir("emc", NULL); debugfs_create_file("available_rates", 0444, emc->debugfs.root, - emc, &tegra_emc_debug_available_rates_fops); + emc, &tegra20_emc_debug_available_rates_fops); debugfs_create_file("min_rate", 0644, emc->debugfs.root, - emc, &tegra_emc_debug_min_rate_fops); + emc, &tegra20_emc_debug_min_rate_fops); debugfs_create_file("max_rate", 0644, emc->debugfs.root, - emc, &tegra_emc_debug_max_rate_fops); + emc, &tegra20_emc_debug_max_rate_fops); } static inline struct tegra_emc * @@ -1000,7 +1000,7 @@ static int emc_icc_set(struct icc_node *src, struct icc_node *dst) return 0; } -static int tegra_emc_interconnect_init(struct tegra_emc *emc) +static int tegra20_emc_interconnect_init(struct tegra_emc *emc) { const struct tegra_mc_soc *soc; struct icc_node *node; @@ -1055,25 +1055,25 @@ static int tegra_emc_interconnect_init(struct tegra_emc *emc) return dev_err_probe(emc->dev, err, "failed to initialize ICC\n"); } -static void devm_tegra_emc_unset_callback(void *data) +static void devm_tegra20_emc_unset_callback(void *data) { tegra20_clk_set_emc_round_callback(NULL, NULL); } -static void devm_tegra_emc_unreg_clk_notifier(void *data) +static void devm_tegra20_emc_unreg_clk_notifier(void *data) { struct tegra_emc *emc = data; clk_notifier_unregister(emc->clk, &emc->clk_nb); } -static int tegra_emc_init_clk(struct tegra_emc *emc) +static int tegra20_emc_init_clk(struct tegra_emc *emc) { int err; tegra20_clk_set_emc_round_callback(emc_round_rate, emc); - err = devm_add_action_or_reset(emc->dev, devm_tegra_emc_unset_callback, + err = devm_add_action_or_reset(emc->dev, devm_tegra20_emc_unset_callback, NULL); if (err) return err; @@ -1088,15 +1088,15 @@ static int tegra_emc_init_clk(struct tegra_emc *emc) return dev_err_probe(emc->dev, err, "failed to register clk notifier\n"); err = devm_add_action_or_reset(emc->dev, - devm_tegra_emc_unreg_clk_notifier, emc); + devm_tegra20_emc_unreg_clk_notifier, emc); if (err) return err; return 0; } -static int tegra_emc_devfreq_target(struct device *dev, unsigned long *freq, - u32 flags) +static int tegra20_emc_devfreq_target(struct device *dev, unsigned long *freq, + u32 flags) { struct tegra_emc *emc = dev_get_drvdata(dev); struct dev_pm_opp *opp; @@ -1114,8 +1114,8 @@ static int tegra_emc_devfreq_target(struct device *dev, unsigned long *freq, return emc_set_min_rate(emc, rate, EMC_RATE_DEVFREQ); } -static int tegra_emc_devfreq_get_dev_status(struct device *dev, - struct devfreq_dev_status *stat) +static int tegra20_emc_devfreq_get_dev_status(struct device *dev, + struct devfreq_dev_status *stat) { struct tegra_emc *emc = dev_get_drvdata(dev); @@ -1137,13 +1137,13 @@ static int tegra_emc_devfreq_get_dev_status(struct device *dev, return 0; } -static struct devfreq_dev_profile tegra_emc_devfreq_profile = { +static struct devfreq_dev_profile tegra20_emc_devfreq_profile = { .polling_ms = 30, - .target = tegra_emc_devfreq_target, - .get_dev_status = tegra_emc_devfreq_get_dev_status, + .target = tegra20_emc_devfreq_target, + .get_dev_status = tegra20_emc_devfreq_get_dev_status, }; -static int tegra_emc_devfreq_init(struct tegra_emc *emc) +static int tegra20_emc_devfreq_init(struct tegra_emc *emc) { struct devfreq *devfreq; @@ -1165,7 +1165,7 @@ static int tegra_emc_devfreq_init(struct tegra_emc *emc) writel_relaxed(0x00000000, emc->regs + EMC_STAT_LLMC_CONTROL); writel_relaxed(0xffffffff, emc->regs + EMC_STAT_PWR_CLOCK_LIMIT); - devfreq = devm_devfreq_add_device(emc->dev, &tegra_emc_devfreq_profile, + devfreq = devm_devfreq_add_device(emc->dev, &tegra20_emc_devfreq_profile, DEVFREQ_GOV_SIMPLE_ONDEMAND, &emc->ondemand_data); if (IS_ERR(devfreq)) @@ -1175,7 +1175,7 @@ static int tegra_emc_devfreq_init(struct tegra_emc *emc) return 0; } -static int tegra_emc_probe(struct platform_device *pdev) +static int tegra20_emc_probe(struct platform_device *pdev) { struct tegra_core_opp_params opp_params = {}; struct device_node *np; @@ -1191,7 +1191,7 @@ static int tegra_emc_probe(struct platform_device *pdev) return -ENOMEM; mutex_init(&emc->rate_lock); - emc->clk_nb.notifier_call = tegra_emc_clk_change_notify; + emc->clk_nb.notifier_call = tegra20_emc_clk_change_notify; emc->dev = &pdev->dev; emc->regs = devm_platform_ioremap_resource(pdev, 0); @@ -1202,22 +1202,22 @@ static int tegra_emc_probe(struct platform_device *pdev) if (err) return err; - np = tegra_emc_find_node_by_ram_code(emc); + np = tegra20_emc_find_node_by_ram_code(emc); if (np) { - err = tegra_emc_load_timings_from_dt(emc, np); + err = tegra20_emc_load_timings_from_dt(emc, np); of_node_put(np); if (err) return err; } - err = devm_request_irq(&pdev->dev, irq, tegra_emc_isr, 0, + err = devm_request_irq(&pdev->dev, irq, tegra20_emc_isr, 0, dev_name(&pdev->dev), emc); if (err) { dev_err(&pdev->dev, "failed to request IRQ: %d\n", err); return err; } - err = tegra_emc_init_clk(emc); + err = tegra20_emc_init_clk(emc); if (err) return err; @@ -1228,10 +1228,10 @@ static int tegra_emc_probe(struct platform_device *pdev) return err; platform_set_drvdata(pdev, emc); - tegra_emc_rate_requests_init(emc); - tegra_emc_debugfs_init(emc); - tegra_emc_interconnect_init(emc); - tegra_emc_devfreq_init(emc); + tegra20_emc_rate_requests_init(emc); + tegra20_emc_debugfs_init(emc); + tegra20_emc_interconnect_init(emc); + tegra20_emc_devfreq_init(emc); /* * Don't allow the kernel module to be unloaded. Unloading adds some @@ -1243,22 +1243,22 @@ static int tegra_emc_probe(struct platform_device *pdev) return 0; } -static const struct of_device_id tegra_emc_of_match[] = { +static const struct of_device_id tegra20_emc_of_match[] = { { .compatible = "nvidia,tegra20-emc", }, {}, }; -MODULE_DEVICE_TABLE(of, tegra_emc_of_match); +MODULE_DEVICE_TABLE(of, tegra20_emc_of_match); -static struct platform_driver tegra_emc_driver = { - .probe = tegra_emc_probe, +static struct platform_driver tegra20_emc_driver = { + .probe = tegra20_emc_probe, .driver = { .name = "tegra20-emc", - .of_match_table = tegra_emc_of_match, + .of_match_table = tegra20_emc_of_match, .suppress_bind_attrs = true, .sync_state = icc_sync_state, }, }; -module_platform_driver(tegra_emc_driver); +module_platform_driver(tegra20_emc_driver); MODULE_AUTHOR("Dmitry Osipenko "); MODULE_DESCRIPTION("NVIDIA Tegra20 EMC driver"); From 50c833c5cd9450c8c67d32883ea290dcbd633ea0 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Thu, 11 Sep 2025 11:43:24 +0200 Subject: [PATCH 017/114] memory: tegra30-emc: Add the SoC model prefix to functions Replace "tegra_emc" with "tegra30_emc" in all functions to: 1. Avoid name clashing with other Tegra EMC drivers which makes it easier to jump to function definitions, 2. Decode the calltraces a bit easier, 3. Unify with other Tegra MC and EMC drivers, which use the SoC model prefixes. No functional impact. Reviewed-by: Jon Hunter Signed-off-by: Krzysztof Kozlowski --- drivers/memory/tegra/tegra30-emc.c | 90 +++++++++++++++--------------- 1 file changed, 45 insertions(+), 45 deletions(-) diff --git a/drivers/memory/tegra/tegra30-emc.c b/drivers/memory/tegra/tegra30-emc.c index cca386af423e..914116d8ec16 100644 --- a/drivers/memory/tegra/tegra30-emc.c +++ b/drivers/memory/tegra/tegra30-emc.c @@ -413,7 +413,7 @@ static int emc_seq_update_timing(struct tegra_emc *emc) return 0; } -static irqreturn_t tegra_emc_isr(int irq, void *data) +static irqreturn_t tegra30_emc_isr(int irq, void *data) { struct tegra_emc *emc = data; u32 intmask = EMC_REFRESH_OVERFLOW_INT; @@ -1228,7 +1228,7 @@ static long emc_round_rate(unsigned long rate, return timing->rate; } -static void tegra_emc_rate_requests_init(struct tegra_emc *emc) +static void tegra30_emc_rate_requests_init(struct tegra_emc *emc) { unsigned int i; @@ -1330,7 +1330,7 @@ static int emc_set_max_rate(struct tegra_emc *emc, unsigned long rate, * valid range. */ -static bool tegra_emc_validate_rate(struct tegra_emc *emc, unsigned long rate) +static bool tegra30_emc_validate_rate(struct tegra_emc *emc, unsigned long rate) { unsigned int i; @@ -1341,7 +1341,7 @@ static bool tegra_emc_validate_rate(struct tegra_emc *emc, unsigned long rate) return false; } -static int tegra_emc_debug_available_rates_show(struct seq_file *s, void *data) +static int tegra30_emc_debug_available_rates_show(struct seq_file *s, void *data) { struct tegra_emc *emc = s->private; const char *prefix = ""; @@ -1356,9 +1356,9 @@ static int tegra_emc_debug_available_rates_show(struct seq_file *s, void *data) return 0; } -DEFINE_SHOW_ATTRIBUTE(tegra_emc_debug_available_rates); +DEFINE_SHOW_ATTRIBUTE(tegra30_emc_debug_available_rates); -static int tegra_emc_debug_min_rate_get(void *data, u64 *rate) +static int tegra30_emc_debug_min_rate_get(void *data, u64 *rate) { struct tegra_emc *emc = data; @@ -1367,12 +1367,12 @@ static int tegra_emc_debug_min_rate_get(void *data, u64 *rate) return 0; } -static int tegra_emc_debug_min_rate_set(void *data, u64 rate) +static int tegra30_emc_debug_min_rate_set(void *data, u64 rate) { struct tegra_emc *emc = data; int err; - if (!tegra_emc_validate_rate(emc, rate)) + if (!tegra30_emc_validate_rate(emc, rate)) return -EINVAL; err = emc_set_min_rate(emc, rate, EMC_RATE_DEBUG); @@ -1384,11 +1384,11 @@ static int tegra_emc_debug_min_rate_set(void *data, u64 rate) return 0; } -DEFINE_DEBUGFS_ATTRIBUTE(tegra_emc_debug_min_rate_fops, - tegra_emc_debug_min_rate_get, - tegra_emc_debug_min_rate_set, "%llu\n"); +DEFINE_DEBUGFS_ATTRIBUTE(tegra30_emc_debug_min_rate_fops, + tegra30_emc_debug_min_rate_get, + tegra30_emc_debug_min_rate_set, "%llu\n"); -static int tegra_emc_debug_max_rate_get(void *data, u64 *rate) +static int tegra30_emc_debug_max_rate_get(void *data, u64 *rate) { struct tegra_emc *emc = data; @@ -1397,12 +1397,12 @@ static int tegra_emc_debug_max_rate_get(void *data, u64 *rate) return 0; } -static int tegra_emc_debug_max_rate_set(void *data, u64 rate) +static int tegra30_emc_debug_max_rate_set(void *data, u64 rate) { struct tegra_emc *emc = data; int err; - if (!tegra_emc_validate_rate(emc, rate)) + if (!tegra30_emc_validate_rate(emc, rate)) return -EINVAL; err = emc_set_max_rate(emc, rate, EMC_RATE_DEBUG); @@ -1414,11 +1414,11 @@ static int tegra_emc_debug_max_rate_set(void *data, u64 rate) return 0; } -DEFINE_DEBUGFS_ATTRIBUTE(tegra_emc_debug_max_rate_fops, - tegra_emc_debug_max_rate_get, - tegra_emc_debug_max_rate_set, "%llu\n"); +DEFINE_DEBUGFS_ATTRIBUTE(tegra30_emc_debug_max_rate_fops, + tegra30_emc_debug_max_rate_get, + tegra30_emc_debug_max_rate_set, "%llu\n"); -static void tegra_emc_debugfs_init(struct tegra_emc *emc) +static void tegra30_emc_debugfs_init(struct tegra_emc *emc) { struct device *dev = emc->dev; unsigned int i; @@ -1451,11 +1451,11 @@ static void tegra_emc_debugfs_init(struct tegra_emc *emc) emc->debugfs.root = debugfs_create_dir("emc", NULL); debugfs_create_file("available_rates", 0444, emc->debugfs.root, - emc, &tegra_emc_debug_available_rates_fops); + emc, &tegra30_emc_debug_available_rates_fops); debugfs_create_file("min_rate", 0644, emc->debugfs.root, - emc, &tegra_emc_debug_min_rate_fops); + emc, &tegra30_emc_debug_min_rate_fops); debugfs_create_file("max_rate", 0644, emc->debugfs.root, - emc, &tegra_emc_debug_max_rate_fops); + emc, &tegra30_emc_debug_max_rate_fops); } static inline struct tegra_emc * @@ -1518,7 +1518,7 @@ static int emc_icc_set(struct icc_node *src, struct icc_node *dst) return 0; } -static int tegra_emc_interconnect_init(struct tegra_emc *emc) +static int tegra30_emc_interconnect_init(struct tegra_emc *emc) { const struct tegra_mc_soc *soc = emc->mc->soc; struct icc_node *node; @@ -1567,25 +1567,25 @@ static int tegra_emc_interconnect_init(struct tegra_emc *emc) return dev_err_probe(emc->dev, err, "failed to initialize ICC\n"); } -static void devm_tegra_emc_unset_callback(void *data) +static void devm_tegra30_emc_unset_callback(void *data) { tegra20_clk_set_emc_round_callback(NULL, NULL); } -static void devm_tegra_emc_unreg_clk_notifier(void *data) +static void devm_tegra30_emc_unreg_clk_notifier(void *data) { struct tegra_emc *emc = data; clk_notifier_unregister(emc->clk, &emc->clk_nb); } -static int tegra_emc_init_clk(struct tegra_emc *emc) +static int tegra30_emc_init_clk(struct tegra_emc *emc) { int err; tegra20_clk_set_emc_round_callback(emc_round_rate, emc); - err = devm_add_action_or_reset(emc->dev, devm_tegra_emc_unset_callback, + err = devm_add_action_or_reset(emc->dev, devm_tegra30_emc_unset_callback, NULL); if (err) return err; @@ -1600,14 +1600,14 @@ static int tegra_emc_init_clk(struct tegra_emc *emc) return dev_err_probe(emc->dev, err, "failed to register clk notifier\n"); err = devm_add_action_or_reset(emc->dev, - devm_tegra_emc_unreg_clk_notifier, emc); + devm_tegra30_emc_unreg_clk_notifier, emc); if (err) return err; return 0; } -static int tegra_emc_probe(struct platform_device *pdev) +static int tegra30_emc_probe(struct platform_device *pdev) { struct tegra_core_opp_params opp_params = {}; struct device_node *np; @@ -1648,12 +1648,12 @@ static int tegra_emc_probe(struct platform_device *pdev) emc->irq = err; - err = devm_request_irq(&pdev->dev, emc->irq, tegra_emc_isr, 0, + err = devm_request_irq(&pdev->dev, emc->irq, tegra30_emc_isr, 0, dev_name(&pdev->dev), emc); if (err) return dev_err_probe(&pdev->dev, err, "failed to request irq\n"); - err = tegra_emc_init_clk(emc); + err = tegra30_emc_init_clk(emc); if (err) return err; @@ -1664,9 +1664,9 @@ static int tegra_emc_probe(struct platform_device *pdev) return err; platform_set_drvdata(pdev, emc); - tegra_emc_rate_requests_init(emc); - tegra_emc_debugfs_init(emc); - tegra_emc_interconnect_init(emc); + tegra30_emc_rate_requests_init(emc); + tegra30_emc_debugfs_init(emc); + tegra30_emc_interconnect_init(emc); /* * Don't allow the kernel module to be unloaded. Unloading adds some @@ -1678,7 +1678,7 @@ static int tegra_emc_probe(struct platform_device *pdev) return 0; } -static int tegra_emc_suspend(struct device *dev) +static int tegra30_emc_suspend(struct device *dev) { struct tegra_emc *emc = dev_get_drvdata(dev); int err; @@ -1699,7 +1699,7 @@ static int tegra_emc_suspend(struct device *dev) return 0; } -static int tegra_emc_resume(struct device *dev) +static int tegra30_emc_resume(struct device *dev) { struct tegra_emc *emc = dev_get_drvdata(dev); @@ -1711,28 +1711,28 @@ static int tegra_emc_resume(struct device *dev) return 0; } -static const struct dev_pm_ops tegra_emc_pm_ops = { - .suspend = tegra_emc_suspend, - .resume = tegra_emc_resume, +static const struct dev_pm_ops tegra30_emc_pm_ops = { + .suspend = tegra30_emc_suspend, + .resume = tegra30_emc_resume, }; -static const struct of_device_id tegra_emc_of_match[] = { +static const struct of_device_id tegra30_emc_of_match[] = { { .compatible = "nvidia,tegra30-emc", }, {}, }; -MODULE_DEVICE_TABLE(of, tegra_emc_of_match); +MODULE_DEVICE_TABLE(of, tegra30_emc_of_match); -static struct platform_driver tegra_emc_driver = { - .probe = tegra_emc_probe, +static struct platform_driver tegra30_emc_driver = { + .probe = tegra30_emc_probe, .driver = { .name = "tegra30-emc", - .of_match_table = tegra_emc_of_match, - .pm = &tegra_emc_pm_ops, + .of_match_table = tegra30_emc_of_match, + .pm = &tegra30_emc_pm_ops, .suppress_bind_attrs = true, .sync_state = icc_sync_state, }, }; -module_platform_driver(tegra_emc_driver); +module_platform_driver(tegra30_emc_driver); MODULE_AUTHOR("Dmitry Osipenko "); MODULE_DESCRIPTION("NVIDIA Tegra30 EMC driver"); From ca4bd675ec459bb7bb008f15f5d866c9ce35f4e2 Mon Sep 17 00:00:00 2001 From: Denzeel Oliva Date: Wed, 17 Sep 2025 21:04:21 +0000 Subject: [PATCH 018/114] dt-bindings: soc: samsung: exynos-sysreg: Add Exynos990 PERIC0/1 compatibles Add compatible strings for Exynos990 PERIC0 and PERIC1 system register controllers. Signed-off-by: Denzeel Oliva Acked-by: Rob Herring (Arm) Signed-off-by: Krzysztof Kozlowski --- .../bindings/soc/samsung/samsung,exynos-sysreg.yaml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Documentation/devicetree/bindings/soc/samsung/samsung,exynos-sysreg.yaml b/Documentation/devicetree/bindings/soc/samsung/samsung,exynos-sysreg.yaml index d8b302f97547..173c51b17d96 100644 --- a/Documentation/devicetree/bindings/soc/samsung/samsung,exynos-sysreg.yaml +++ b/Documentation/devicetree/bindings/soc/samsung/samsung,exynos-sysreg.yaml @@ -30,6 +30,8 @@ properties: - samsung,exynos8895-fsys1-sysreg - samsung,exynos8895-peric0-sysreg - samsung,exynos8895-peric1-sysreg + - samsung,exynos990-peric0-sysreg + - samsung,exynos990-peric1-sysreg - samsung,exynosautov920-hsi2-sysreg - samsung,exynosautov920-peric0-sysreg - samsung,exynosautov920-peric1-sysreg @@ -93,6 +95,8 @@ allOf: - samsung,exynos8895-fsys1-sysreg - samsung,exynos8895-peric0-sysreg - samsung,exynos8895-peric1-sysreg + - samsung,exynos990-peric0-sysreg + - samsung,exynos990-peric1-sysreg then: required: - clocks From 944d40232eb4281aa8b56ea5389a8fe83b7c7074 Mon Sep 17 00:00:00 2001 From: Alexandru Chimac Date: Sun, 14 Sep 2025 19:50:28 +0000 Subject: [PATCH 019/114] dt-bindings: hwinfo: samsung,exynos-chipid: add exynos9610 compatible Add a compatible for the "samsung,exynos9610-chipid" node, used by Exynos9610 platforms. Signed-off-by: Alexandru Chimac Acked-by: Rob Herring (Arm) Signed-off-by: Krzysztof Kozlowski --- .../devicetree/bindings/hwinfo/samsung,exynos-chipid.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/hwinfo/samsung,exynos-chipid.yaml b/Documentation/devicetree/bindings/hwinfo/samsung,exynos-chipid.yaml index 383020450d78..55fd1cd59e4e 100644 --- a/Documentation/devicetree/bindings/hwinfo/samsung,exynos-chipid.yaml +++ b/Documentation/devicetree/bindings/hwinfo/samsung,exynos-chipid.yaml @@ -26,6 +26,7 @@ properties: - samsung,exynos2200-chipid - samsung,exynos7885-chipid - samsung,exynos8895-chipid + - samsung,exynos9610-chipid - samsung,exynos9810-chipid - samsung,exynos990-chipid - samsung,exynosautov9-chipid From fe31e894c284012f11a841dd2346fd99bce4a001 Mon Sep 17 00:00:00 2001 From: Alexandru Chimac Date: Sun, 14 Sep 2025 19:50:38 +0000 Subject: [PATCH 020/114] soc: samsung: exynos-chipid: Add exynos9610 SoC support Exynos9610's product ID is "0xE9610000". Add this ID to the IDs table along with the name of the SoC. Signed-off-by: Alexandru Chimac Signed-off-by: Krzysztof Kozlowski --- drivers/soc/samsung/exynos-chipid.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/soc/samsung/exynos-chipid.c b/drivers/soc/samsung/exynos-chipid.c index c86f1058ceed..a5ed1c105b8f 100644 --- a/drivers/soc/samsung/exynos-chipid.c +++ b/drivers/soc/samsung/exynos-chipid.c @@ -62,6 +62,7 @@ static const struct exynos_soc_id { { "EXYNOS7885", 0xE7885000 }, { "EXYNOS850", 0xE3830000 }, { "EXYNOS8895", 0xE8895000 }, + { "EXYNOS9610", 0xE9610000 }, { "EXYNOS9810", 0xE9810000 }, { "EXYNOS990", 0xE9830000 }, { "EXYNOSAUTOV9", 0xAAA80000 }, From 326312707492c136ba44cf96730e70aabc959da9 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Fri, 5 Sep 2025 19:37:18 +0200 Subject: [PATCH 021/114] soc: samsung: exynos-pmu: Annotate online/offline functions with __must_hold Annotate functions writing to PMU registers to online and offline CPUs as __must_hold() the necessary spinlock for code correctness. These are static functions so possibility of mistakes is low here, but __must_hold() serves as self-documenting code. Signed-off-by: Krzysztof Kozlowski --- drivers/soc/samsung/exynos-pmu.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/soc/samsung/exynos-pmu.c b/drivers/soc/samsung/exynos-pmu.c index 22c50ca2aa79..105293970d48 100644 --- a/drivers/soc/samsung/exynos-pmu.c +++ b/drivers/soc/samsung/exynos-pmu.c @@ -364,6 +364,7 @@ EXPORT_SYMBOL_GPL(exynos_get_pmu_regmap_by_phandle); * disabled and cpupm_lock held. */ static int __gs101_cpu_pmu_online(unsigned int cpu) + __must_hold(&pmu_context->cpupm_lock) { unsigned int cpuhint = smp_processor_id(); u32 reg, mask; @@ -424,6 +425,7 @@ static int gs101_cpuhp_pmu_online(unsigned int cpu) /* Common function shared by both CPU hot plug and CPUIdle */ static int __gs101_cpu_pmu_offline(unsigned int cpu) + __must_hold(&pmu_context->cpupm_lock) { unsigned int cpuhint = smp_processor_id(); u32 reg, mask; From 5e88dfc52f521da6044e02fadac173a2111aecc9 Mon Sep 17 00:00:00 2001 From: Prasad Kumpatla Date: Tue, 14 Oct 2025 14:57:10 +0530 Subject: [PATCH 022/114] soc: qcom: pd-mapper: Add Kaanapali compatible Add support for the Qualcomm Kaanapali SoC to the protection domain mapper. Kaanapali shares the same protection domain configuration as SM8550, except charger_pd as it move to SoCCP. Signed-off-by: Jingyi Wang Signed-off-by: Prasad Kumpatla Reviewed-by: Konrad Dybcio Link: https://lore.kernel.org/r/20251014-knp-pdmapper-v2-v2-1-ba44422ac503@oss.qualcomm.com Signed-off-by: Bjorn Andersson --- drivers/soc/qcom/qcom_pd_mapper.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/soc/qcom/qcom_pd_mapper.c b/drivers/soc/qcom/qcom_pd_mapper.c index 6384f271953d..1bcbe69688d2 100644 --- a/drivers/soc/qcom/qcom_pd_mapper.c +++ b/drivers/soc/qcom/qcom_pd_mapper.c @@ -360,6 +360,15 @@ static const struct qcom_pdm_domain_data mpss_wlan_pd = { }, }; +static const struct qcom_pdm_domain_data *kaanapali_domains[] = { + &adsp_audio_pd, + &adsp_root_pd, + &adsp_sensor_pd, + &cdsp_root_pd, + &mpss_root_pd_gps, + NULL, +}; + static const struct qcom_pdm_domain_data *msm8996_domains[] = { &msm8996_adsp_audio_pd, &msm8996_adsp_root_pd, @@ -552,6 +561,7 @@ static const struct of_device_id qcom_pdm_domains[] __maybe_unused = { { .compatible = "qcom,apq8074", .data = NULL, }, { .compatible = "qcom,apq8084", .data = NULL, }, { .compatible = "qcom,apq8096", .data = msm8996_domains, }, + { .compatible = "qcom,kaanapali", .data = kaanapali_domains, }, { .compatible = "qcom,msm8226", .data = NULL, }, { .compatible = "qcom,msm8909", .data = NULL, }, { .compatible = "qcom,msm8916", .data = NULL, }, From a1d5955b288988596f1dc0f953f239e968a14c10 Mon Sep 17 00:00:00 2001 From: Ivaylo Ivanov Date: Sun, 14 Sep 2025 14:29:40 +0300 Subject: [PATCH 023/114] dt-bindings: soc: samsung: exynos-pmu: add exynos8890 compatible Add exynos8890-pmu compatible to the bindings documentation. Since Samsung, as usual, reuses devices from older designs, use the samsung,exynos7-pmu compatible. Signed-off-by: Ivaylo Ivanov Acked-by: Rob Herring (Arm) Signed-off-by: Krzysztof Kozlowski --- Documentation/devicetree/bindings/soc/samsung/exynos-pmu.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/soc/samsung/exynos-pmu.yaml b/Documentation/devicetree/bindings/soc/samsung/exynos-pmu.yaml index f0fb24156da9..be1441193fee 100644 --- a/Documentation/devicetree/bindings/soc/samsung/exynos-pmu.yaml +++ b/Documentation/devicetree/bindings/soc/samsung/exynos-pmu.yaml @@ -55,6 +55,7 @@ properties: - samsung,exynos2200-pmu - samsung,exynos7870-pmu - samsung,exynos7885-pmu + - samsung,exynos8890-pmu - samsung,exynos8895-pmu - samsung,exynos9810-pmu - samsung,exynos990-pmu From 7319872fe0d4a623e86a0f2747b11d4f52b5a0e4 Mon Sep 17 00:00:00 2001 From: Ivaylo Ivanov Date: Sun, 14 Sep 2025 14:29:41 +0300 Subject: [PATCH 024/114] dt-bindings: hwinfo: samsung,exynos-chipid: add exynos8890-chipid compatible Document the samsung,exynos8890-chipid compatible. The registers are entirely compatible with "samsung,exynos4210-chipid". Signed-off-by: Ivaylo Ivanov Acked-by: Rob Herring (Arm) Signed-off-by: Krzysztof Kozlowski --- .../devicetree/bindings/hwinfo/samsung,exynos-chipid.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/hwinfo/samsung,exynos-chipid.yaml b/Documentation/devicetree/bindings/hwinfo/samsung,exynos-chipid.yaml index 55fd1cd59e4e..b9cdfe52b62f 100644 --- a/Documentation/devicetree/bindings/hwinfo/samsung,exynos-chipid.yaml +++ b/Documentation/devicetree/bindings/hwinfo/samsung,exynos-chipid.yaml @@ -20,6 +20,7 @@ properties: - samsung,exynos5433-chipid - samsung,exynos7-chipid - samsung,exynos7870-chipid + - samsung,exynos8890-chipid - const: samsung,exynos4210-chipid - items: - enum: From aaf9a2f487ad88298d94d32954f8ab9e8ae008d5 Mon Sep 17 00:00:00 2001 From: Ivaylo Ivanov Date: Sun, 14 Sep 2025 14:29:42 +0300 Subject: [PATCH 025/114] soc: samsung: exynos-chipid: add exynos8890 SoC support Add exynos8890 information to soc_ids tables. This SoC product id is "0xE8890000". Signed-off-by: Ivaylo Ivanov Signed-off-by: Krzysztof Kozlowski --- drivers/soc/samsung/exynos-chipid.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/soc/samsung/exynos-chipid.c b/drivers/soc/samsung/exynos-chipid.c index a5ed1c105b8f..0f9f83a00679 100644 --- a/drivers/soc/samsung/exynos-chipid.c +++ b/drivers/soc/samsung/exynos-chipid.c @@ -57,6 +57,7 @@ static const struct exynos_soc_id { { "EXYNOS5800", 0xE5422000 }, { "EXYNOS7420", 0xE7420000 }, { "EXYNOS7870", 0xE7870000 }, + { "EXYNOS8890", 0xE8890000 }, /* Compatible with: samsung,exynos850-chipid */ { "EXYNOS2200", 0xE9925000 }, { "EXYNOS7885", 0xE7885000 }, From 3abd9b087a4cd7430cec2080c67e7a94fd7a44b4 Mon Sep 17 00:00:00 2001 From: Kaustabh Chakraborty Date: Sun, 28 Sep 2025 23:26:35 +0530 Subject: [PATCH 026/114] dt-bindings: samsung: exynos-sysreg: add exynos7870 sysregs Add sysreg compatible strings for the Exynos7870 SoC. Two sysregs are added, used for the SoC MIPI PHY's CSIS and DSIM blocks. Acked-by: Rob Herring (Arm) Signed-off-by: Kaustabh Chakraborty Signed-off-by: Krzysztof Kozlowski --- .../devicetree/bindings/soc/samsung/samsung,exynos-sysreg.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Documentation/devicetree/bindings/soc/samsung/samsung,exynos-sysreg.yaml b/Documentation/devicetree/bindings/soc/samsung/samsung,exynos-sysreg.yaml index 173c51b17d96..518af7b926b7 100644 --- a/Documentation/devicetree/bindings/soc/samsung/samsung,exynos-sysreg.yaml +++ b/Documentation/devicetree/bindings/soc/samsung/samsung,exynos-sysreg.yaml @@ -26,6 +26,8 @@ properties: - samsung,exynos3-sysreg - samsung,exynos4-sysreg - samsung,exynos5-sysreg + - samsung,exynos7870-cam0-sysreg + - samsung,exynos7870-disp-sysreg - samsung,exynos8895-fsys0-sysreg - samsung,exynos8895-fsys1-sysreg - samsung,exynos8895-peric0-sysreg From 1fce7e4d6c42c8164e6e36d8600e16663066c1b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Draszik?= Date: Thu, 9 Oct 2025 10:31:25 +0100 Subject: [PATCH 027/114] soc: samsung: exynos-pmu: allow specifying read & write access tables for secure regmap MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Accessing non-existent PMU registers causes an SError, halting the system. regmap can help us with that by allowing to pass the list of valid registers as part of the config during creation. When this driver creates a new regmap itself rather than relying on syscon_node_to_regmap(), it's therefore easily possible to hook in custom access tables for valid read and write registers. Specifying access tables avoids SErrors for invalid registers and instead the regmap core can just return an error. Outside drivers, this is also helpful when using debugfs to access the regmap. Make it possible for drivers to specify read and write tables to be used on creation of the secure regmap by adding respective fields to struct exynos_pmu_data. Also add kerneldoc to same struct while updating it. Reviewed-by: Sam Protsenko Signed-off-by: André Draszik Link: https://patch.msgid.link/20251009-gs101-pmu-regmap-tables-v2-1-2d64f5261952@linaro.org Signed-off-by: Krzysztof Kozlowski --- drivers/soc/samsung/exynos-pmu.c | 3 +++ drivers/soc/samsung/exynos-pmu.h | 30 ++++++++++++++++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/drivers/soc/samsung/exynos-pmu.c b/drivers/soc/samsung/exynos-pmu.c index 105293970d48..565eb75b003a 100644 --- a/drivers/soc/samsung/exynos-pmu.c +++ b/drivers/soc/samsung/exynos-pmu.c @@ -637,6 +637,9 @@ static int exynos_pmu_probe(struct platform_device *pdev) pmu_regmcfg = regmap_smccfg; pmu_regmcfg.max_register = resource_size(res) - pmu_regmcfg.reg_stride; + pmu_regmcfg.wr_table = pmu_context->pmu_data->wr_table; + pmu_regmcfg.rd_table = pmu_context->pmu_data->rd_table; + /* Need physical address for SMC call */ regmap = devm_regmap_init(dev, NULL, (void *)(uintptr_t)res->start, diff --git a/drivers/soc/samsung/exynos-pmu.h b/drivers/soc/samsung/exynos-pmu.h index 0938bb4fe15f..1658a55fe61c 100644 --- a/drivers/soc/samsung/exynos-pmu.h +++ b/drivers/soc/samsung/exynos-pmu.h @@ -13,11 +13,38 @@ #define PMU_TABLE_END (-1U) +struct regmap_access_table; + struct exynos_pmu_conf { unsigned int offset; u8 val[NUM_SYS_POWERDOWN]; }; +/** + * struct exynos_pmu_data - of_device_id (match) data + * + * @pmu_config: Optional table detailing register writes for target system + * states: SYS_AFTR, SYS_LPA, SYS_SLEEP. + * @pmu_config_extra: Optional secondary table detailing additional register + * writes for target system states: SYS_AFTR, SYS_LPA, + * SYS_SLEEP. + * @pmu_secure: Whether or not PMU register writes need to be done via SMC call. + * @pmu_cpuhp: Whether or not extra handling is required for CPU hotplug and + * CPUidle outside of standard PSCI calls, due to non-compliant + * firmware. + * @pmu_init: Optional init function. + * @powerdown_conf: Optional callback before entering target system states: + * SYS_AFTR, SYS_LPA, SYS_SLEEP. This will be invoked before + * the registers from @pmu_config are written. + * @powerdown_conf_extra: Optional secondary callback before entering + * target system states: SYS_AFTR, SYS_LPA, SYS_SLEEP. + * This will be invoked after @pmu_config registers have + * been written. + * @rd_table: A table of readable register ranges in case a custom regmap is + * used (i.e. when @pmu_secure is @true). + * @wr_table: A table of writable register ranges in case a custom regmap is + * used (i.e. when @pmu_secure is @true). + */ struct exynos_pmu_data { const struct exynos_pmu_conf *pmu_config; const struct exynos_pmu_conf *pmu_config_extra; @@ -27,6 +54,9 @@ struct exynos_pmu_data { void (*pmu_init)(void); void (*powerdown_conf)(enum sys_powerdown); void (*powerdown_conf_extra)(enum sys_powerdown); + + const struct regmap_access_table *rd_table; + const struct regmap_access_table *wr_table; }; extern void __iomem *pmu_base_addr; From b320711e4c377b0e2ce0b296ba9485cf3f9eb10d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Draszik?= Date: Thu, 9 Oct 2025 10:31:26 +0100 Subject: [PATCH 028/114] soc: samsung: exynos-pmu: move some gs101 related code into new file MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit To avoid cluttering common code, move most of the gs101 code into a new file, gs101-pmu.c More code is going to be added for gs101 - having it all in one file helps keeping the common code (file) more readable. While at it, rename variables 'ctx' to 'context' for consistency. No functional change. Reviewed-by: Sam Protsenko Signed-off-by: André Draszik Link: https://patch.msgid.link/20251009-gs101-pmu-regmap-tables-v2-2-2d64f5261952@linaro.org Signed-off-by: Krzysztof Kozlowski --- MAINTAINERS | 1 + drivers/soc/samsung/Makefile | 3 +- drivers/soc/samsung/exynos-pmu.c | 133 ----------------------------- drivers/soc/samsung/exynos-pmu.h | 7 ++ drivers/soc/samsung/gs101-pmu.c | 142 +++++++++++++++++++++++++++++++ 5 files changed, 152 insertions(+), 134 deletions(-) create mode 100644 drivers/soc/samsung/gs101-pmu.c diff --git a/MAINTAINERS b/MAINTAINERS index 46126ce2f968..88bd72b2761c 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -10600,6 +10600,7 @@ F: Documentation/devicetree/bindings/clock/google,gs101-clock.yaml F: Documentation/devicetree/bindings/soc/google/google,gs101-pmu-intr-gen.yaml F: arch/arm64/boot/dts/exynos/google/ F: drivers/clk/samsung/clk-gs101.c +F: drivers/soc/samsung/gs101-pmu.c F: drivers/phy/samsung/phy-gs101-ufs.c F: include/dt-bindings/clock/google,gs101.h K: [gG]oogle.?[tT]ensor diff --git a/drivers/soc/samsung/Makefile b/drivers/soc/samsung/Makefile index 248a33d7754a..636a762608c9 100644 --- a/drivers/soc/samsung/Makefile +++ b/drivers/soc/samsung/Makefile @@ -6,7 +6,8 @@ exynos_chipid-y += exynos-chipid.o exynos-asv.o obj-$(CONFIG_EXYNOS_USI) += exynos-usi.o -obj-$(CONFIG_EXYNOS_PMU) += exynos-pmu.o +obj-$(CONFIG_EXYNOS_PMU) += exynos_pmu.o +exynos_pmu-y += exynos-pmu.o gs101-pmu.o obj-$(CONFIG_EXYNOS_PMU_ARM_DRIVERS) += exynos3250-pmu.o exynos4-pmu.o \ exynos5250-pmu.o exynos5420-pmu.o diff --git a/drivers/soc/samsung/exynos-pmu.c b/drivers/soc/samsung/exynos-pmu.c index 565eb75b003a..f258a4ec2a33 100644 --- a/drivers/soc/samsung/exynos-pmu.c +++ b/drivers/soc/samsung/exynos-pmu.c @@ -6,7 +6,6 @@ // Exynos - CPU PMU(Power Management Unit) support #include -#include #include #include #include @@ -25,14 +24,6 @@ #include "exynos-pmu.h" -#define PMUALIVE_MASK GENMASK(13, 0) -#define TENSOR_SET_BITS (BIT(15) | BIT(14)) -#define TENSOR_CLR_BITS BIT(15) -#define TENSOR_SMC_PMU_SEC_REG 0x82000504 -#define TENSOR_PMUREG_READ 0 -#define TENSOR_PMUREG_WRITE 1 -#define TENSOR_PMUREG_RMW 2 - struct exynos_pmu_context { struct device *dev; const struct exynos_pmu_data *pmu_data; @@ -54,125 +45,6 @@ static struct exynos_pmu_context *pmu_context; /* forward declaration */ static struct platform_driver exynos_pmu_driver; -/* - * Tensor SoCs are configured so that PMU_ALIVE registers can only be written - * from EL3, but are still read accessible. As Linux needs to write some of - * these registers, the following functions are provided and exposed via - * regmap. - * - * Note: This SMC interface is known to be implemented on gs101 and derivative - * SoCs. - */ - -/* Write to a protected PMU register. */ -static int tensor_sec_reg_write(void *context, unsigned int reg, - unsigned int val) -{ - struct arm_smccc_res res; - unsigned long pmu_base = (unsigned long)context; - - arm_smccc_smc(TENSOR_SMC_PMU_SEC_REG, pmu_base + reg, - TENSOR_PMUREG_WRITE, val, 0, 0, 0, 0, &res); - - /* returns -EINVAL if access isn't allowed or 0 */ - if (res.a0) - pr_warn("%s(): SMC failed: %d\n", __func__, (int)res.a0); - - return (int)res.a0; -} - -/* Read/Modify/Write a protected PMU register. */ -static int tensor_sec_reg_rmw(void *context, unsigned int reg, - unsigned int mask, unsigned int val) -{ - struct arm_smccc_res res; - unsigned long pmu_base = (unsigned long)context; - - arm_smccc_smc(TENSOR_SMC_PMU_SEC_REG, pmu_base + reg, - TENSOR_PMUREG_RMW, mask, val, 0, 0, 0, &res); - - /* returns -EINVAL if access isn't allowed or 0 */ - if (res.a0) - pr_warn("%s(): SMC failed: %d\n", __func__, (int)res.a0); - - return (int)res.a0; -} - -/* - * Read a protected PMU register. All PMU registers can be read by Linux. - * Note: The SMC read register is not used, as only registers that can be - * written are readable via SMC. - */ -static int tensor_sec_reg_read(void *context, unsigned int reg, - unsigned int *val) -{ - *val = pmu_raw_readl(reg); - return 0; -} - -/* - * For SoCs that have set/clear bit hardware this function can be used when - * the PMU register will be accessed by multiple masters. - * - * For example, to set bits 13:8 in PMU reg offset 0x3e80 - * tensor_set_bits_atomic(ctx, 0x3e80, 0x3f00, 0x3f00); - * - * Set bit 8, and clear bits 13:9 PMU reg offset 0x3e80 - * tensor_set_bits_atomic(0x3e80, 0x100, 0x3f00); - */ -static int tensor_set_bits_atomic(void *ctx, unsigned int offset, u32 val, - u32 mask) -{ - int ret; - unsigned int i; - - for (i = 0; i < 32; i++) { - if (!(mask & BIT(i))) - continue; - - offset &= ~TENSOR_SET_BITS; - - if (val & BIT(i)) - offset |= TENSOR_SET_BITS; - else - offset |= TENSOR_CLR_BITS; - - ret = tensor_sec_reg_write(ctx, offset, i); - if (ret) - return ret; - } - return 0; -} - -static bool tensor_is_atomic(unsigned int reg) -{ - /* - * Use atomic operations for PMU_ALIVE registers (offset 0~0x3FFF) - * as the target registers can be accessed by multiple masters. SFRs - * that don't support atomic are added to the switch statement below. - */ - if (reg > PMUALIVE_MASK) - return false; - - switch (reg) { - case GS101_SYSIP_DAT0: - case GS101_SYSTEM_CONFIGURATION: - return false; - default: - return true; - } -} - -static int tensor_sec_update_bits(void *ctx, unsigned int reg, - unsigned int mask, unsigned int val) -{ - - if (!tensor_is_atomic(reg)) - return tensor_sec_reg_rmw(ctx, reg, mask, val); - - return tensor_set_bits_atomic(ctx, reg, val, mask); -} - void pmu_raw_writel(u32 val, u32 offset) { writel_relaxed(val, pmu_base_addr + offset); @@ -244,11 +116,6 @@ static const struct regmap_config regmap_pmu_intr = { .use_raw_spinlock = true, }; -static const struct exynos_pmu_data gs101_pmu_data = { - .pmu_secure = true, - .pmu_cpuhp = true, -}; - /* * PMU platform driver and devicetree bindings. */ diff --git a/drivers/soc/samsung/exynos-pmu.h b/drivers/soc/samsung/exynos-pmu.h index 1658a55fe61c..fbe381e2a2e1 100644 --- a/drivers/soc/samsung/exynos-pmu.h +++ b/drivers/soc/samsung/exynos-pmu.h @@ -70,7 +70,14 @@ extern const struct exynos_pmu_data exynos4412_pmu_data; extern const struct exynos_pmu_data exynos5250_pmu_data; extern const struct exynos_pmu_data exynos5420_pmu_data; #endif +extern const struct exynos_pmu_data gs101_pmu_data; extern void pmu_raw_writel(u32 val, u32 offset); extern u32 pmu_raw_readl(u32 offset); + +int tensor_sec_reg_write(void *context, unsigned int reg, unsigned int val); +int tensor_sec_reg_read(void *context, unsigned int reg, unsigned int *val); +int tensor_sec_update_bits(void *context, unsigned int reg, unsigned int mask, + unsigned int val); + #endif /* __EXYNOS_PMU_H */ diff --git a/drivers/soc/samsung/gs101-pmu.c b/drivers/soc/samsung/gs101-pmu.c new file mode 100644 index 000000000000..ec345d09f21f --- /dev/null +++ b/drivers/soc/samsung/gs101-pmu.c @@ -0,0 +1,142 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright 2025 Linaro Ltd. + * + * GS101 PMU (Power Management Unit) support + */ + +#include +#include +#include +#include + +#include "exynos-pmu.h" + +#define PMUALIVE_MASK GENMASK(13, 0) +#define TENSOR_SET_BITS (BIT(15) | BIT(14)) +#define TENSOR_CLR_BITS BIT(15) +#define TENSOR_SMC_PMU_SEC_REG 0x82000504 +#define TENSOR_PMUREG_READ 0 +#define TENSOR_PMUREG_WRITE 1 +#define TENSOR_PMUREG_RMW 2 + +const struct exynos_pmu_data gs101_pmu_data = { + .pmu_secure = true, + .pmu_cpuhp = true, +}; + +/* + * Tensor SoCs are configured so that PMU_ALIVE registers can only be written + * from EL3, but are still read accessible. As Linux needs to write some of + * these registers, the following functions are provided and exposed via + * regmap. + * + * Note: This SMC interface is known to be implemented on gs101 and derivative + * SoCs. + */ + +/* Write to a protected PMU register. */ +int tensor_sec_reg_write(void *context, unsigned int reg, unsigned int val) +{ + struct arm_smccc_res res; + unsigned long pmu_base = (unsigned long)context; + + arm_smccc_smc(TENSOR_SMC_PMU_SEC_REG, pmu_base + reg, + TENSOR_PMUREG_WRITE, val, 0, 0, 0, 0, &res); + + /* returns -EINVAL if access isn't allowed or 0 */ + if (res.a0) + pr_warn("%s(): SMC failed: %d\n", __func__, (int)res.a0); + + return (int)res.a0; +} + +/* Read/Modify/Write a protected PMU register. */ +static int tensor_sec_reg_rmw(void *context, unsigned int reg, + unsigned int mask, unsigned int val) +{ + struct arm_smccc_res res; + unsigned long pmu_base = (unsigned long)context; + + arm_smccc_smc(TENSOR_SMC_PMU_SEC_REG, pmu_base + reg, + TENSOR_PMUREG_RMW, mask, val, 0, 0, 0, &res); + + /* returns -EINVAL if access isn't allowed or 0 */ + if (res.a0) + pr_warn("%s(): SMC failed: %d\n", __func__, (int)res.a0); + + return (int)res.a0; +} + +/* + * Read a protected PMU register. All PMU registers can be read by Linux. + * Note: The SMC read register is not used, as only registers that can be + * written are readable via SMC. + */ +int tensor_sec_reg_read(void *context, unsigned int reg, unsigned int *val) +{ + *val = pmu_raw_readl(reg); + return 0; +} + +/* + * For SoCs that have set/clear bit hardware this function can be used when + * the PMU register will be accessed by multiple masters. + * + * For example, to set bits 13:8 in PMU reg offset 0x3e80 + * tensor_set_bits_atomic(ctx, 0x3e80, 0x3f00, 0x3f00); + * + * Set bit 8, and clear bits 13:9 PMU reg offset 0x3e80 + * tensor_set_bits_atomic(0x3e80, 0x100, 0x3f00); + */ +static int tensor_set_bits_atomic(void *context, unsigned int offset, u32 val, + u32 mask) +{ + int ret; + unsigned int i; + + for (i = 0; i < 32; i++) { + if (!(mask & BIT(i))) + continue; + + offset &= ~TENSOR_SET_BITS; + + if (val & BIT(i)) + offset |= TENSOR_SET_BITS; + else + offset |= TENSOR_CLR_BITS; + + ret = tensor_sec_reg_write(context, offset, i); + if (ret) + return ret; + } + return 0; +} + +static bool tensor_is_atomic(unsigned int reg) +{ + /* + * Use atomic operations for PMU_ALIVE registers (offset 0~0x3FFF) + * as the target registers can be accessed by multiple masters. SFRs + * that don't support atomic are added to the switch statement below. + */ + if (reg > PMUALIVE_MASK) + return false; + + switch (reg) { + case GS101_SYSIP_DAT0: + case GS101_SYSTEM_CONFIGURATION: + return false; + default: + return true; + } +} + +int tensor_sec_update_bits(void *context, unsigned int reg, unsigned int mask, + unsigned int val) +{ + if (!tensor_is_atomic(reg)) + return tensor_sec_reg_rmw(context, reg, mask, val); + + return tensor_set_bits_atomic(context, reg, val, mask); +} From 8b9cd112f1ac8d72244b189654e693012ea8dfe0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Draszik?= Date: Thu, 9 Oct 2025 10:31:27 +0100 Subject: [PATCH 029/114] soc: samsung: gs101-pmu: implement access tables for read and write MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Accessing non-existent PMU registers causes an SError, halting the system. Implement read and write access tables for the gs101-PMU to specify which registers are read- and/or writable to avoid that SError. Reviewed-by: Sam Protsenko Signed-off-by: André Draszik Link: https://patch.msgid.link/20251009-gs101-pmu-regmap-tables-v2-3-2d64f5261952@linaro.org Signed-off-by: Krzysztof Kozlowski --- drivers/soc/samsung/gs101-pmu.c | 306 ++++++++++++++++- include/linux/soc/samsung/exynos-regs-pmu.h | 343 +++++++++++++++++++- 2 files changed, 640 insertions(+), 9 deletions(-) diff --git a/drivers/soc/samsung/gs101-pmu.c b/drivers/soc/samsung/gs101-pmu.c index ec345d09f21f..17dadc1b9c6e 100644 --- a/drivers/soc/samsung/gs101-pmu.c +++ b/drivers/soc/samsung/gs101-pmu.c @@ -9,6 +9,7 @@ #include #include #include +#include #include "exynos-pmu.h" @@ -20,9 +21,312 @@ #define TENSOR_PMUREG_WRITE 1 #define TENSOR_PMUREG_RMW 2 +static const struct regmap_range gs101_pmu_registers[] = { + regmap_reg_range(GS101_OM_STAT, GS101_SYSTEM_INFO), + regmap_reg_range(GS101_IDLE_IP(0), GS101_IDLE_IP_MASK(3)), + regmap_reg_range(GS101_DATARAM_STATE_SLC_CH(0), + GS101_PPMPURAM_INFORM_SCL_CH(3)), + regmap_reg_range(GS101_INFORM0, GS101_SYSIP_DAT(0)), + /* skip SYSIP_DAT1 SYSIP_DAT2 */ + regmap_reg_range(GS101_SYSIP_DAT(3), GS101_PWR_HOLD_SW_TRIP), + regmap_reg_range(GS101_GSA_INFORM(0), GS101_GSA_INFORM(1)), + regmap_reg_range(GS101_INFORM4, GS101_IROM_INFORM), + regmap_reg_range(GS101_IROM_CPU_INFORM(0), GS101_IROM_CPU_INFORM(7)), + regmap_reg_range(GS101_PMU_SPARE(0), GS101_PMU_SPARE(3)), + /* skip most IROM_xxx registers */ + regmap_reg_range(GS101_DREX_CALIBRATION(0), GS101_DREX_CALIBRATION(7)), + +#define CLUSTER_CPU_RANGE(cl, cpu) \ + regmap_reg_range(GS101_CLUSTER_CPU_CONFIGURATION(cl, cpu), \ + GS101_CLUSTER_CPU_OPTION(cl, cpu)), \ + regmap_reg_range(GS101_CLUSTER_CPU_OUT(cl, cpu), \ + GS101_CLUSTER_CPU_IN(cl, cpu)), \ + regmap_reg_range(GS101_CLUSTER_CPU_INT_IN(cl, cpu), \ + GS101_CLUSTER_CPU_INT_DIR(cl, cpu)) + + /* cluster 0..2 and cpu 0..4 or 0..1 */ + CLUSTER_CPU_RANGE(GS101_CLUSTER0_OFFSET, 0), + CLUSTER_CPU_RANGE(GS101_CLUSTER0_OFFSET, 1), + CLUSTER_CPU_RANGE(GS101_CLUSTER0_OFFSET, 2), + CLUSTER_CPU_RANGE(GS101_CLUSTER0_OFFSET, 3), + CLUSTER_CPU_RANGE(GS101_CLUSTER1_OFFSET, 0), + CLUSTER_CPU_RANGE(GS101_CLUSTER1_OFFSET, 1), + CLUSTER_CPU_RANGE(GS101_CLUSTER2_OFFSET, 0), + CLUSTER_CPU_RANGE(GS101_CLUSTER2_OFFSET, 1), +#undef CLUSTER_CPU_RANGE + +#define CLUSTER_NONCPU_RANGE(cl) \ + regmap_reg_range(GS101_CLUSTER_NONCPU_CONFIGURATION(cl), \ + GS101_CLUSTER_NONCPU_OPTION(cl)), \ + regmap_reg_range(GS101_CLUSTER_NONCPU_OUT(cl), \ + GS101_CLUSTER_NONCPU_IN(cl)), \ + regmap_reg_range(GS101_CLUSTER_NONCPU_INT_IN(cl), \ + GS101_CLUSTER_NONCPU_INT_DIR(cl)), \ + regmap_reg_range(GS101_CLUSTER_NONCPU_DUALRAIL_CTRL_OUT(cl), \ + GS101_CLUSTER_NONCPU_DUALRAIL_POS_OUT(cl)), \ + regmap_reg_range(GS101_CLUSTER_NONCPU_DUALRAIL_CTRL_IN(cl), \ + GS101_CLUSTER_NONCPU_DUALRAIL_CTRL_IN(cl)) + + CLUSTER_NONCPU_RANGE(0), + regmap_reg_range(GS101_CLUSTER0_NONCPU_DSU_PCH, + GS101_CLUSTER0_NONCPU_DSU_PCH), + CLUSTER_NONCPU_RANGE(1), + CLUSTER_NONCPU_RANGE(2), +#undef CLUSTER_NONCPU_RANGE + +#define SUBBLK_RANGE(blk) \ + regmap_reg_range(GS101_SUBBLK_CONFIGURATION(blk), \ + GS101_SUBBLK_CTRL(blk)), \ + regmap_reg_range(GS101_SUBBLK_OUT(blk), GS101_SUBBLK_IN(blk)), \ + regmap_reg_range(GS101_SUBBLK_INT_IN(blk), \ + GS101_SUBBLK_INT_DIR(blk)), \ + regmap_reg_range(GS101_SUBBLK_MEMORY_OUT(blk), \ + GS101_SUBBLK_MEMORY_IN(blk)) + + SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_ALIVE), + SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_AOC), + SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_APM), + SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_CMU), + SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_BUS0), + SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_BUS1), + SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_BUS2), + SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_CORE), + SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_EH), + SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_CPUCL0), + SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_CPUCL1), + SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_CPUCL2), + SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_G3D), + SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_EMBEDDED_CPUCL0), + SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_EMBEDDED_G3D), + SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_HSI0), + SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_HSI1), + SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_HSI2), + SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_DPU), + SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_DISP), + SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_G2D), + SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_MFC), + SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_CSIS), + SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_PDP), + SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_DNS), + SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_G3AA), + SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_IPP), + SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_ITP), + SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_MCSC), + SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_GDC), + SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_TNR), + SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_BO), + SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_TPU), + SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_MIF0), + SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_MIF1), + SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_MIF2), + SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_MIF3), + SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_MISC), + SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_PERIC0), + SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_PERIC1), + SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_S2D), +#undef SUBBLK_RANGE + +#define SUBBLK_CPU_RANGE(blk) \ + regmap_reg_range(GS101_SUBBLK_CPU_CONFIGURATION(blk), \ + GS101_SUBBLK_CPU_OPTION(blk)), \ + regmap_reg_range(GS101_SUBBLK_CPU_OUT(blk), \ + GS101_SUBBLK_CPU_IN(blk)), \ + regmap_reg_range(GS101_SUBBLK_CPU_INT_IN(blk), \ + GS101_SUBBLK_CPU_INT_DIR(blk)) + + SUBBLK_CPU_RANGE(GS101_SUBBBLK_CPU_OFFSET_APM), + SUBBLK_CPU_RANGE(GS101_SUBBBLK_CPU_OFFSET_DBGCORE), + SUBBLK_CPU_RANGE(GS101_SUBBBLK_CPU_OFFSET_SSS), +#undef SUBBLK_CPU_RANGE + + regmap_reg_range(GS101_MIF_CONFIGURATION, GS101_MIF_CTRL), + regmap_reg_range(GS101_MIF_OUT, GS101_MIF_IN), + regmap_reg_range(GS101_MIF_INT_IN, GS101_MIF_INT_DIR), + regmap_reg_range(GS101_TOP_CONFIGURATION, GS101_TOP_OPTION), + regmap_reg_range(GS101_TOP_OUT, GS101_TOP_IN), + regmap_reg_range(GS101_TOP_INT_IN, GS101_WAKEUP2_STAT), + regmap_reg_range(GS101_WAKEUP2_INT_IN, GS101_WAKEUP2_INT_DIR), + regmap_reg_range(GS101_SYSTEM_CONFIGURATION, GS101_USER_DEFINED_OUT), + regmap_reg_range(GS101_SYSTEM_OUT, GS101_SYSTEM_IN), + regmap_reg_range(GS101_SYSTEM_INT_IN, GS101_EINT_WAKEUP_MASK3), + regmap_reg_range(GS101_USER_DEFINED_INT_IN, GS101_SCAN2DRAM_INT_DIR), + /* skip HCU_START */ + regmap_reg_range(GS101_CUSTOM_OUT, GS101_CUSTOM_IN), + regmap_reg_range(GS101_CUSTOM_INT_IN, GS101_CUSTOM_INT_DIR), + regmap_reg_range(GS101_ACK_LAST_CPU, GS101_HCU_R(3)), + regmap_reg_range(GS101_HCU_SP, GS101_HCU_PC), + /* skip PMU_RAM_CTRL */ + regmap_reg_range(GS101_APM_HCU_CTRL, GS101_APM_HCU_CTRL), + regmap_reg_range(GS101_APM_NMI_ENABLE, GS101_RST_STAT_PMU), + regmap_reg_range(GS101_HPM_INT_IN, GS101_BOOT_STAT), + regmap_reg_range(GS101_PMLINK_OUT, GS101_PMLINK_AOC_CTRL), + regmap_reg_range(GS101_TCXO_BUF_CTRL, GS101_ADD_CTRL), + regmap_reg_range(GS101_HCU_TIMEOUT_RESET, GS101_HCU_TIMEOUT_SCAN2DRAM), + regmap_reg_range(GS101_TIMER(0), GS101_TIMER(3)), + regmap_reg_range(GS101_PPC_MIF(0), GS101_PPC_EH), + /* PPC_OFFSET, skip PPC_CPUCL1_0 PPC_CPUCL1_1 */ + regmap_reg_range(GS101_EXT_REGULATOR_MIF_DURATION, GS101_TCXO_DURATION), + regmap_reg_range(GS101_BURNIN_CTRL, GS101_TMU_SUB_TRIP), + regmap_reg_range(GS101_MEMORY_CEN, GS101_MEMORY_SMX_FEEDBACK), + regmap_reg_range(GS101_SLC_PCH_CHANNEL, GS101_SLC_PCH_CB), + regmap_reg_range(GS101_FORCE_NOMC, GS101_FORCE_NOMC), + regmap_reg_range(GS101_FORCE_BOOST, GS101_PMLINK_SLC_BUSY), + regmap_reg_range(GS101_BOOTSYNC_OUT, GS101_CTRL_SECJTAG_ALIVE), + regmap_reg_range(GS101_CTRL_DIV_PLL_ALV_DIVLOW, GS101_CTRL_CLKDIV__CLKRTC), + regmap_reg_range(GS101_CTRL_SOC32K, GS101_CTRL_SBU_SW_EN), + regmap_reg_range(GS101_PAD_CTRL_CLKOUT0, GS101_PAD_CTRL_WRESETO_n), + regmap_reg_range(GS101_PHY_CTRL_USB20, GS101_PHY_CTRL_UFS), +}; + +static const struct regmap_range gs101_pmu_ro_registers[] = { + regmap_reg_range(GS101_OM_STAT, GS101_VERSION), + regmap_reg_range(GS101_OTP_STATUS, GS101_OTP_STATUS), + + regmap_reg_range(GS101_DATARAM_STATE_SLC_CH(0), + GS101_PPMPURAM_STATE_SLC_CH(0)), + regmap_reg_range(GS101_DATARAM_STATE_SLC_CH(1), + GS101_PPMPURAM_STATE_SLC_CH(1)), + regmap_reg_range(GS101_DATARAM_STATE_SLC_CH(2), + GS101_PPMPURAM_STATE_SLC_CH(2)), + regmap_reg_range(GS101_DATARAM_STATE_SLC_CH(3), + GS101_PPMPURAM_STATE_SLC_CH(3)), + +#define CLUSTER_CPU_RANGE(cl, cpu) \ + regmap_reg_range(GS101_CLUSTER_CPU_IN(cl, cpu), \ + GS101_CLUSTER_CPU_IN(cl, cpu)), \ + regmap_reg_range(GS101_CLUSTER_CPU_INT_IN(cl, cpu), \ + GS101_CLUSTER_CPU_INT_IN(cl, cpu)) + + CLUSTER_CPU_RANGE(GS101_CLUSTER0_OFFSET, 0), + CLUSTER_CPU_RANGE(GS101_CLUSTER0_OFFSET, 1), + CLUSTER_CPU_RANGE(GS101_CLUSTER0_OFFSET, 2), + CLUSTER_CPU_RANGE(GS101_CLUSTER0_OFFSET, 3), + CLUSTER_CPU_RANGE(GS101_CLUSTER1_OFFSET, 0), + CLUSTER_CPU_RANGE(GS101_CLUSTER1_OFFSET, 1), + CLUSTER_CPU_RANGE(GS101_CLUSTER2_OFFSET, 0), + CLUSTER_CPU_RANGE(GS101_CLUSTER2_OFFSET, 1), +#undef CLUSTER_CPU_RANGE + +#define CLUSTER_NONCPU_RANGE(cl) \ + regmap_reg_range(GS101_CLUSTER_NONCPU_IN(cl), \ + GS101_CLUSTER_NONCPU_IN(cl)), \ + regmap_reg_range(GS101_CLUSTER_NONCPU_INT_IN(cl), \ + GS101_CLUSTER_NONCPU_INT_IN(cl)), \ + regmap_reg_range(GS101_CLUSTER_NONCPU_DUALRAIL_CTRL_IN(cl), \ + GS101_CLUSTER_NONCPU_DUALRAIL_CTRL_IN(cl)) + + CLUSTER_NONCPU_RANGE(0), + CLUSTER_NONCPU_RANGE(1), + CLUSTER_NONCPU_RANGE(2), + regmap_reg_range(GS101_CLUSTER_NONCPU_INT_EN(2), + GS101_CLUSTER_NONCPU_INT_DIR(2)), +#undef CLUSTER_NONCPU_RANGE + +#define SUBBLK_RANGE(blk) \ + regmap_reg_range(GS101_SUBBLK_IN(blk), GS101_SUBBLK_IN(blk)), \ + regmap_reg_range(GS101_SUBBLK_INT_IN(blk), \ + GS101_SUBBLK_INT_IN(blk)), \ + regmap_reg_range(GS101_SUBBLK_MEMORY_IN(blk), \ + GS101_SUBBLK_MEMORY_IN(blk)) + + SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_ALIVE), + SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_AOC), + SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_APM), + SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_CMU), + SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_BUS0), + SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_BUS1), + SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_BUS2), + SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_CORE), + SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_EH), + SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_CPUCL0), + SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_CPUCL1), + SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_CPUCL2), + SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_G3D), + SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_EMBEDDED_CPUCL0), + SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_EMBEDDED_G3D), + SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_HSI0), + SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_HSI1), + SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_HSI2), + SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_DPU), + SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_DISP), + SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_G2D), + SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_MFC), + SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_CSIS), + SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_PDP), + SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_DNS), + SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_G3AA), + SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_IPP), + SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_ITP), + SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_MCSC), + SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_GDC), + SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_TNR), + SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_BO), + SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_TPU), + SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_MIF0), + SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_MIF1), + SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_MIF2), + SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_MIF3), + SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_MISC), + SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_PERIC0), + SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_PERIC1), + SUBBLK_RANGE(GS101_SUBBBLK_OFFSET_S2D), +#undef SUBBLK_RANGE + +#define SUBBLK_CPU_RANGE(blk) \ + regmap_reg_range(GS101_SUBBLK_CPU_IN(blk), \ + GS101_SUBBLK_CPU_IN(blk)), \ + regmap_reg_range(GS101_SUBBLK_CPU_INT_IN(blk), \ + GS101_SUBBLK_CPU_INT_IN(blk)) + + SUBBLK_CPU_RANGE(GS101_SUBBBLK_CPU_OFFSET_APM), + SUBBLK_CPU_RANGE(GS101_SUBBBLK_CPU_OFFSET_DBGCORE), + SUBBLK_CPU_RANGE(GS101_SUBBBLK_CPU_OFFSET_SSS), +#undef SUBBLK_CPU_RANGE + + regmap_reg_range(GS101_MIF_CONFIGURATION, GS101_MIF_CONFIGURATION), + regmap_reg_range(GS101_MIF_IN, GS101_MIF_IN), + regmap_reg_range(GS101_MIF_INT_IN, GS101_MIF_INT_IN), + regmap_reg_range(GS101_TOP_IN, GS101_TOP_IN), + regmap_reg_range(GS101_TOP_INT_IN, GS101_TOP_INT_IN), + regmap_reg_range(GS101_WAKEUP2_INT_IN, GS101_WAKEUP2_INT_IN), + regmap_reg_range(GS101_SYSTEM_IN, GS101_SYSTEM_IN), + regmap_reg_range(GS101_SYSTEM_INT_IN, GS101_SYSTEM_INT_IN), + regmap_reg_range(GS101_EINT_INT_IN, GS101_EINT_INT_IN), + regmap_reg_range(GS101_EINT2_INT_IN, GS101_EINT2_INT_IN), + regmap_reg_range(GS101_EINT3_INT_IN, GS101_EINT3_INT_IN), + regmap_reg_range(GS101_USER_DEFINED_INT_IN, GS101_USER_DEFINED_INT_IN), + regmap_reg_range(GS101_SCAN2DRAM_INT_IN, GS101_SCAN2DRAM_INT_IN), + regmap_reg_range(GS101_CUSTOM_IN, GS101_CUSTOM_IN), + regmap_reg_range(GS101_CUSTOM_INT_IN, GS101_CUSTOM_INT_IN), + regmap_reg_range(GS101_HCU_R(0), GS101_HCU_R(3)), + regmap_reg_range(GS101_HCU_SP, GS101_HCU_PC), + regmap_reg_range(GS101_NMI_SRC_IN, GS101_NMI_SRC_IN), + regmap_reg_range(GS101_HPM_INT_IN, GS101_HPM_INT_IN), + regmap_reg_range(GS101_MEMORY_PGEN_FEEDBACK, GS101_MEMORY_PGEN_FEEDBACK), + regmap_reg_range(GS101_MEMORY_SMX_FEEDBACK, GS101_MEMORY_SMX_FEEDBACK), + regmap_reg_range(GS101_PMLINK_SLC_ACK, GS101_PMLINK_SLC_BUSY), + regmap_reg_range(GS101_BOOTSYNC_IN, GS101_BOOTSYNC_IN), + regmap_reg_range(GS101_SCAN_READY_IN, GS101_SCAN_READY_IN), + regmap_reg_range(GS101_CTRL_PLL_ALV_LOCK, GS101_CTRL_PLL_ALV_LOCK), +}; + +static const struct regmap_access_table gs101_pmu_rd_table = { + .yes_ranges = gs101_pmu_registers, + .n_yes_ranges = ARRAY_SIZE(gs101_pmu_registers), +}; + +static const struct regmap_access_table gs101_pmu_wr_table = { + .yes_ranges = gs101_pmu_registers, + .n_yes_ranges = ARRAY_SIZE(gs101_pmu_registers), + .no_ranges = gs101_pmu_ro_registers, + .n_no_ranges = ARRAY_SIZE(gs101_pmu_ro_registers), +}; + const struct exynos_pmu_data gs101_pmu_data = { .pmu_secure = true, .pmu_cpuhp = true, + .rd_table = &gs101_pmu_rd_table, + .wr_table = &gs101_pmu_wr_table, }; /* @@ -124,7 +428,7 @@ static bool tensor_is_atomic(unsigned int reg) return false; switch (reg) { - case GS101_SYSIP_DAT0: + case GS101_SYSIP_DAT(0): case GS101_SYSTEM_CONFIGURATION: return false; default: diff --git a/include/linux/soc/samsung/exynos-regs-pmu.h b/include/linux/soc/samsung/exynos-regs-pmu.h index 71e0c09a49eb..532c6c2d1195 100644 --- a/include/linux/soc/samsung/exynos-regs-pmu.h +++ b/include/linux/soc/samsung/exynos-regs-pmu.h @@ -672,14 +672,341 @@ /* For Tensor GS101 */ /* PMU ALIVE */ -#define GS101_SYSIP_DAT0 (0x810) -#define GS101_CPU0_INFORM (0x860) -#define GS101_CPU_INFORM(cpu) \ - (GS101_CPU0_INFORM + (cpu*4)) -#define GS101_SYSTEM_CONFIGURATION (0x3A00) -#define GS101_EINT_WAKEUP_MASK (0x3A80) -#define GS101_PHY_CTRL_USB20 (0x3EB0) -#define GS101_PHY_CTRL_USBDP (0x3EB4) +#define GS101_OM_STAT 0x0000 +#define GS101_VERSION 0x0004 +#define GS101_PORESET_CHECK 0x0008 +#define GS101_OTP_STATUS 0x000c +#define GS101_SYSTEM_INFO 0x0010 +#define GS101_IDLE_IP(n) (0x03e0 + ((n) & 3) * 4) +#define GS101_IDLE_IP_MASK(n) (0x03f0 + ((n) & 3) * 4) +#define GS101_SLC_CH_OFFSET(ch) (0x0400 + ((ch) & 3) * 0x10) +#define GS101_DATARAM_STATE_SLC_CH(ch) (GS101_SLC_CH_OFFSET(ch) + 0x00) +#define GS101_TAGRAM_STATE_SLC_CH(ch) (GS101_SLC_CH_OFFSET(ch) + 0x04) +#define GS101_LRURAM_STATE_SLC_CH(ch) (GS101_SLC_CH_OFFSET(ch) + 0x08) +#define GS101_PPMPURAM_STATE_SLC_CH(ch) (GS101_SLC_CH_OFFSET(ch) + 0x0c) +#define GS101_DATARAM_INFORM_SCL_CH(ch) (GS101_SLC_CH_OFFSET(ch) + 0x40) +#define GS101_TAGRAM_INFORM_SCL_CH(ch) (GS101_SLC_CH_OFFSET(ch) + 0x44) +#define GS101_LRURAM_INFORM_SCL_CH(ch) (GS101_SLC_CH_OFFSET(ch) + 0x48) +#define GS101_PPMPURAM_INFORM_SCL_CH(ch) (GS101_SLC_CH_OFFSET(ch) + 0x4c) +#define GS101_INFORM0 0x0800 +#define GS101_INFORM1 0x0804 +#define GS101_INFORM2 0x0808 +#define GS101_INFORM3 0x080c +#define GS101_SYSIP_DAT(n) (0x0810 + ((n) & 3) * 4) +#define GS101_PWR_HOLD_HW_TRIP 0x0820 +#define GS101_PWR_HOLD_SW_TRIP 0x0824 +#define GS101_GSA_INFORM(n) (0x0830 + ((n) & 1) * 4) +#define GS101_INFORM4 0x0840 +#define GS101_INFORM5 0x0844 +#define GS101_INFORM6 0x0848 +#define GS101_INFORM7 0x084c +#define GS101_INFORM8 0x0850 +#define GS101_INFORM9 0x0854 +#define GS101_INFORM10 0x0858 +#define GS101_INFORM11 0x085c +#define GS101_CPU_INFORM(cpu) (0x0860 + ((cpu) & 7) * 4) +#define GS101_IROM_INFORM 0x0880 +#define GS101_IROM_CPU_INFORM(cpu) (0x0890 + ((cpu) & 7) * 4) +#define GS101_PMU_SPARE(n) (0x0900 + ((n) & 3) * 4) +#define GS101_IROM_DATA_REG(n) (0x0980 + ((n) & 3) * 4) +#define GS101_IROM_PWRMODE 0x0990 +#define GS101_DREX_CALIBRATION(n) (0x09a0 + ((n) & 7) * 4) + +#define GS101_CLUSTER0_OFFSET 0x1000 +#define GS101_CLUSTER1_OFFSET 0x1300 +#define GS101_CLUSTER2_OFFSET 0x1500 +#define GS101_CLUSTER_CPU_OFFSET(cl, cpu) ((cl) + ((cpu) * 0x80)) +#define GS101_CLUSTER_CPU_CONFIGURATION(cl, cpu) \ + (GS101_CLUSTER_CPU_OFFSET(cl, cpu) + 0x00) +#define GS101_CLUSTER_CPU_STATUS(cl, cpu) \ + (GS101_CLUSTER_CPU_OFFSET(cl, cpu) + 0x04) +#define GS101_CLUSTER_CPU_STATES(cl, cpu) \ + (GS101_CLUSTER_CPU_OFFSET(cl, cpu) + 0x08) +#define GS101_CLUSTER_CPU_OPTION(cl, cpu) \ + (GS101_CLUSTER_CPU_OFFSET(cl, cpu) + 0x0c) +#define GS101_CLUSTER_CPU_OUT(cl, cpu) \ + (GS101_CLUSTER_CPU_OFFSET(cl, cpu) + 0x20) +#define GS101_CLUSTER_CPU_IN(cl, cpu) \ + (GS101_CLUSTER_CPU_OFFSET(cl, cpu) + 0x24) +#define GS101_CLUSTER_CPU_INT_IN(cl, cpu) \ + (GS101_CLUSTER_CPU_OFFSET(cl, cpu) + 0x40) +#define GS101_CLUSTER_CPU_INT_EN(cl, cpu) \ + (GS101_CLUSTER_CPU_OFFSET(cl, cpu) + 0x44) +#define GS101_CLUSTER_CPU_INT_TYPE(cl, cpu) \ + (GS101_CLUSTER_CPU_OFFSET(cl, cpu) + 0x48) +#define GS101_CLUSTER_CPU_INT_DIR(cl, cpu) \ + (GS101_CLUSTER_CPU_OFFSET(cl, cpu) + 0x4c) + +#define GS101_CLUSTER_NONCPU_OFFSET(cl) (0x1200 + ((cl) * 0x200)) +#define GS101_CLUSTER_NONCPU_CONFIGURATION(cl) \ + (GS101_CLUSTER_NONCPU_OFFSET(cl) + 0x00) +#define GS101_CLUSTER_NONCPU_STATUS(cl) \ + (GS101_CLUSTER_NONCPU_OFFSET(cl) + 0x04) +#define GS101_CLUSTER_NONCPU_STATES(cl) \ + (GS101_CLUSTER_NONCPU_OFFSET(cl) + 0x08) +#define GS101_CLUSTER_NONCPU_OPTION(cl) \ + (GS101_CLUSTER_NONCPU_OFFSET(cl) + 0x0c) +#define GS101_CLUSTER_NONCPU_OUT(cl) \ + (GS101_CLUSTER_NONCPU_OFFSET(cl) + 0x20) +#define GS101_CLUSTER_NONCPU_IN(cl) \ + (GS101_CLUSTER_NONCPU_OFFSET(cl) + 0x24) +#define GS101_CLUSTER_NONCPU_INT_IN(cl) \ + (GS101_CLUSTER_NONCPU_OFFSET(cl) + 0x40) +#define GS101_CLUSTER_NONCPU_INT_EN(cl) \ + (GS101_CLUSTER_NONCPU_OFFSET(cl) + 0x44) +#define GS101_CLUSTER_NONCPU_INT_TYPE(cl) \ + (GS101_CLUSTER_NONCPU_OFFSET(cl) + 0x48) +#define GS101_CLUSTER_NONCPU_INT_DIR(cl) \ + (GS101_CLUSTER_NONCPU_OFFSET(cl) + 0x4c) +#define GS101_CLUSTER_NONCPU_DUALRAIL_CTRL_OUT(cl) \ + (GS101_CLUSTER_NONCPU_OFFSET(cl) + 0x60) +#define GS101_CLUSTER_NONCPU_DUALRAIL_POS_OUT(cl) \ + (GS101_CLUSTER_NONCPU_OFFSET(cl) + 0x64) +#define GS101_CLUSTER_NONCPU_DUALRAIL_CTRL_IN(cl) \ + (GS101_CLUSTER_NONCPU_OFFSET(cl) + 0x6c) +#define GS101_CLUSTER0_NONCPU_DSU_PCH \ + (GS101_CLUSTER_NONCPU_OFFSET(0) + 0x80) + +#define GS101_SUBBBLK_OFFSET_ALIVE 0x1800 +#define GS101_SUBBBLK_OFFSET_AOC 0x1880 +#define GS101_SUBBBLK_OFFSET_APM 0x1900 +#define GS101_SUBBBLK_OFFSET_CMU 0x1980 +#define GS101_SUBBBLK_OFFSET_BUS0 0x1a00 +#define GS101_SUBBBLK_OFFSET_BUS1 0x1a80 +#define GS101_SUBBBLK_OFFSET_BUS2 0x1b00 +#define GS101_SUBBBLK_OFFSET_CORE 0x1b80 +#define GS101_SUBBBLK_OFFSET_EH 0x1c00 +#define GS101_SUBBBLK_OFFSET_CPUCL0 0x1c80 +#define GS101_SUBBBLK_OFFSET_CPUCL1 0x1d00 +#define GS101_SUBBBLK_OFFSET_CPUCL2 0x1d80 +#define GS101_SUBBBLK_OFFSET_G3D 0x1e00 +#define GS101_SUBBBLK_OFFSET_EMBEDDED_CPUCL0 0x1e80 +#define GS101_SUBBBLK_OFFSET_EMBEDDED_G3D 0x2000 +#define GS101_SUBBBLK_OFFSET_HSI0 0x2080 +#define GS101_SUBBBLK_OFFSET_HSI1 0x2100 +#define GS101_SUBBBLK_OFFSET_HSI2 0x2180 +#define GS101_SUBBBLK_OFFSET_DPU 0x2200 +#define GS101_SUBBBLK_OFFSET_DISP 0x2280 +#define GS101_SUBBBLK_OFFSET_G2D 0x2300 +#define GS101_SUBBBLK_OFFSET_MFC 0x2380 +#define GS101_SUBBBLK_OFFSET_CSIS 0x2400 +#define GS101_SUBBBLK_OFFSET_PDP 0x2480 +#define GS101_SUBBBLK_OFFSET_DNS 0x2500 +#define GS101_SUBBBLK_OFFSET_G3AA 0x2580 +#define GS101_SUBBBLK_OFFSET_IPP 0x2600 +#define GS101_SUBBBLK_OFFSET_ITP 0x2680 +#define GS101_SUBBBLK_OFFSET_MCSC 0x2700 +#define GS101_SUBBBLK_OFFSET_GDC 0x2780 +#define GS101_SUBBBLK_OFFSET_TNR 0x2800 +#define GS101_SUBBBLK_OFFSET_BO 0x2880 +#define GS101_SUBBBLK_OFFSET_TPU 0x2900 +#define GS101_SUBBBLK_OFFSET_MIF0 0x2980 +#define GS101_SUBBBLK_OFFSET_MIF1 0x2a00 +#define GS101_SUBBBLK_OFFSET_MIF2 0x2a80 +#define GS101_SUBBBLK_OFFSET_MIF3 0x2b00 +#define GS101_SUBBBLK_OFFSET_MISC 0x2b80 +#define GS101_SUBBBLK_OFFSET_PERIC0 0x2c00 +#define GS101_SUBBBLK_OFFSET_PERIC1 0x2c80 +#define GS101_SUBBBLK_OFFSET_S2D 0x2d00 +#define GS101_SUBBLK_CONFIGURATION(blk) ((blk) + 0x00) +#define GS101_SUBBLK_STATUS(blk) ((blk) + 0x04) +#define GS101_SUBBLK_STATES(blk) ((blk) + 0x08) +#define GS101_SUBBLK_OPTION(blk) ((blk) + 0x0c) +#define GS101_SUBBLK_CTRL(blk) ((blk) + 0x10) +#define GS101_SUBBLK_OUT(blk) ((blk) + 0x20) +#define GS101_SUBBLK_IN(blk) ((blk) + 0x24) +#define GS101_SUBBLK_INT_IN(blk) ((blk) + 0x40) +#define GS101_SUBBLK_INT_EN(blk) ((blk) + 0x44) +#define GS101_SUBBLK_INT_TYPE(blk) ((blk) + 0x48) +#define GS101_SUBBLK_INT_DIR(blk) ((blk) + 0x4c) +#define GS101_SUBBLK_MEMORY_OUT(blk) ((blk) + 0x60) +#define GS101_SUBBLK_MEMORY_IN(blk) ((blk) + 0x64) + +#define GS101_SUBBBLK_CPU_OFFSET_APM 0x3000 +#define GS101_SUBBBLK_CPU_OFFSET_DBGCORE 0x3080 +#define GS101_SUBBBLK_CPU_OFFSET_SSS 0x3100 +#define GS101_SUBBLK_CPU_CONFIGURATION(blk) ((blk) + 0x00) +#define GS101_SUBBLK_CPU_STATUS(blk) ((blk) + 0x04) +#define GS101_SUBBLK_CPU_STATES(blk) ((blk) + 0x08) +#define GS101_SUBBLK_CPU_OPTION(blk) ((blk) + 0x0c) +#define GS101_SUBBLK_CPU_OUT(blk) ((blk) + 0x20) +#define GS101_SUBBLK_CPU_IN(blk) ((blk) + 0x24) +#define GS101_SUBBLK_CPU_INT_IN(blk) ((blk) + 0x40) +#define GS101_SUBBLK_CPU_INT_EN(blk) ((blk) + 0x44) +#define GS101_SUBBLK_CPU_INT_TYPE(blk) ((blk) + 0x48) +#define GS101_SUBBLK_CPU_INT_DIR(blk) ((blk) + 0x4c) + +#define GS101_MIF_CONFIGURATION 0x3800 +#define GS101_MIF_STATUS 0x3804 +#define GS101_MIF_STATES 0x3808 +#define GS101_MIF_OPTION 0x380c +#define GS101_MIF_CTRL 0x3810 +#define GS101_MIF_OUT 0x3820 +#define GS101_MIF_IN 0x3824 +#define GS101_MIF_INT_IN 0x3840 +#define GS101_MIF_INT_EN 0x3844 +#define GS101_MIF_INT_TYPE 0x3848 +#define GS101_MIF_INT_DIR 0x384c +#define GS101_TOP_CONFIGURATION 0x3900 +#define GS101_TOP_STATUS 0x3904 +#define GS101_TOP_STATES 0x3908 +#define GS101_TOP_OPTION 0x390c +#define GS101_TOP_OUT 0x3920 +#define GS101_TOP_IN 0x3924 +#define GS101_TOP_INT_IN 0x3940 +#define GS101_TOP_INT_EN 0x3944 +#define GS101_TOP_INT_TYPE 0x3948 +#define GS101_TOP_INT_DIR 0x394c +#define GS101_WAKEUP_STAT 0x3950 +#define GS101_WAKEUP2_STAT 0x3954 +#define GS101_WAKEUP2_INT_IN 0x3960 +#define GS101_WAKEUP2_INT_EN 0x3964 +#define GS101_WAKEUP2_INT_TYPE 0x3968 +#define GS101_WAKEUP2_INT_DIR 0x396c +#define GS101_SYSTEM_CONFIGURATION 0x3a00 +#define GS101_SYSTEM_STATUS 0x3a04 +#define GS101_SYSTEM_STATES 0x3a08 +#define GS101_SYSTEM_OPTION 0x3a0c +#define GS101_SYSTEM_CTRL 0x3a10 +#define GS101_SPARE_CTRL 0x3a14 +#define GS101_USER_DEFINED_OUT 0x3a18 +#define GS101_SYSTEM_OUT 0x3a20 +#define GS101_SYSTEM_IN 0x3a24 +#define GS101_SYSTEM_INT_IN 0x3a40 +#define GS101_SYSTEM_INT_EN 0x3a44 +#define GS101_SYSTEM_INT_TYPE 0x3a48 +#define GS101_SYSTEM_INT_DIR 0x3a4c +#define GS101_EINT_INT_IN 0x3a50 +#define GS101_EINT_INT_EN 0x3a54 +#define GS101_EINT_INT_TYPE 0x3a58 +#define GS101_EINT_INT_DIR 0x3a5c +#define GS101_EINT2_INT_IN 0x3a60 +#define GS101_EINT2_INT_EN 0x3a64 +#define GS101_EINT2_INT_TYPE 0x3a68 +#define GS101_EINT2_INT_DIR 0x3a6c +#define GS101_EINT3_INT_IN 0x3a70 +#define GS101_EINT3_INT_EN 0x3a74 +#define GS101_EINT3_INT_TYPE 0x3a78 +#define GS101_EINT3_INT_DIR 0x3a7c +#define GS101_EINT_WAKEUP_MASK 0x3a80 +#define GS101_EINT_WAKEUP_MASK2 0x3a84 +#define GS101_EINT_WAKEUP_MASK3 0x3a88 +#define GS101_USER_DEFINED_INT_IN 0x3a90 +#define GS101_USER_DEFINED_INT_EN 0x3a94 +#define GS101_USER_DEFINED_INT_TYPE 0x3a98 +#define GS101_USER_DEFINED_INT_DIR 0x3a9c +#define GS101_SCAN2DRAM_INT_IN 0x3aa0 +#define GS101_SCAN2DRAM_INT_EN 0x3aa4 +#define GS101_SCAN2DRAM_INT_TYPE 0x3aa8 +#define GS101_SCAN2DRAM_INT_DIR 0x3aac +#define GS101_HCU_START 0x3ab0 +#define GS101_CUSTOM_OUT 0x3ac0 +#define GS101_CUSTOM_IN 0x3ac4 +#define GS101_CUSTOM_INT_IN 0x3ad0 +#define GS101_CUSTOM_INT_EN 0x3ad4 +#define GS101_CUSTOM_INT_TYPE 0x3ad8 +#define GS101_CUSTOM_INT_DIR 0x3adc +#define GS101_ACK_LAST_CPU 0x3afc +#define GS101_HCU_R(n) (0x3b00 + ((n) & 3) * 4) +#define GS101_HCU_SP 0x3b14 +#define GS101_HCU_PC 0x3b18 +#define GS101_PMU_RAM_CTRL 0x3b20 +#define GS101_APM_HCU_CTRL 0x3b24 +#define GS101_APM_NMI_ENABLE 0x3b30 +#define GS101_DBGCORE_NMI_ENABLE 0x3b34 +#define GS101_HCU_NMI_ENABLE 0x3b38 +#define GS101_PWR_HOLD_WDT_ENABLE 0x3b3c +#define GS101_NMI_SRC_IN 0x3b40 +#define GS101_RST_STAT 0x3b44 +#define GS101_RST_STAT_PMU 0x3b48 +#define GS101_HPM_INT_IN 0x3b60 +#define GS101_HPM_INT_EN 0x3b64 +#define GS101_HPM_INT_TYPE 0x3b68 +#define GS101_HPM_INT_DIR 0x3b6c +#define GS101_S2D_AUTH 0x3b70 +#define GS101_BOOT_STAT 0x3b74 +#define GS101_PMLINK_OUT 0x3c00 +#define GS101_PMLINK_AOC_OUT 0x3c04 +#define GS101_PMLINK_AOC_CTRL 0x3c08 +#define GS101_TCXO_BUF_CTRL 0x3c10 +#define GS101_ADD_CTRL 0x3c14 +#define GS101_HCU_TIMEOUT_RESET 0x3c20 +#define GS101_HCU_TIMEOUT_SCAN2DRAM 0x3c24 +#define GS101_TIMER(n) (0x3c80 + ((n) & 3) * 4) +#define GS101_PPC_MIF(n) (0x3c90 + ((n) & 3) * 4) +#define GS101_PPC_CORE 0x3ca0 +#define GS101_PPC_EH 0x3ca4 +#define GS101_PPC_CPUCL1_0 0x3ca8 +#define GS101_PPC_CPUCL1_1 0x3cac +#define GS101_EXT_REGULATOR_MIF_DURATION 0x3cb0 +#define GS101_EXT_REGULATOR_TOP_DURATION 0x3cb4 +#define GS101_EXT_REGULATOR_CPUCL2_DURATION 0x3cb8 +#define GS101_EXT_REGULATOR_CPUCL1_DURATION 0x3cbc +#define GS101_EXT_REGULATOR_G3D_DURATION 0x3cc0 +#define GS101_EXT_REGULATOR_TPU_DURATION 0x3cc4 +#define GS101_TCXO_DURATION 0x3cc8 +#define GS101_BURNIN_CTRL 0x3cd0 +#define GS101_JTAG_DBG_DET 0x3cd4 +#define GS101_MMC_CONWKUP_CTRL 0x3cd8 +#define GS101_USBDPPHY0_USBDP_WAKEUP 0x3cdc +#define GS101_TMU_TOP_TRIP 0x3ce0 +#define GS101_TMU_SUB_TRIP 0x3ce4 +#define GS101_MEMORY_CEN 0x3d00 +#define GS101_MEMORY_PGEN 0x3d04 +#define GS101_MEMORY_RET 0x3d08 +#define GS101_MEMORY_PGEN_FEEDBACK 0x3d0c +#define GS101_MEMORY_SMX 0x3d10 +#define GS101_MEMORY_SMX_FEEDBACK 0x3d14 +#define GS101_SLC_PCH_CHANNEL 0x3d20 +#define GS101_SLC_PCH_CB 0x3d24 +#define GS101_FORCE_NOMC 0x3d3c +#define GS101_FORCE_BOOST 0x3d4c +#define GS101_PMLINK_SLC_REQ 0x3d50 +#define GS101_PMLINK_SLC_ACK 0x3d54 +#define GS101_PMLINK_SLC_BUSY 0x3d58 +#define GS101_BOOTSYNC_OUT 0x3d80 +#define GS101_BOOTSYNC_IN 0x3d84 +#define GS101_SCAN_READY_OUT 0x3d88 +#define GS101_SCAN_READY_IN 0x3d8c +#define GS101_GSA_RESTORE 0x3d90 +#define GS101_ALIVE_OTP_LATCH 0x3d94 +#define GS101_DEBUG_OVERRIDE 0x3d98 +#define GS101_WDT_OPTION 0x3d9c +#define GS101_AOC_WDT_CFG 0x3da0 +#define GS101_CTRL_SECJTAG_ALIVE 0x3da4 +#define GS101_CTRL_DIV_PLL_ALV_DIVLOW 0x3e00 +#define GS101_CTRL_MUX_CLK_APM_REFSRC_AUTORESTORE 0x3e04 +#define GS101_CTRL_MUX_CLK_APM_REFSRC 0x3e08 +#define GS101_CTRL_MUX_CLK_APM_REF 0x3e0c +#define GS101_CTRL_MUX_PLL_ALV_DIV4 0x3e10 +#define GS101_CTRL_PLL_ALV_DIV4 0x3e14 +#define GS101_CTRL_OSCCLK_APMGSA 0x3e18 +#define GS101_CTRL_BLK_AOC_CLKS 0x3e1c +#define GS101_CTRL_PLL_ALV_LOCK 0x3e20 +#define GS101_CTRL_CLKDIV__CLKRTC 0x3e24 +#define GS101_CTRL_SOC32K 0x3e30 +#define GS101_CTRL_STM_PMU 0x3e34 +#define GS101_CTRL_PMU_DEBUG 0x3e38 +#define GS101_CTRL_DEBUG_UART 0x3e3c +#define GS101_CTRL_TCK 0x3e40 +#define GS101_CTRL_SBU_SW_EN 0x3e44 +#define GS101_PAD_CTRL_CLKOUT0 0x3e80 +#define GS101_PAD_CTRL_CLKOUT1 0x3e84 +#define GS101_PAD_CTRL_APM_24MOUT_0 0x3e88 +#define GS101_PAD_CTRL_APM_24MOUT_1 0x3e8c +#define GS101_PAD_CTRL_IO_FORCE_RETENTION 0x3e90 +#define GS101_PAD_CTRL_APACTIVE_n 0x3e94 +#define GS101_PAD_CTRL_TCXO_ON 0x3e98 +#define GS101_PAD_CTRL_PWR_HOLD 0x3e9c +#define GS101_PAD_CTRL_RESETO_n 0x3ea0 +#define GS101_PAD_CTRL_WRESETO_n 0x3ea4 +#define GS101_PHY_CTRL_USB20 0x3eb0 +#define GS101_PHY_CTRL_USBDP 0x3eb4 +#define GS101_PHY_CTRL_MIPI_DCPHY_M4M4 0x3eb8 +#define GS101_PHY_CTRL_MIPI_DCPHY_S4S4S4S4 0x3ebc +#define GS101_PHY_CTRL_PCIE_GEN4_0 0x3ec0 +#define GS101_PHY_CTRL_PCIE_GEN4_1 0x3ec4 +#define GS101_PHY_CTRL_UFS 0x3ec8 /* PMU INTR GEN */ #define GS101_GRP1_INTR_BID_UPEND (0x0108) From edd548dc64a699d71ea4f537f815044e763d01e1 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Fri, 17 Oct 2025 12:13:23 -0700 Subject: [PATCH 030/114] firmware: qcom: tzmem: fix qcom_tzmem_policy kernel-doc Fix kernel-doc warnings by using correct kernel-doc syntax and formatting to prevent warnings: Warning: include/linux/firmware/qcom/qcom_tzmem.h:25 Enum value 'QCOM_TZMEM_POLICY_STATIC' not described in enum 'qcom_tzmem_policy' Warning: ../include/linux/firmware/qcom/qcom_tzmem.h:25 Enum value 'QCOM_TZMEM_POLICY_MULTIPLIER' not described in enum 'qcom_tzmem_policy' Warning: ../include/linux/firmware/qcom/qcom_tzmem.h:25 Enum value 'QCOM_TZMEM_POLICY_ON_DEMAND' not described in enum 'qcom_tzmem_policy' Fixes: 84f5a7b67b61 ("firmware: qcom: add a dedicated TrustZone buffer allocator") Signed-off-by: Randy Dunlap Link: https://lore.kernel.org/r/20251017191323.1820167-1-rdunlap@infradead.org Signed-off-by: Bjorn Andersson --- include/linux/firmware/qcom/qcom_tzmem.h | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/include/linux/firmware/qcom/qcom_tzmem.h b/include/linux/firmware/qcom/qcom_tzmem.h index 48ac0e5454c7..23173e0c3ddd 100644 --- a/include/linux/firmware/qcom/qcom_tzmem.h +++ b/include/linux/firmware/qcom/qcom_tzmem.h @@ -17,11 +17,20 @@ struct qcom_tzmem_pool; * enum qcom_tzmem_policy - Policy for pool growth. */ enum qcom_tzmem_policy { - /**< Static pool, never grow above initial size. */ + /** + * @QCOM_TZMEM_POLICY_STATIC: Static pool, + * never grow above initial size. + */ QCOM_TZMEM_POLICY_STATIC = 1, - /**< When out of memory, add increment * current size of memory. */ + /** + * @QCOM_TZMEM_POLICY_MULTIPLIER: When out of memory, + * add increment * current size of memory. + */ QCOM_TZMEM_POLICY_MULTIPLIER, - /**< When out of memory add as much as is needed until max_size. */ + /** + * @QCOM_TZMEM_POLICY_ON_DEMAND: When out of memory + * add as much as is needed until max_size. + */ QCOM_TZMEM_POLICY_ON_DEMAND, }; From fc3d701f0d75ffbd788991cbf84f4937435e504e Mon Sep 17 00:00:00 2001 From: WeiHao Li Date: Sat, 6 Sep 2025 22:21:25 +0800 Subject: [PATCH 031/114] soc: rockchip: grf: Set pwm2/xin32k pad default to xin32k for rk3368 PWM2 and xin32k share the same pad, but some peripheral need the xin32k clock to run properly, such as tsadc. I have observed that this pad is used as xin32k by default on some existing board [1], so it maybe more appropriate to set it to xin32k by default. I also tested it on another rk3368 based board [2], without this adjust, tsadc does not work properly. [1] https://rockchip.fr/geekbox/Geekbox_V1.23.pdf [2] https://ieiao.github.io/wiki/embedded-dev/rockchip/rk3368 Signed-off-by: WeiHao Li Link: https://patch.msgid.link/20250906142125.7602-1-cn.liweihao@gmail.com Signed-off-by: Heiko Stuebner --- drivers/soc/rockchip/grf.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/drivers/soc/rockchip/grf.c b/drivers/soc/rockchip/grf.c index 344870da7675..c0c2ec1296f5 100644 --- a/drivers/soc/rockchip/grf.c +++ b/drivers/soc/rockchip/grf.c @@ -98,6 +98,17 @@ static const struct rockchip_grf_info rk3368_grf __initconst = { .num_values = ARRAY_SIZE(rk3368_defaults), }; +#define RK3368_PMUGRF_SOC_CON0 0x100 + +static const struct rockchip_grf_value rk3368_pmugrf_defaults[] __initconst = { + { "pwm2 select", RK3368_PMUGRF_SOC_CON0, FIELD_PREP_WM16_CONST(BIT(7), 0) }, +}; + +static const struct rockchip_grf_info rk3368_pmugrf __initconst = { + .values = rk3368_pmugrf_defaults, + .num_values = ARRAY_SIZE(rk3368_pmugrf_defaults), +}; + #define RK3399_GRF_SOC_CON7 0xe21c static const struct rockchip_grf_value rk3399_defaults[] __initconst = { @@ -175,6 +186,9 @@ static const struct of_device_id rockchip_grf_dt_match[] __initconst = { }, { .compatible = "rockchip,rk3368-grf", .data = (void *)&rk3368_grf, + }, { + .compatible = "rockchip,rk3368-pmugrf", + .data = (void *)&rk3368_pmugrf, }, { .compatible = "rockchip,rk3399-grf", .data = (void *)&rk3399_grf, From 8c79c80ff3366095fbb5b133e1fe032ccb70c3e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Draszik?= Date: Fri, 10 Oct 2025 07:29:01 +0100 Subject: [PATCH 032/114] dt-bindings: soc: samsung: exynos-sysreg: add power-domains MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On gs101 only, sysreg can be part of a power domain, so we need to allow the relevant property 'power-domains' for the relevant compatibles google,gs101-*-sysreg. Signed-off-by: André Draszik Reviewed-by: Krzysztof Kozlowski Link: https://patch.msgid.link/20251010-power-domains-dt-bindings-soc-samsung-exynos-sysreg-v2-1-552f5787a3f3@linaro.org Signed-off-by: Krzysztof Kozlowski --- .../bindings/soc/samsung/samsung,exynos-sysreg.yaml | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/Documentation/devicetree/bindings/soc/samsung/samsung,exynos-sysreg.yaml b/Documentation/devicetree/bindings/soc/samsung/samsung,exynos-sysreg.yaml index 518af7b926b7..e772a7482b02 100644 --- a/Documentation/devicetree/bindings/soc/samsung/samsung,exynos-sysreg.yaml +++ b/Documentation/devicetree/bindings/soc/samsung/samsung,exynos-sysreg.yaml @@ -77,6 +77,9 @@ properties: clocks: maxItems: 1 + power-domains: + maxItems: 1 + required: - compatible - reg @@ -106,6 +109,16 @@ allOf: properties: clocks: false + - if: + properties: + compatible: + not: + contains: + pattern: "^google,gs101-[^-]+-sysreg$" + then: + properties: + power-domains: false + additionalProperties: false examples: From af17f9f0bb46e553e2e8101e75e1a87e410b382e Mon Sep 17 00:00:00 2001 From: Peter Griffin Date: Mon, 13 Oct 2025 21:51:30 +0100 Subject: [PATCH 033/114] dt-bindings: soc: samsung: exynos-sysreg: add gs101 hsi0 and misc compatibles MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add dedicated compatibles for gs101 hsi0 and misc sysreg controllers to the documentation. Signed-off-by: Peter Griffin Reviewed-by: André Draszik Acked-by: Rob Herring (Arm) Link: https://patch.msgid.link/20251013-automatic-clocks-v1-1-72851ee00300@linaro.org Signed-off-by: Krzysztof Kozlowski --- .../bindings/soc/samsung/samsung,exynos-sysreg.yaml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Documentation/devicetree/bindings/soc/samsung/samsung,exynos-sysreg.yaml b/Documentation/devicetree/bindings/soc/samsung/samsung,exynos-sysreg.yaml index e772a7482b02..5e1e155510b3 100644 --- a/Documentation/devicetree/bindings/soc/samsung/samsung,exynos-sysreg.yaml +++ b/Documentation/devicetree/bindings/soc/samsung/samsung,exynos-sysreg.yaml @@ -15,7 +15,9 @@ properties: - items: - enum: - google,gs101-apm-sysreg + - google,gs101-hsi0-sysreg - google,gs101-hsi2-sysreg + - google,gs101-misc-sysreg - google,gs101-peric0-sysreg - google,gs101-peric1-sysreg - samsung,exynos2200-cmgp-sysreg @@ -90,7 +92,9 @@ allOf: compatible: contains: enum: + - google,gs101-hsi0-sysreg - google,gs101-hsi2-sysreg + - google,gs101-misc-sysreg - google,gs101-peric0-sysreg - google,gs101-peric1-sysreg - samsung,exynos850-cmgp-sysreg From 6773cb33e7a7191ae7ae490af279596c91a828cc Mon Sep 17 00:00:00 2001 From: Anjelique Melendez Date: Fri, 19 Sep 2025 10:50:25 -0700 Subject: [PATCH 034/114] soc: qcom: pmic_glink: Add support for SOCCP remoteproc channels System On Chip Control Processor (SOCCP) is a subsystem that can have battery management firmware running on it to support Type-C/PD and battery charging. SOCCP does not have multiple PDs and hence PDR is not supported. So, if the subsystem comes up/down, rpmsg driver would be probed or removed. Use that for notifying clients of pmic_glink for PDR events. Add support for battery management FW running on SOCCP by adding the "PMIC_RTR_SOCCP_APPS" channel name to the rpmsg_match list and updating notify_clients logic. Signed-off-by: Anjelique Melendez Link: https://lore.kernel.org/r/20250919175025.2988948-1-anjelique.melendez@oss.qualcomm.com Signed-off-by: Bjorn Andersson --- drivers/soc/qcom/pmic_glink.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/soc/qcom/pmic_glink.c b/drivers/soc/qcom/pmic_glink.c index c0a4be5df926..627f96ca322e 100644 --- a/drivers/soc/qcom/pmic_glink.c +++ b/drivers/soc/qcom/pmic_glink.c @@ -39,6 +39,7 @@ struct pmic_glink { struct mutex state_lock; unsigned int client_state; unsigned int pdr_state; + bool pdr_available; /* serializing clients list updates */ spinlock_t client_lock; @@ -246,9 +247,12 @@ static int pmic_glink_rpmsg_probe(struct rpmsg_device *rpdev) return dev_err_probe(&rpdev->dev, -ENODEV, "no pmic_glink device to attach to\n"); dev_set_drvdata(&rpdev->dev, pg); + pg->pdr_available = rpdev->id.driver_data; guard(mutex)(&pg->state_lock); pg->ept = rpdev->ept; + if (!pg->pdr_available) + pg->pdr_state = SERVREG_SERVICE_STATE_UP; pmic_glink_state_notify_clients(pg); return 0; @@ -265,11 +269,14 @@ static void pmic_glink_rpmsg_remove(struct rpmsg_device *rpdev) guard(mutex)(&pg->state_lock); pg->ept = NULL; + if (!pg->pdr_available) + pg->pdr_state = SERVREG_SERVICE_STATE_DOWN; pmic_glink_state_notify_clients(pg); } static const struct rpmsg_device_id pmic_glink_rpmsg_id_match[] = { - { "PMIC_RTR_ADSP_APPS" }, + {.name = "PMIC_RTR_ADSP_APPS", .driver_data = true }, + {.name = "PMIC_RTR_SOCCP_APPS", .driver_data = false }, {} }; From f5f1e5abb649d0a532ebc72f4196b4818585d20b Mon Sep 17 00:00:00 2001 From: Jingyi Wang Date: Wed, 24 Sep 2025 16:24:54 -0700 Subject: [PATCH 035/114] dt-bindings: cache: qcom,llcc: Document the Kaanapali LLCC Document the Last Level Cache Controller on Kaanapali platform. Signed-off-by: Jingyi Wang Reviewed-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20250924-knp-llcc-v1-1-ae6a016e5138@oss.qualcomm.com Signed-off-by: Bjorn Andersson --- Documentation/devicetree/bindings/cache/qcom,llcc.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Documentation/devicetree/bindings/cache/qcom,llcc.yaml b/Documentation/devicetree/bindings/cache/qcom,llcc.yaml index 37e3ebd55487..a620a2ff5c56 100644 --- a/Documentation/devicetree/bindings/cache/qcom,llcc.yaml +++ b/Documentation/devicetree/bindings/cache/qcom,llcc.yaml @@ -21,6 +21,7 @@ properties: compatible: enum: - qcom,ipq5424-llcc + - qcom,kaanapali-llcc - qcom,qcs615-llcc - qcom,qcs8300-llcc - qcom,qdu1000-llcc @@ -272,6 +273,7 @@ allOf: compatible: contains: enum: + - qcom,kaanapali-llcc - qcom,sm8450-llcc - qcom,sm8550-llcc - qcom,sm8650-llcc From c88b6ee3ba3c7bf6386ea0e6de8111acc3d832bc Mon Sep 17 00:00:00 2001 From: Jingyi Wang Date: Wed, 24 Sep 2025 16:24:55 -0700 Subject: [PATCH 036/114] soc: qcom: llcc-qcom: Add support for Kaanapali Add system cache table and configs for Kaanapali SoC. Signed-off-by: Jingyi Wang Reviewed-by: Konrad Dybcio Link: https://lore.kernel.org/r/20250924-knp-llcc-v1-2-ae6a016e5138@oss.qualcomm.com Signed-off-by: Bjorn Andersson --- drivers/soc/qcom/llcc-qcom.c | 373 +++++++++++++++++++++++++++++ include/linux/soc/qcom/llcc-qcom.h | 7 + 2 files changed, 380 insertions(+) diff --git a/drivers/soc/qcom/llcc-qcom.c b/drivers/soc/qcom/llcc-qcom.c index 857ead56b37d..13e174267294 100644 --- a/drivers/soc/qcom/llcc-qcom.c +++ b/drivers/soc/qcom/llcc-qcom.c @@ -214,6 +214,364 @@ static const struct llcc_slice_config ipq5424_data[] = { }, }; +static const struct llcc_slice_config kaanapali_data[] = { + { + .usecase_id = LLCC_CPUSS, + .slice_id = 1, + .max_cap = 5120, + .priority = 1, + .bonus_ways = 0xffffffff, + .activate_on_init = true, + .write_scid_en = true, + .stale_en = true, + .mru_uncap_en = true, + .vict_prio = true, + }, { + .usecase_id = LLCC_VIDSC0, + .slice_id = 2, + .max_cap = 512, + .priority = 4, + .fixed_size = true, + .bonus_ways = 0xffffffff, + .mru_uncap_en = true, + .vict_prio = true, + }, { + .usecase_id = LLCC_AUDIO, + .slice_id = 35, + .max_cap = 512, + .priority = 1, + .fixed_size = true, + .bonus_ways = 0xffffffff, + .mru_uncap_en = true, + .vict_prio = true, + }, { + .usecase_id = LLCC_MDMHPGRW, + .slice_id = 25, + .max_cap = 1024, + .priority = 5, + .bonus_ways = 0xffffffff, + .mru_uncap_en = true, + .vict_prio = true, + }, { + .usecase_id = LLCC_CMPT, + .slice_id = 34, + .max_cap = 4096, + .priority = 1, + .fixed_size = true, + .bonus_ways = 0xffffffff, + .mru_uncap_en = true, + .vict_prio = true, + }, { + .usecase_id = LLCC_GPUHTW, + .slice_id = 11, + .max_cap = 512, + .priority = 1, + .fixed_size = true, + .bonus_ways = 0xffffffff, + .mru_uncap_en = true, + .vict_prio = true, + }, { + .usecase_id = LLCC_GPU, + .slice_id = 9, + .max_cap = 5632, + .priority = 1, + .fixed_size = true, + .bonus_ways = 0xffffffff, + .write_scid_cacheable_en = true, + .mru_uncap_en = true, + .vict_prio = true, + }, { + .usecase_id = LLCC_MMUHWT, + .slice_id = 18, + .max_cap = 768, + .priority = 1, + .fixed_size = true, + .bonus_ways = 0xffffffff, + .activate_on_init = true, + .mru_uncap_en = true, + .vict_prio = true, + }, { + .usecase_id = LLCC_DISP, + .slice_id = 16, + .max_cap = 7168, + .priority = 1, + .fixed_size = true, + .bonus_ways = 0xffffffff, + .cache_mode = 2, + .stale_en = true, + .mru_uncap_en = true, + .vict_prio = true, + }, { + .usecase_id = LLCC_MDMHPFX, + .slice_id = 24, + .max_cap = 1024, + .priority = 5, + .fixed_size = true, + .bonus_ways = 0xffffffff, + .mru_uncap_en = true, + .vict_prio = true, + }, { + .usecase_id = LLCC_MDMPNG, + .slice_id = 27, + .max_cap = 256, + .priority = 5, + .bonus_ways = 0xfffff, + .mru_uncap_en = true, + .vict_prio = true, + }, { + .usecase_id = LLCC_CVP, + .slice_id = 8, + .max_cap = 800, + .priority = 5, + .fixed_size = true, + .bonus_ways = 0xffffffff, + .mru_uncap_en = true, + .ovcap_en = true, + .vict_prio = true, + .parent_slice_id = 33, + }, { + .usecase_id = LLCC_MODPE, + .slice_id = 29, + .max_cap = 256, + .priority = 1, + .fixed_size = true, + .bonus_ways = 0xf0000000, + .mru_uncap_en = true, + .alloc_oneway_en = true, + .vict_prio = true, + }, { + .usecase_id = LLCC_WRCACHE, + .slice_id = 31, + .max_cap = 512, + .priority = 1, + .fixed_size = true, + .bonus_ways = 0xffffffff, + .activate_on_init = true, + .mru_uncap_en = true, + .vict_prio = true, + }, { + .usecase_id = LLCC_CVPFW, + .slice_id = 19, + .max_cap = 512, + .priority = 5, + .fixed_size = true, + .bonus_ways = 0xffffffff, + .mru_uncap_en = true, + .vict_prio = true, + .parent_slice_id = 33, + }, { + .usecase_id = LLCC_CPUMTE, + .slice_id = 7, + .max_cap = 256, + .priority = 1, + .fixed_size = true, + .bonus_ways = 0xffffffff, + .mru_uncap_en = true, + .vict_prio = true, + }, { + .usecase_id = LLCC_CMPTHCP, + .slice_id = 15, + .max_cap = 256, + .priority = 4, + .fixed_size = true, + .bonus_ways = 0xffffffff, + .mru_uncap_en = true, + .vict_prio = true, + }, { + .usecase_id = LLCC_LCPDARE, + .slice_id = 30, + .max_cap = 128, + .priority = 5, + .fixed_size = true, + .bonus_ways = 0xffffffff, + .activate_on_init = true, + .mru_uncap_en = true, + .alloc_oneway_en = true, + .vict_prio = true, + }, { + .usecase_id = LLCC_AENPU, + .slice_id = 3, + .max_cap = 3072, + .priority = 1, + .fixed_size = true, + .bonus_ways = 0xffffffff, + .cache_mode = 2, + .mru_uncap_en = true, + .vict_prio = true, + }, { + .usecase_id = LLCC_ISLAND1, + .slice_id = 12, + .max_cap = 7936, + .priority = 7, + .fixed_size = true, + .bonus_ways = 0x7fffffff, + .mru_uncap_en = true, + .vict_prio = true, + }, { + .usecase_id = LLCC_DISP_WB, + .slice_id = 23, + .max_cap = 512, + .priority = 4, + .fixed_size = true, + .bonus_ways = 0xffffffff, + .mru_uncap_en = true, + .vict_prio = true, + }, { + .usecase_id = LLCC_VIDVSP, + .slice_id = 4, + .max_cap = 256, + .priority = 4, + .fixed_size = true, + .bonus_ways = 0xffffffff, + .mru_uncap_en = true, + .vict_prio = true, + }, { + .usecase_id = LLCC_VIDDEC, + .slice_id = 5, + .max_cap = 512, + .priority = 4, + .fixed_size = true, + .bonus_ways = 0xffffffff, + .cache_mode = 2, + .mru_uncap_en = true, + .ovcap_en = true, + .vict_prio = true, + .parent_slice_id = 33, + }, { + .usecase_id = LLCC_CAMOFE, + .slice_id = 33, + .max_cap = 6144, + .priority = 4, + .fixed_size = true, + .bonus_ways = 0xffffffff, + .stale_en = true, + .mru_uncap_en = true, + .ovcap_en = true, + .vict_prio = true, + .parent_slice_id = 33, + }, { + .usecase_id = LLCC_CAMRTIP, + .slice_id = 13, + .max_cap = 6144, + .priority = 4, + .fixed_size = true, + .bonus_ways = 0xffffffff, + .stale_en = true, + .mru_uncap_en = true, + .ovcap_en = true, + .vict_prio = true, + .parent_slice_id = 33, + }, { + .usecase_id = LLCC_CAMRTRF, + .slice_id = 10, + .max_cap = 3584, + .priority = 3, + .fixed_size = true, + .bonus_ways = 0xffffffff, + .stale_en = true, + .mru_uncap_en = true, + .ovcap_en = true, + .vict_prio = true, + .parent_slice_id = 33, + }, { + .usecase_id = LLCC_CAMSRTRF, + .slice_id = 21, + .max_cap = 6144, + .priority = 1, + .fixed_size = true, + .bonus_ways = 0xffffffff, + .stale_en = true, + .mru_uncap_en = true, + .ovcap_en = true, + .vict_prio = true, + .parent_slice_id = 33, + }, { + .usecase_id = LLCC_VIDEO_APV, + .slice_id = 6, + .max_cap = 768, + .priority = 4, + .fixed_size = true, + .bonus_ways = 0xffffffff, + .mru_uncap_en = true, + .vict_prio = true, + }, { + .usecase_id = LLCC_COMPUTE1, + .slice_id = 22, + .max_cap = 4096, + .priority = 1, + .fixed_size = true, + .bonus_ways = 0xffffffff, + .mru_uncap_en = true, + .vict_prio = true, + }, { + .usecase_id = LLCC_CPUSS_OPP, + .slice_id = 32, + .max_cap = 0, + .priority = 0, + .fixed_size = true, + .bonus_ways = 0, + .activate_on_init = true, + .write_scid_en = true, + .mru_uncap_en = true, + .vict_prio = true, + }, { + .usecase_id = LLCC_CPUSSMPAM, + .slice_id = 17, + .max_cap = 2048, + .priority = 1, + .fixed_size = true, + .bonus_ways = 0xffffffff, + .activate_on_init = true, + .write_scid_en = true, + .stale_en = true, + .mru_uncap_en = true, + .vict_prio = true, + }, { + .usecase_id = LLCC_CAM_IPE_STROV, + .slice_id = 14, + .max_cap = 400, + .priority = 5, + .fixed_size = true, + .bonus_ways = 0xffffffff, + .mru_uncap_en = true, + .ovcap_en = true, + .vict_prio = true, + .parent_slice_id = 33, + }, { + .usecase_id = LLCC_CAM_OFE_STROV, + .slice_id = 20, + .max_cap = 400, + .priority = 5, + .fixed_size = true, + .bonus_ways = 0xffffffff, + .mru_uncap_en = true, + .ovcap_en = true, + .vict_prio = true, + .parent_slice_id = 33, + }, { + .usecase_id = LLCC_CPUSS_HEU, + .slice_id = 28, + .max_cap = 0, + .priority = 0, + .fixed_size = true, + .bonus_ways = 0, + .mru_uncap_en = true, + .ovcap_en = true, + .vict_prio = true, + }, { + .usecase_id = LLCC_MDM_PNG_FIXED, + .slice_id = 26, + .max_cap = 256, + .priority = 5, + .fixed_size = true, + .bonus_ways = 0xff000000, + .activate_on_init = true, + .write_scid_en = true, + .mru_uncap_en = true, + .vict_prio = true, + }, +}; + static const struct llcc_slice_config sa8775p_data[] = { { .usecase_id = LLCC_CPUSS, @@ -3505,6 +3863,15 @@ static const u32 llcc_v6_reg_offset[] = { [LLCC_TRP_WRS_CACHEABLE_EN] = 0x00042088, }; +static const struct qcom_llcc_config kaanapali_cfg[] = { + { + .sct_data = kaanapali_data, + .size = ARRAY_SIZE(kaanapali_data), + .reg_offset = llcc_v6_reg_offset, + .edac_reg_offset = &llcc_v6_edac_reg_offset, + }, +}; + static const struct qcom_llcc_config qcs615_cfg[] = { { .sct_data = qcs615_data, @@ -3731,6 +4098,11 @@ static const struct qcom_llcc_config x1e80100_cfg[] = { }, }; +static const struct qcom_sct_config kaanapali_cfgs = { + .llcc_config = kaanapali_cfg, + .num_config = ARRAY_SIZE(kaanapali_cfg), +}; + static const struct qcom_sct_config qcs615_cfgs = { .llcc_config = qcs615_cfg, .num_config = ARRAY_SIZE(qcs615_cfg), @@ -4570,6 +4942,7 @@ static int qcom_llcc_probe(struct platform_device *pdev) static const struct of_device_id qcom_llcc_of_match[] = { { .compatible = "qcom,ipq5424-llcc", .data = &ipq5424_cfgs}, + { .compatible = "qcom,kaanapali-llcc", .data = &kaanapali_cfgs}, { .compatible = "qcom,qcs615-llcc", .data = &qcs615_cfgs}, { .compatible = "qcom,qcs8300-llcc", .data = &qcs8300_cfgs}, { .compatible = "qcom,qdu1000-llcc", .data = &qdu1000_cfgs}, diff --git a/include/linux/soc/qcom/llcc-qcom.h b/include/linux/soc/qcom/llcc-qcom.h index 7a69210a250c..0287f9182c4d 100644 --- a/include/linux/soc/qcom/llcc-qcom.h +++ b/include/linux/soc/qcom/llcc-qcom.h @@ -74,7 +74,14 @@ #define LLCC_CAMSRTIP 73 #define LLCC_CAMRTRF 74 #define LLCC_CAMSRTRF 75 +#define LLCC_VIDEO_APV 83 +#define LLCC_COMPUTE1 87 +#define LLCC_CPUSS_OPP 88 #define LLCC_CPUSSMPAM 89 +#define LLCC_CAM_IPE_STROV 92 +#define LLCC_CAM_OFE_STROV 93 +#define LLCC_CPUSS_HEU 94 +#define LLCC_MDM_PNG_FIXED 100 /** * struct llcc_slice_desc - Cache slice descriptor From b5c16ea57b030b8e9428ec726e26219dfe05c3d9 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Fri, 26 Sep 2025 16:35:10 +0200 Subject: [PATCH 037/114] soc: qcom: ocmem: fix device leak on lookup Make sure to drop the reference taken to the ocmem platform device when looking up its driver data. Note that holding a reference to a device does not prevent its driver data from going away so there is no point in keeping the reference. Also note that commit 0ff027027e05 ("soc: qcom: ocmem: Fix missing put_device() call in of_get_ocmem") fixed the leak in a lookup error path, but the reference is still leaking on success. Fixes: 88c1e9404f1d ("soc: qcom: add OCMEM driver") Cc: stable@vger.kernel.org # 5.5: 0ff027027e05 Cc: Brian Masney Cc: Miaoqian Lin Signed-off-by: Johan Hovold Reviewed-by: Brian Masney Link: https://lore.kernel.org/r/20250926143511.6715-2-johan@kernel.org Signed-off-by: Bjorn Andersson --- drivers/soc/qcom/ocmem.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/soc/qcom/ocmem.c b/drivers/soc/qcom/ocmem.c index 9c3bd37b6579..71130a2f62e9 100644 --- a/drivers/soc/qcom/ocmem.c +++ b/drivers/soc/qcom/ocmem.c @@ -202,9 +202,9 @@ struct ocmem *of_get_ocmem(struct device *dev) } ocmem = platform_get_drvdata(pdev); + put_device(&pdev->dev); if (!ocmem) { dev_err(dev, "Cannot get ocmem\n"); - put_device(&pdev->dev); return ERR_PTR(-ENODEV); } return ocmem; From 94124bf253d24b13e89c45618a168d5a1d8a61e7 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Fri, 26 Sep 2025 16:35:11 +0200 Subject: [PATCH 038/114] soc: qcom: pbs: fix device leak on lookup Make sure to drop the reference taken to the pbs platform device when looking up its driver data. Note that holding a reference to a device does not prevent its driver data from going away so there is no point in keeping the reference. Fixes: 5b2dd77be1d8 ("soc: qcom: add QCOM PBS driver") Cc: stable@vger.kernel.org # 6.9 Cc: Anjelique Melendez Signed-off-by: Johan Hovold Link: https://lore.kernel.org/r/20250926143511.6715-3-johan@kernel.org Signed-off-by: Bjorn Andersson --- drivers/soc/qcom/qcom-pbs.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/soc/qcom/qcom-pbs.c b/drivers/soc/qcom/qcom-pbs.c index 1cc5d045f9dd..06b4a596e275 100644 --- a/drivers/soc/qcom/qcom-pbs.c +++ b/drivers/soc/qcom/qcom-pbs.c @@ -173,6 +173,8 @@ struct pbs_dev *get_pbs_client_device(struct device *dev) return ERR_PTR(-EINVAL); } + platform_device_put(pdev); + return pbs; } EXPORT_SYMBOL_GPL(get_pbs_client_device); From abac241e1d5da20332160b29b23f357016abe3e1 Mon Sep 17 00:00:00 2001 From: Kathiravan Thirumoorthy Date: Mon, 29 Sep 2025 19:47:07 +0530 Subject: [PATCH 039/114] soc: qcom: socinfo: arrange the socinfo_image_names array in alphabetical order The socinfo_image_names array is currently neither arranged alphabetically nor by image index values, making it harder to maintain. Reorder the array alphabetically to improve readability and simplify the addition of new entries. Signed-off-by: Kathiravan Thirumoorthy Reviewed-by: Dmitry Baryshkov Link: https://lore.kernel.org/r/20250929-image_crm-v1-1-e06530c42357@oss.qualcomm.com Signed-off-by: Bjorn Andersson --- drivers/soc/qcom/socinfo.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/soc/qcom/socinfo.c b/drivers/soc/qcom/socinfo.c index 963772f45489..8d25da4c7018 100644 --- a/drivers/soc/qcom/socinfo.c +++ b/drivers/soc/qcom/socinfo.c @@ -60,17 +60,17 @@ static const char *const socinfo_image_names[] = { [SMEM_IMAGE_TABLE_APPSBL_INDEX] = "appsbl", [SMEM_IMAGE_TABLE_APPS_INDEX] = "apps", [SMEM_IMAGE_TABLE_BOOT_INDEX] = "boot", + [SMEM_IMAGE_TABLE_CDSP1_INDEX] = "cdsp1", + [SMEM_IMAGE_TABLE_CDSP_INDEX] = "cdsp", [SMEM_IMAGE_TABLE_CNSS_INDEX] = "cnss", + [SMEM_IMAGE_TABLE_DSPS_INDEX] = "dsps", + [SMEM_IMAGE_TABLE_GPDSP1_INDEX] = "gpdsp1", + [SMEM_IMAGE_TABLE_GPDSP_INDEX] = "gpdsp", [SMEM_IMAGE_TABLE_MPSS_INDEX] = "mpss", [SMEM_IMAGE_TABLE_RPM_INDEX] = "rpm", + [SMEM_IMAGE_TABLE_TME_INDEX] = "tme", [SMEM_IMAGE_TABLE_TZ_INDEX] = "tz", [SMEM_IMAGE_TABLE_VIDEO_INDEX] = "video", - [SMEM_IMAGE_TABLE_DSPS_INDEX] = "dsps", - [SMEM_IMAGE_TABLE_CDSP_INDEX] = "cdsp", - [SMEM_IMAGE_TABLE_CDSP1_INDEX] = "cdsp1", - [SMEM_IMAGE_TABLE_GPDSP_INDEX] = "gpdsp", - [SMEM_IMAGE_TABLE_GPDSP1_INDEX] = "gpdsp1", - [SMEM_IMAGE_TABLE_TME_INDEX] = "tme", }; static const char *const pmic_models[] = { From dcbce2c23e5edcba2ac538e7a53d0e3d1a21f975 Mon Sep 17 00:00:00 2001 From: Kathiravan Thirumoorthy Date: Mon, 29 Sep 2025 19:47:08 +0530 Subject: [PATCH 040/114] soc: qcom: socinfo: add the missing entries to the smem image table Add the missing entries to the SMEM image table to ensure completeness, rather than adding support for one image at a time. Signed-off-by: Kathiravan Thirumoorthy Reviewed-by: Dmitry Baryshkov Link: https://lore.kernel.org/r/20250929-image_crm-v1-2-e06530c42357@oss.qualcomm.com Signed-off-by: Bjorn Andersson --- drivers/soc/qcom/socinfo.c | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/drivers/soc/qcom/socinfo.c b/drivers/soc/qcom/socinfo.c index 8d25da4c7018..5627fb6ffbdb 100644 --- a/drivers/soc/qcom/socinfo.c +++ b/drivers/soc/qcom/socinfo.c @@ -37,7 +37,13 @@ */ #define SMEM_IMAGE_TABLE_BOOT_INDEX 0 #define SMEM_IMAGE_TABLE_TZ_INDEX 1 +#define SMEM_IMAGE_TABLE_TZSECAPP_INDEX 2 #define SMEM_IMAGE_TABLE_RPM_INDEX 3 +#define SMEM_IMAGE_TABLE_SDI_INDEX 4 +#define SMEM_IMAGE_TABLE_HYP_INDEX 5 +#define SMEM_IMAGE_TABLE_ADSP1_INDEX 6 +#define SMEM_IMAGE_TABLE_ADSP2_INDEX 7 +#define SMEM_IMAGE_TABLE_CDSP2_INDEX 8 #define SMEM_IMAGE_TABLE_APPSBL_INDEX 9 #define SMEM_IMAGE_TABLE_APPS_INDEX 10 #define SMEM_IMAGE_TABLE_MPSS_INDEX 11 @@ -46,31 +52,59 @@ #define SMEM_IMAGE_TABLE_VIDEO_INDEX 14 #define SMEM_IMAGE_TABLE_DSPS_INDEX 15 #define SMEM_IMAGE_TABLE_CDSP_INDEX 16 +#define SMEM_IMAGE_TABLE_NPU_INDEX 17 +#define SMEM_IMAGE_TABLE_WPSS_INDEX 18 #define SMEM_IMAGE_TABLE_CDSP1_INDEX 19 #define SMEM_IMAGE_TABLE_GPDSP_INDEX 20 #define SMEM_IMAGE_TABLE_GPDSP1_INDEX 21 +#define SMEM_IMAGE_TABLE_SENSORPD_INDEX 22 +#define SMEM_IMAGE_TABLE_AUDIOPD_INDEX 23 +#define SMEM_IMAGE_TABLE_OEMPD_INDEX 24 +#define SMEM_IMAGE_TABLE_CHARGERPD_INDEX 25 +#define SMEM_IMAGE_TABLE_OISPD_INDEX 26 +#define SMEM_IMAGE_TABLE_SOCCP_INDEX 27 #define SMEM_IMAGE_TABLE_TME_INDEX 28 +#define SMEM_IMAGE_TABLE_GEARVM_INDEX 29 +#define SMEM_IMAGE_TABLE_UEFI_INDEX 30 +#define SMEM_IMAGE_TABLE_CDSP3_INDEX 31 #define SMEM_IMAGE_VERSION_TABLE 469 /* * SMEM Image table names */ static const char *const socinfo_image_names[] = { + [SMEM_IMAGE_TABLE_ADSP1_INDEX] = "adsp1", + [SMEM_IMAGE_TABLE_ADSP2_INDEX] = "adsp2", [SMEM_IMAGE_TABLE_ADSP_INDEX] = "adsp", [SMEM_IMAGE_TABLE_APPSBL_INDEX] = "appsbl", [SMEM_IMAGE_TABLE_APPS_INDEX] = "apps", + [SMEM_IMAGE_TABLE_AUDIOPD_INDEX] = "audiopd", [SMEM_IMAGE_TABLE_BOOT_INDEX] = "boot", [SMEM_IMAGE_TABLE_CDSP1_INDEX] = "cdsp1", + [SMEM_IMAGE_TABLE_CDSP2_INDEX] = "cdsp2", + [SMEM_IMAGE_TABLE_CDSP3_INDEX] = "cdsp3", [SMEM_IMAGE_TABLE_CDSP_INDEX] = "cdsp", + [SMEM_IMAGE_TABLE_CHARGERPD_INDEX] = "chargerpd", [SMEM_IMAGE_TABLE_CNSS_INDEX] = "cnss", [SMEM_IMAGE_TABLE_DSPS_INDEX] = "dsps", + [SMEM_IMAGE_TABLE_GEARVM_INDEX] = "gearvm", [SMEM_IMAGE_TABLE_GPDSP1_INDEX] = "gpdsp1", [SMEM_IMAGE_TABLE_GPDSP_INDEX] = "gpdsp", + [SMEM_IMAGE_TABLE_HYP_INDEX] = "hyp", [SMEM_IMAGE_TABLE_MPSS_INDEX] = "mpss", + [SMEM_IMAGE_TABLE_NPU_INDEX] = "npu", + [SMEM_IMAGE_TABLE_OEMPD_INDEX] = "oempd", + [SMEM_IMAGE_TABLE_OISPD_INDEX] = "oispd", [SMEM_IMAGE_TABLE_RPM_INDEX] = "rpm", + [SMEM_IMAGE_TABLE_SDI_INDEX] = "sdi", + [SMEM_IMAGE_TABLE_SENSORPD_INDEX] = "sensorpd", + [SMEM_IMAGE_TABLE_SOCCP_INDEX] = "soccp", [SMEM_IMAGE_TABLE_TME_INDEX] = "tme", [SMEM_IMAGE_TABLE_TZ_INDEX] = "tz", + [SMEM_IMAGE_TABLE_TZSECAPP_INDEX] = "tzsecapp", + [SMEM_IMAGE_TABLE_UEFI_INDEX] = "uefi", [SMEM_IMAGE_TABLE_VIDEO_INDEX] = "video", + [SMEM_IMAGE_TABLE_WPSS_INDEX] = "wpss", }; static const char *const pmic_models[] = { From 2286e18e3937c69cc103308a8c1d4898d8a7b04f Mon Sep 17 00:00:00 2001 From: Haotian Zhang Date: Tue, 21 Oct 2025 00:02:15 +0800 Subject: [PATCH 041/114] soc: qcom: gsbi: fix double disable caused by devm In the commit referenced by the Fixes tag, devm_clk_get_enabled() was introduced to replace devm_clk_get() and clk_prepare_enable(). While the clk_disable_unprepare() call in the error path was correctly removed, the one in the remove function was overlooked, leading to a double disable issue. Remove the redundant clk_disable_unprepare() call from gsbi_remove() to fix this issue. Since all resources are now managed by devres and will be automatically released, the remove function serves no purpose and can be deleted entirely. Fixes: 489d7a8cc286 ("soc: qcom: use devm_clk_get_enabled() in gsbi_probe()") Signed-off-by: Haotian Zhang Reviewed-by: Konrad Dybcio Link: https://lore.kernel.org/stable/20251020160215.523-1-vulab%40iscas.ac.cn Link: https://lore.kernel.org/r/20251020160215.523-1-vulab@iscas.ac.cn Signed-off-by: Bjorn Andersson --- drivers/soc/qcom/qcom_gsbi.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/drivers/soc/qcom/qcom_gsbi.c b/drivers/soc/qcom/qcom_gsbi.c index 8f1158e0c631..a25d1de592f0 100644 --- a/drivers/soc/qcom/qcom_gsbi.c +++ b/drivers/soc/qcom/qcom_gsbi.c @@ -212,13 +212,6 @@ static int gsbi_probe(struct platform_device *pdev) return of_platform_populate(node, NULL, NULL, &pdev->dev); } -static void gsbi_remove(struct platform_device *pdev) -{ - struct gsbi_info *gsbi = platform_get_drvdata(pdev); - - clk_disable_unprepare(gsbi->hclk); -} - static const struct of_device_id gsbi_dt_match[] = { { .compatible = "qcom,gsbi-v1.0.0", }, { }, @@ -232,7 +225,6 @@ static struct platform_driver gsbi_driver = { .of_match_table = gsbi_dt_match, }, .probe = gsbi_probe, - .remove = gsbi_remove, }; module_platform_driver(gsbi_driver); From 42ec0bc61f052beb0d9a6a889fe746591de74508 Mon Sep 17 00:00:00 2001 From: Biju Das Date: Sun, 19 Oct 2025 19:09:38 +0100 Subject: [PATCH 042/114] memory: renesas-rpc-if: Add suspend/resume support On RZ/G3E using PSCI, s2ram powers down the SoC. Add suspend/resume callbacks to control spi/spix2 clocks. Signed-off-by: Biju Das Link: https://patch.msgid.link/20251019180940.157088-1-biju.das.jz@bp.renesas.com Signed-off-by: Krzysztof Kozlowski --- drivers/memory/renesas-rpc-if.c | 56 ++++++++++++++++++++++++++------- 1 file changed, 44 insertions(+), 12 deletions(-) diff --git a/drivers/memory/renesas-rpc-if.c b/drivers/memory/renesas-rpc-if.c index 4a417b693080..58ccc1c02e90 100644 --- a/drivers/memory/renesas-rpc-if.c +++ b/drivers/memory/renesas-rpc-if.c @@ -67,6 +67,8 @@ struct rpcif_priv { void __iomem *dirmap; struct regmap *regmap; struct reset_control *rstc; + struct clk *spi_clk; + struct clk *spix2_clk; struct platform_device *vdev; size_t size; const struct rpcif_info *info; @@ -1024,19 +1026,15 @@ static int rpcif_probe(struct platform_device *pdev) * flash write failure. So, enable these clocks during probe() and * disable it in remove(). */ - if (rpc->info->type == XSPI_RZ_G3E) { - struct clk *spi_clk; + rpc->spix2_clk = devm_clk_get_optional_enabled(dev, "spix2"); + if (IS_ERR(rpc->spix2_clk)) + return dev_err_probe(dev, PTR_ERR(rpc->spix2_clk), + "cannot get enabled spix2 clk\n"); - spi_clk = devm_clk_get_enabled(dev, "spix2"); - if (IS_ERR(spi_clk)) - return dev_err_probe(dev, PTR_ERR(spi_clk), - "cannot get enabled spix2 clk\n"); - - spi_clk = devm_clk_get_enabled(dev, "spi"); - if (IS_ERR(spi_clk)) - return dev_err_probe(dev, PTR_ERR(spi_clk), - "cannot get enabled spi clk\n"); - } + rpc->spi_clk = devm_clk_get_optional_enabled(dev, "spi"); + if (IS_ERR(rpc->spi_clk)) + return dev_err_probe(dev, PTR_ERR(rpc->spi_clk), + "cannot get enabled spi clk\n"); vdev = platform_device_alloc(name, pdev->id); if (!vdev) @@ -1063,6 +1061,37 @@ static void rpcif_remove(struct platform_device *pdev) platform_device_unregister(rpc->vdev); } +static int rpcif_suspend(struct device *dev) +{ + struct rpcif_priv *rpc = dev_get_drvdata(dev); + + clk_disable_unprepare(rpc->spi_clk); + clk_disable_unprepare(rpc->spix2_clk); + + return 0; +} + +static int rpcif_resume(struct device *dev) +{ + struct rpcif_priv *rpc = dev_get_drvdata(dev); + int ret; + + ret = clk_prepare_enable(rpc->spix2_clk); + if (ret) { + dev_err(dev, "failed to enable spix2 clock: %pe\n", ERR_PTR(ret)); + return ret; + } + + ret = clk_prepare_enable(rpc->spi_clk); + if (ret) { + clk_disable_unprepare(rpc->spix2_clk); + dev_err(dev, "failed to enable spi clock: %pe\n", ERR_PTR(ret)); + return ret; + } + + return 0; +} + static const struct rpcif_impl rpcif_impl = { .hw_init = rpcif_hw_init_impl, .prepare = rpcif_prepare_impl, @@ -1125,12 +1154,15 @@ static const struct of_device_id rpcif_of_match[] = { }; MODULE_DEVICE_TABLE(of, rpcif_of_match); +static DEFINE_SIMPLE_DEV_PM_OPS(rpcif_pm_ops, rpcif_suspend, rpcif_resume); + static struct platform_driver rpcif_driver = { .probe = rpcif_probe, .remove = rpcif_remove, .driver = { .name = "rpc-if", .of_match_table = rpcif_of_match, + .pm = pm_sleep_ptr(&rpcif_pm_ops), }, }; module_platform_driver(rpcif_driver); From 4765d59fcf8679372286bc899628c3721dafe456 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Fri, 17 Oct 2025 13:42:34 +0200 Subject: [PATCH 043/114] soc: renesas: rcar-rst: Keep RESBAR2S in default state Unlike Gen2, Gen4 has bit 15 of WDTRSTCR register also used. Keep it in the default state for the V3U firmware workaround. Signed-off-by: Wolfram Sang Reviewed-by: Geert Uytterhoeven Tested-by: Geert Uytterhoeven Link: https://patch.msgid.link/20251017114234.2968-2-wsa+renesas@sang-engineering.com Signed-off-by: Geert Uytterhoeven --- drivers/soc/renesas/rcar-rst.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/soc/renesas/rcar-rst.c b/drivers/soc/renesas/rcar-rst.c index 7ba02f3a4a4f..0541990901fc 100644 --- a/drivers/soc/renesas/rcar-rst.c +++ b/drivers/soc/renesas/rcar-rst.c @@ -12,6 +12,7 @@ #define WDTRSTCR_RESET 0xA55A0002 #define WDTRSTCR 0x0054 +#define GEN4_WDTRSTCR_RESET 0xA55A8002 #define GEN4_WDTRSTCR 0x0010 #define CR7BAR 0x0070 @@ -30,7 +31,7 @@ static int rcar_rst_enable_wdt_reset(void __iomem *base) static int rcar_rst_v3u_enable_wdt_reset(void __iomem *base) { - iowrite32(WDTRSTCR_RESET, base + GEN4_WDTRSTCR); + iowrite32(GEN4_WDTRSTCR_RESET, base + GEN4_WDTRSTCR); return 0; } From ee67247843a2b62d1473cfa4df300e69b5190ccf Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Fri, 17 Oct 2025 09:56:24 +0800 Subject: [PATCH 044/114] firmware: imx: scu-irq: fix OF node leak in imx_scu_enable_general_irq_channel() calls of_parse_phandle_with_args(), but does not release the OF node reference. Add a of_node_put() call to release the reference. Fixes: 851826c7566e ("firmware: imx: enable imx scu general irq function") Reviewed-by: Frank Li Signed-off-by: Peng Fan Signed-off-by: Shawn Guo --- drivers/firmware/imx/imx-scu-irq.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/firmware/imx/imx-scu-irq.c b/drivers/firmware/imx/imx-scu-irq.c index 6125cccc9ba7..f2b902e95b73 100644 --- a/drivers/firmware/imx/imx-scu-irq.c +++ b/drivers/firmware/imx/imx-scu-irq.c @@ -226,8 +226,10 @@ int imx_scu_enable_general_irq_channel(struct device *dev) INIT_WORK(&imx_sc_irq_work, imx_scu_irq_work_handler); if (!of_parse_phandle_with_args(dev->of_node, "mboxes", - "#mbox-cells", 0, &spec)) + "#mbox-cells", 0, &spec)) { i = of_alias_get_id(spec.np, "mu"); + of_node_put(spec.np); + } /* use mu1 as general mu irq channel if failed */ if (i < 0) From 62c740fb11ea7790f6bcd4f72c563f9ae2a42e9a Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Fri, 17 Oct 2025 09:56:25 +0800 Subject: [PATCH 045/114] firmware: imx: scu-irq: Free mailbox client on failure at imx_scu_enable_general_irq_channel() The IRQ mailbox is an optional channel and does not need to be kept until driver removal when an error occurs. Free the allocated memory in the error path. Add 'goto free_cl' when mbox_request_channel_byname() fails, to keep free at one place. Signed-off-by: Peng Fan Reviewed-by: Frank Li Signed-off-by: Shawn Guo --- drivers/firmware/imx/imx-scu-irq.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/firmware/imx/imx-scu-irq.c b/drivers/firmware/imx/imx-scu-irq.c index f2b902e95b73..d6fd04404e2a 100644 --- a/drivers/firmware/imx/imx-scu-irq.c +++ b/drivers/firmware/imx/imx-scu-irq.c @@ -219,8 +219,7 @@ int imx_scu_enable_general_irq_channel(struct device *dev) if (IS_ERR(ch)) { ret = PTR_ERR(ch); dev_err(dev, "failed to request mbox chan gip3, ret %d\n", ret); - devm_kfree(dev, cl); - return ret; + goto free_cl; } INIT_WORK(&imx_sc_irq_work, imx_scu_irq_work_handler); @@ -255,6 +254,8 @@ int imx_scu_enable_general_irq_channel(struct device *dev) free_ch: mbox_free_channel(ch); +free_cl: + devm_kfree(dev, cl); return ret; } From 81fb53feb66a3aefbf6fcab73bb8d06f5b0c54ad Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Fri, 17 Oct 2025 09:56:26 +0800 Subject: [PATCH 046/114] firmware: imx: scu-irq: Init workqueue before request mbox channel With mailbox channel requested, there is possibility that interrupts may come in, so need to make sure the workqueue is initialized before the queue is scheduled by mailbox rx callback. Reviewed-by: Frank Li Signed-off-by: Peng Fan Signed-off-by: Shawn Guo --- drivers/firmware/imx/imx-scu-irq.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/firmware/imx/imx-scu-irq.c b/drivers/firmware/imx/imx-scu-irq.c index d6fd04404e2a..2d7237188932 100644 --- a/drivers/firmware/imx/imx-scu-irq.c +++ b/drivers/firmware/imx/imx-scu-irq.c @@ -214,6 +214,8 @@ int imx_scu_enable_general_irq_channel(struct device *dev) cl->dev = dev; cl->rx_callback = imx_scu_irq_callback; + INIT_WORK(&imx_sc_irq_work, imx_scu_irq_work_handler); + /* SCU general IRQ uses general interrupt channel 3 */ ch = mbox_request_channel_byname(cl, "gip3"); if (IS_ERR(ch)) { @@ -222,8 +224,6 @@ int imx_scu_enable_general_irq_channel(struct device *dev) goto free_cl; } - INIT_WORK(&imx_sc_irq_work, imx_scu_irq_work_handler); - if (!of_parse_phandle_with_args(dev->of_node, "mboxes", "#mbox-cells", 0, &spec)) { i = of_alias_get_id(spec.np, "mu"); From ff3f9913bc0749364fbfd86ea62ba2d31c6136c8 Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Fri, 17 Oct 2025 09:56:27 +0800 Subject: [PATCH 047/114] firmware: imx: scu-irq: Set mu_resource_id before get handle mu_resource_id is referenced in imx_scu_irq_get_status() and imx_scu_irq_group_enable() which could be used by other modules, so need to set correct value before using imx_sc_irq_ipc_handle in SCU API call. Reviewed-by: Frank Li Signed-off-by: Peng Fan Signed-off-by: Shawn Guo --- drivers/firmware/imx/imx-scu-irq.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/drivers/firmware/imx/imx-scu-irq.c b/drivers/firmware/imx/imx-scu-irq.c index 2d7237188932..3dda42be4e6b 100644 --- a/drivers/firmware/imx/imx-scu-irq.c +++ b/drivers/firmware/imx/imx-scu-irq.c @@ -203,6 +203,18 @@ int imx_scu_enable_general_irq_channel(struct device *dev) struct mbox_chan *ch; int ret = 0, i = 0; + if (!of_parse_phandle_with_args(dev->of_node, "mboxes", + "#mbox-cells", 0, &spec)) { + i = of_alias_get_id(spec.np, "mu"); + of_node_put(spec.np); + } + + /* use mu1 as general mu irq channel if failed */ + if (i < 0) + i = 1; + + mu_resource_id = IMX_SC_R_MU_0A + i; + ret = imx_scu_get_handle(&imx_sc_irq_ipc_handle); if (ret) return ret; @@ -224,18 +236,6 @@ int imx_scu_enable_general_irq_channel(struct device *dev) goto free_cl; } - if (!of_parse_phandle_with_args(dev->of_node, "mboxes", - "#mbox-cells", 0, &spec)) { - i = of_alias_get_id(spec.np, "mu"); - of_node_put(spec.np); - } - - /* use mu1 as general mu irq channel if failed */ - if (i < 0) - i = 1; - - mu_resource_id = IMX_SC_R_MU_0A + i; - /* Create directory under /sysfs/firmware */ wakeup_obj = kobject_create_and_add("scu_wakeup_source", firmware_kobj); if (!wakeup_obj) { From ea2f83c6aa027d42249fa73e833213c0d919d1fd Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Fri, 17 Oct 2025 09:56:28 +0800 Subject: [PATCH 048/114] firmware: imx: scu-irq: Remove unused export of imx_scu_enable_general_irq_channel Since its introduction, this symbol has not been used by any loadable modules. It remains only referenced within imx-scu.c, which is always built together with imx-scu-irq.c As such, exporting imx_scu_enable_general_irq_channel is unnecessary, so remove the export. Reviewed-by: Frank Li Signed-off-by: Peng Fan Signed-off-by: Shawn Guo --- drivers/firmware/imx/imx-scu-irq.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/firmware/imx/imx-scu-irq.c b/drivers/firmware/imx/imx-scu-irq.c index 3dda42be4e6b..a68d38f89254 100644 --- a/drivers/firmware/imx/imx-scu-irq.c +++ b/drivers/firmware/imx/imx-scu-irq.c @@ -259,4 +259,3 @@ int imx_scu_enable_general_irq_channel(struct device *dev) return ret; } -EXPORT_SYMBOL(imx_scu_enable_general_irq_channel); From 27d408697f0ca09806e49ae5e5d3fceae7a671d4 Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Fri, 17 Oct 2025 09:56:29 +0800 Subject: [PATCH 049/114] firmware: imx: scu: Update error code IMX_SC_ERR_NOTFOUND should map with -ENOENT, not -EEXIST. -ENODEV makes more sense for IMX_SC_ERR_NOPOWER, and -ECOMM makes more sense for IMX_SC_ERR_IPC. Reviewed-by: Frank Li Signed-off-by: Peng Fan Signed-off-by: Shawn Guo --- drivers/firmware/imx/imx-scu.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/firmware/imx/imx-scu.c b/drivers/firmware/imx/imx-scu.c index 8c28e25ddc8a..6046156bc3c9 100644 --- a/drivers/firmware/imx/imx-scu.c +++ b/drivers/firmware/imx/imx-scu.c @@ -73,9 +73,9 @@ static int imx_sc_linux_errmap[IMX_SC_ERR_LAST] = { -EACCES, /* IMX_SC_ERR_NOACCESS */ -EACCES, /* IMX_SC_ERR_LOCKED */ -ERANGE, /* IMX_SC_ERR_UNAVAILABLE */ - -EEXIST, /* IMX_SC_ERR_NOTFOUND */ - -EPERM, /* IMX_SC_ERR_NOPOWER */ - -EPIPE, /* IMX_SC_ERR_IPC */ + -ENOENT, /* IMX_SC_ERR_NOTFOUND */ + -ENODEV, /* IMX_SC_ERR_NOPOWER */ + -ECOMM, /* IMX_SC_ERR_IPC */ -EBUSY, /* IMX_SC_ERR_BUSY */ -EIO, /* IMX_SC_ERR_FAIL */ }; From ff79af939d84791b1af49492431c1520f31e671b Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Fri, 17 Oct 2025 09:56:30 +0800 Subject: [PATCH 050/114] firmware: imx: scu: Suppress bind attrs The SCU driver is critical for system working properly, it should never be removed and binded again. So suppress the bind attrs Reviewed-by: Frank Li Signed-off-by: Peng Fan Signed-off-by: Shawn Guo --- drivers/firmware/imx/imx-scu.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/firmware/imx/imx-scu.c b/drivers/firmware/imx/imx-scu.c index 6046156bc3c9..630e3dba4db1 100644 --- a/drivers/firmware/imx/imx-scu.c +++ b/drivers/firmware/imx/imx-scu.c @@ -352,6 +352,7 @@ static struct platform_driver imx_scu_driver = { .driver = { .name = "imx-scu", .of_match_table = imx_scu_match, + .suppress_bind_attrs = true, }, .probe = imx_scu_probe, }; From 97a07dd2b559d149598cd49574ce50614752211a Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Fri, 17 Oct 2025 09:56:31 +0800 Subject: [PATCH 051/114] firmware: imx: scu: Use devm_mutex_init In normal case, there is no need to invoke mutex_destroy in error path, but it is useful when CONFIG_DEBUG_MUTEXES, so use devm_mutex_init(). Reviewed-by: Frank Li Signed-off-by: Peng Fan Signed-off-by: Shawn Guo --- drivers/firmware/imx/imx-scu.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/firmware/imx/imx-scu.c b/drivers/firmware/imx/imx-scu.c index 630e3dba4db1..67b267a7408a 100644 --- a/drivers/firmware/imx/imx-scu.c +++ b/drivers/firmware/imx/imx-scu.c @@ -324,7 +324,9 @@ static int imx_scu_probe(struct platform_device *pdev) } sc_ipc->dev = dev; - mutex_init(&sc_ipc->lock); + ret = devm_mutex_init(dev, &sc_ipc->lock); + if (ret) + return ret; init_completion(&sc_ipc->done); imx_sc_ipc_handle = sc_ipc; From 9b21c3bd24803e4ebab9f91bd812aa10576d8220 Mon Sep 17 00:00:00 2001 From: Abel Vesa Date: Tue, 14 Oct 2025 15:38:32 +0300 Subject: [PATCH 052/114] soc: qcom: ubwc: Add configuration Glymur platform Describe the Universal Bandwidth Compression (UBWC) configuration for the new Glymur platform. Signed-off-by: Abel Vesa Reviewed-by: Dmitry Baryshkov Link: https://lore.kernel.org/r/20251014-glymur-display-v2-7-ff935e2f88c5@linaro.org Signed-off-by: Bjorn Andersson --- drivers/soc/qcom/ubwc_config.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/drivers/soc/qcom/ubwc_config.c b/drivers/soc/qcom/ubwc_config.c index 15d373bff231..7cca2afb68e3 100644 --- a/drivers/soc/qcom/ubwc_config.c +++ b/drivers/soc/qcom/ubwc_config.c @@ -218,11 +218,23 @@ static const struct qcom_ubwc_cfg_data x1e80100_data = { .macrotile_mode = true, }; +static const struct qcom_ubwc_cfg_data glymur_data = { + .ubwc_enc_version = UBWC_5_0, + .ubwc_dec_version = UBWC_5_0, + .ubwc_swizzle = UBWC_SWIZZLE_ENABLE_LVL2 | + UBWC_SWIZZLE_ENABLE_LVL3, + .ubwc_bank_spread = true, + /* TODO: highest_bank_bit = 15 for LP_DDR4 */ + .highest_bank_bit = 16, + .macrotile_mode = true, +}; + static const struct of_device_id qcom_ubwc_configs[] __maybe_unused = { { .compatible = "qcom,apq8016", .data = &no_ubwc_data }, { .compatible = "qcom,apq8026", .data = &no_ubwc_data }, { .compatible = "qcom,apq8074", .data = &no_ubwc_data }, { .compatible = "qcom,apq8096", .data = &msm8998_data }, + { .compatible = "qcom,glymur", .data = &glymur_data}, { .compatible = "qcom,msm8226", .data = &no_ubwc_data }, { .compatible = "qcom,msm8916", .data = &no_ubwc_data }, { .compatible = "qcom,msm8917", .data = &no_ubwc_data }, From 457129aa3610f46bfa6f97725de731345d4aaef0 Mon Sep 17 00:00:00 2001 From: Jingyi Wang Date: Wed, 22 Oct 2025 21:57:36 -0700 Subject: [PATCH 053/114] dt-bindings: arm: qcom,ids: Add SoC ID for SM8850 Add the ID for the Qualcomm SM8850 SoC which represents the Kaanapali platform. Signed-off-by: Jingyi Wang Reviewed-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20251022-knp-socid-v2-1-d147eadd09ee@oss.qualcomm.com Signed-off-by: Bjorn Andersson --- include/dt-bindings/arm/qcom,ids.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/dt-bindings/arm/qcom,ids.h b/include/dt-bindings/arm/qcom,ids.h index cb8ce53146f0..19598ed4679e 100644 --- a/include/dt-bindings/arm/qcom,ids.h +++ b/include/dt-bindings/arm/qcom,ids.h @@ -286,6 +286,7 @@ #define QCOM_ID_IPQ5424 651 #define QCOM_ID_QCM6690 657 #define QCOM_ID_QCS6690 658 +#define QCOM_ID_SM8850 660 #define QCOM_ID_IPQ5404 671 #define QCOM_ID_QCS9100 667 #define QCOM_ID_QCS8300 674 From 4648c70f2ee3636585d536d8272279e312180798 Mon Sep 17 00:00:00 2001 From: Jingyi Wang Date: Wed, 22 Oct 2025 21:57:37 -0700 Subject: [PATCH 054/114] soc: qcom: socinfo: Add SM8850 SoC ID Add SoC ID for Qualcomm SM8850 which represents the Kaanapali platform. Signed-off-by: Jingyi Wang Link: https://lore.kernel.org/r/20251022-knp-socid-v2-2-d147eadd09ee@oss.qualcomm.com Signed-off-by: Bjorn Andersson --- drivers/soc/qcom/socinfo.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/soc/qcom/socinfo.c b/drivers/soc/qcom/socinfo.c index 5627fb6ffbdb..4fd09e2bfd02 100644 --- a/drivers/soc/qcom/socinfo.c +++ b/drivers/soc/qcom/socinfo.c @@ -495,6 +495,7 @@ static const struct soc_id soc_id[] = { { qcom_board_id(IPQ5424) }, { qcom_board_id(QCM6690) }, { qcom_board_id(QCS6690) }, + { qcom_board_id(SM8850) }, { qcom_board_id(IPQ5404) }, { qcom_board_id(QCS9100) }, { qcom_board_id(QCS8300) }, From 6d49c6ede81516121b7dbf840040775f8da9333f Mon Sep 17 00:00:00 2001 From: Pankaj Patil Date: Thu, 18 Sep 2025 19:47:38 +0530 Subject: [PATCH 055/114] dt-bindings: firmware: qcom,scm: Document Glymur scm Document the SCM compatible for Qualcomm Glymur SoC. Secure Channel Manager(SCM) is used to communicate with secure firmware. Signed-off-by: Pankaj Patil Acked-by: Rob Herring (Arm) Link: https://lore.kernel.org/r/20250918141738.2524269-1-pankaj.patil@oss.qualcomm.com Signed-off-by: Bjorn Andersson --- Documentation/devicetree/bindings/firmware/qcom,scm.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/firmware/qcom,scm.yaml b/Documentation/devicetree/bindings/firmware/qcom,scm.yaml index ef97faac7e47..38c64c3783f8 100644 --- a/Documentation/devicetree/bindings/firmware/qcom,scm.yaml +++ b/Documentation/devicetree/bindings/firmware/qcom,scm.yaml @@ -23,6 +23,7 @@ properties: - enum: - qcom,scm-apq8064 - qcom,scm-apq8084 + - qcom,scm-glymur - qcom,scm-ipq4019 - qcom,scm-ipq5018 - qcom,scm-ipq5332 From 122df8416e7f4c68fb3248377a2b34cdd31a85b0 Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Mon, 27 Oct 2025 15:33:59 +0200 Subject: [PATCH 056/114] bus: sunxi-rsb: Remove redundant pm_runtime_mark_last_busy() calls pm_runtime_put_autosuspend(), pm_runtime_put_sync_autosuspend(), pm_runtime_autosuspend() and pm_request_autosuspend() now include a call to pm_runtime_mark_last_busy(). Remove the now-reduntant explicit call to pm_runtime_mark_last_busy(). Signed-off-by: Sakari Ailus Reviewed-by: Jernej Skrabec Link: https://patch.msgid.link/20251027133359.392984-1-sakari.ailus@linux.intel.com Signed-off-by: Chen-Yu Tsai --- drivers/bus/sunxi-rsb.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/bus/sunxi-rsb.c b/drivers/bus/sunxi-rsb.c index 7a33c3b31d1e..82735c58be11 100644 --- a/drivers/bus/sunxi-rsb.c +++ b/drivers/bus/sunxi-rsb.c @@ -373,7 +373,6 @@ static int sunxi_rsb_read(struct sunxi_rsb *rsb, u8 rtaddr, u8 addr, unlock: mutex_unlock(&rsb->lock); - pm_runtime_mark_last_busy(rsb->dev); pm_runtime_put_autosuspend(rsb->dev); return ret; @@ -417,7 +416,6 @@ static int sunxi_rsb_write(struct sunxi_rsb *rsb, u8 rtaddr, u8 addr, mutex_unlock(&rsb->lock); - pm_runtime_mark_last_busy(rsb->dev); pm_runtime_put_autosuspend(rsb->dev); return ret; From dd1d7af420e5a085e08c33220425caad35289bea Mon Sep 17 00:00:00 2001 From: Sirius Wang Date: Wed, 29 Oct 2025 21:08:34 +0800 Subject: [PATCH 057/114] soc: mediatek: mtk-socinfo: Add extra entry for MT8189 The MT8189 has a different socinfo match for MT8189 SoC (commercial name Kompanio 540), so add it the driver. Signed-off-by: Sirius Wang Signed-off-by: AngeloGioacchino Del Regno --- drivers/soc/mediatek/mtk-socinfo.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/soc/mediatek/mtk-socinfo.c b/drivers/soc/mediatek/mtk-socinfo.c index c697a0398d91..32153c122416 100644 --- a/drivers/soc/mediatek/mtk-socinfo.c +++ b/drivers/soc/mediatek/mtk-socinfo.c @@ -50,6 +50,8 @@ static struct socinfo_data socinfo_data_table[] = { MTK_SOCINFO_ENTRY("MT8186T", "MT8186TV/AZA", "Kompanio 528", 0x81862001, CELL_NOT_USED), MTK_SOCINFO_ENTRY("MT8188", "MT8188GV/AZA", "Kompanio 838", 0x81880000, 0x00000010), MTK_SOCINFO_ENTRY("MT8188", "MT8188GV/HZA", "Kompanio 838", 0x81880000, 0x00000011), + MTK_SOCINFO_ENTRY("MT8189", "MT8189GV/AZA", "Kompanio 540", 0x81890000, 0x00000020), + MTK_SOCINFO_ENTRY("MT8189", "MT8189HV/AZA", "Kompanio 540", 0x81890000, 0x00000021), MTK_SOCINFO_ENTRY("MT8192", "MT8192V/AZA", "Kompanio 820", 0x00001100, 0x00040080), MTK_SOCINFO_ENTRY("MT8192T", "MT8192V/ATZA", "Kompanio 828", 0x00000100, 0x000400C0), MTK_SOCINFO_ENTRY("MT8195", "MT8195GV/EZA", "Kompanio 1200", 0x81950300, CELL_NOT_USED), From 58fbc8208e9fd950ddaa2614ac6f324999c32d09 Mon Sep 17 00:00:00 2001 From: Yongxing Mou Date: Wed, 29 Oct 2025 16:51:37 +0800 Subject: [PATCH 058/114] soc: qcom: ubwc: Add QCS8300 UBWC cfg The QCS8300 supports UBWC 4.0 and 4 channels LP5 memory interface. Use the SC8280XP data structure for QCS8300 according to the specification. Acked-by: Bjorn Andersson Reviewed-by: Dmitry Baryshkov Signed-off-by: Yongxing Mou Reviewed-by: Konrad Dybcio Link: https://lore.kernel.org/r/20251029-qcs8300_mdss-v13-4-e8c8c4f82da2@oss.qualcomm.com Signed-off-by: Bjorn Andersson --- drivers/soc/qcom/ubwc_config.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/soc/qcom/ubwc_config.c b/drivers/soc/qcom/ubwc_config.c index 7cca2afb68e3..942fe6c17612 100644 --- a/drivers/soc/qcom/ubwc_config.c +++ b/drivers/soc/qcom/ubwc_config.c @@ -249,6 +249,7 @@ static const struct of_device_id qcom_ubwc_configs[] __maybe_unused = { { .compatible = "qcom,msm8998", .data = &msm8998_data }, { .compatible = "qcom,qcm2290", .data = &qcm2290_data, }, { .compatible = "qcom,qcm6490", .data = &sc7280_data, }, + { .compatible = "qcom,qcs8300", .data = &sc8280xp_data, }, { .compatible = "qcom,sa8155p", .data = &sm8150_data, }, { .compatible = "qcom,sa8540p", .data = &sc8280xp_data, }, { .compatible = "qcom,sa8775p", .data = &sa8775p_data, }, From 0fb35ecee061dde31c6a59ab5127695732332db4 Mon Sep 17 00:00:00 2001 From: Jingyi Wang Date: Wed, 22 Oct 2025 00:28:42 -0700 Subject: [PATCH 059/114] dt-bindings: soc: qcom,aoss-qmp: Document the Kaanapali AOSS channel Document the Always-On Subsystem side channel on the Qualcomm Kaanapali platform for communication with client found on the SoC such as remoteprocs. Reviewed-by: Eugen Hristev Signed-off-by: Jingyi Wang Acked-by: Rob Herring (Arm) Link: https://lore.kernel.org/r/20251022-knp-soc-binding-v2-2-3cd3f390f3e2@oss.qualcomm.com Signed-off-by: Bjorn Andersson --- Documentation/devicetree/bindings/soc/qcom/qcom,aoss-qmp.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/soc/qcom/qcom,aoss-qmp.yaml b/Documentation/devicetree/bindings/soc/qcom/qcom,aoss-qmp.yaml index 851a1260f8dc..57aa819939f0 100644 --- a/Documentation/devicetree/bindings/soc/qcom/qcom,aoss-qmp.yaml +++ b/Documentation/devicetree/bindings/soc/qcom/qcom,aoss-qmp.yaml @@ -25,6 +25,7 @@ properties: compatible: items: - enum: + - qcom,kaanapali-aoss-qmp - qcom,milos-aoss-qmp - qcom,qcs615-aoss-qmp - qcom,qcs8300-aoss-qmp From df8764c2cbfeae63c4fa42c9d4ce926e412fa53c Mon Sep 17 00:00:00 2001 From: Sibi Sankar Date: Wed, 22 Oct 2025 00:28:44 -0700 Subject: [PATCH 060/114] dt-bindings: soc: qcom,aoss-qmp: Document the Glymur AOSS side channel Document the Always-on Subsystem side channel on the Glymur SoC. Signed-off-by: Sibi Sankar Signed-off-by: Jingyi Wang Acked-by: Rob Herring (Arm) Link: https://lore.kernel.org/r/20251022-knp-soc-binding-v2-4-3cd3f390f3e2@oss.qualcomm.com Signed-off-by: Bjorn Andersson --- Documentation/devicetree/bindings/soc/qcom/qcom,aoss-qmp.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/soc/qcom/qcom,aoss-qmp.yaml b/Documentation/devicetree/bindings/soc/qcom/qcom,aoss-qmp.yaml index 57aa819939f0..c5c1bac2db01 100644 --- a/Documentation/devicetree/bindings/soc/qcom/qcom,aoss-qmp.yaml +++ b/Documentation/devicetree/bindings/soc/qcom/qcom,aoss-qmp.yaml @@ -25,6 +25,7 @@ properties: compatible: items: - enum: + - qcom,glymur-aoss-qmp - qcom,kaanapali-aoss-qmp - qcom,milos-aoss-qmp - qcom,qcs615-aoss-qmp From dc5db35073a19f6d3c30bea367b551c1a784ef8f Mon Sep 17 00:00:00 2001 From: Haotian Zhang Date: Wed, 29 Oct 2025 10:27:33 +0800 Subject: [PATCH 061/114] soc: qcom: smem: fix hwspinlock resource leak in probe error paths The hwspinlock acquired via hwspin_lock_request_specific() is not released on several error paths. This results in resource leakage when probe fails. Switch to devm_hwspin_lock_request_specific() to automatically handle cleanup on probe failure. Remove the manual hwspin_lock_free() in qcom_smem_remove() as devm handles it automatically. Fixes: 20bb6c9de1b7 ("soc: qcom: smem: map only partitions used by local HOST") Signed-off-by: Haotian Zhang Reviewed-by: Konrad Dybcio Link: https://lore.kernel.org/r/20251029022733.255-1-vulab@iscas.ac.cn Signed-off-by: Bjorn Andersson --- drivers/soc/qcom/smem.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/soc/qcom/smem.c b/drivers/soc/qcom/smem.c index c4c45f15dca4..f1d1b5aa5e4d 100644 --- a/drivers/soc/qcom/smem.c +++ b/drivers/soc/qcom/smem.c @@ -1190,7 +1190,7 @@ static int qcom_smem_probe(struct platform_device *pdev) return dev_err_probe(&pdev->dev, hwlock_id, "failed to retrieve hwlock\n"); - smem->hwlock = hwspin_lock_request_specific(hwlock_id); + smem->hwlock = devm_hwspin_lock_request_specific(&pdev->dev, hwlock_id); if (!smem->hwlock) return -ENXIO; @@ -1243,7 +1243,6 @@ static void qcom_smem_remove(struct platform_device *pdev) { platform_device_unregister(__smem->socinfo); - hwspin_lock_free(__smem->hwlock); __smem = NULL; } From 781bb149dae361eab5c8c1ece4d4c8ea953ecbf9 Mon Sep 17 00:00:00 2001 From: Louis-Alexis Eyraud Date: Wed, 29 Oct 2025 14:46:43 +0100 Subject: [PATCH 062/114] soc: mediatek: mtk-socinfo: Add entry for MT8391AV/AZA Genio 720 Add an entry for the MT8391 SoC with commercial name Genio 720. Signed-off-by: Louis-Alexis Eyraud Signed-off-by: AngeloGioacchino Del Regno --- drivers/soc/mediatek/mtk-socinfo.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/soc/mediatek/mtk-socinfo.c b/drivers/soc/mediatek/mtk-socinfo.c index 32153c122416..978c43e9115a 100644 --- a/drivers/soc/mediatek/mtk-socinfo.c +++ b/drivers/soc/mediatek/mtk-socinfo.c @@ -60,6 +60,7 @@ static struct socinfo_data socinfo_data_table[] = { MTK_SOCINFO_ENTRY("MT8195", "MT8195TV/EHZA", "Kompanio 1380", 0x81950404, CELL_NOT_USED), MTK_SOCINFO_ENTRY("MT8370", "MT8370AV/AZA", "Genio 510", 0x83700000, 0x00000081), MTK_SOCINFO_ENTRY("MT8390", "MT8390AV/AZA", "Genio 700", 0x83900000, 0x00000080), + MTK_SOCINFO_ENTRY("MT8391", "MT8391AV/AZA", "Genio 720", 0x83910000, 0x00000080), MTK_SOCINFO_ENTRY("MT8395", "MT8395AV/ZA", "Genio 1200", 0x83950100, CELL_NOT_USED), MTK_SOCINFO_ENTRY("MT8395", "MT8395AV/ZA", "Genio 1200", 0x83950800, CELL_NOT_USED), }; From 4459d667a3d7001d1c1703dc79c87db1808cdde2 Mon Sep 17 00:00:00 2001 From: Louis-Alexis Eyraud Date: Wed, 29 Oct 2025 14:25:57 +0100 Subject: [PATCH 063/114] dt-bindings: soc: mediatek: pwrap: Add compatible for MT8189 SoC Add compatible string for the PWRAP block on MT8189 SoC, which is compatible with the one used on MT8195. Signed-off-by: Louis-Alexis Eyraud Acked-by: Conor Dooley Reviewed-by: AngeloGioacchino Del Regno Signed-off-by: AngeloGioacchino Del Regno --- .../devicetree/bindings/soc/mediatek/mediatek,pwrap.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/soc/mediatek/mediatek,pwrap.yaml b/Documentation/devicetree/bindings/soc/mediatek/mediatek,pwrap.yaml index 54c0cd64d309..e7c4a3984c60 100644 --- a/Documentation/devicetree/bindings/soc/mediatek/mediatek,pwrap.yaml +++ b/Documentation/devicetree/bindings/soc/mediatek/mediatek,pwrap.yaml @@ -52,6 +52,7 @@ properties: - items: - enum: - mediatek,mt8188-pwrap + - mediatek,mt8189-pwrap - const: mediatek,mt8195-pwrap - const: syscon From 652a86b24c5ac444afaf7625c9340d55aab7f105 Mon Sep 17 00:00:00 2001 From: Christian Marangi Date: Fri, 31 Oct 2025 14:08:32 +0100 Subject: [PATCH 064/114] err.h: add INIT_ERR_PTR() macro Add INIT_ERR_PTR() macro to initialize static variables with error pointers. This might be useful for specific case where there is a static variable initialized to an error condition and then later set to the real handle once probe finish/completes. This is to handle compilation problems like: error: initializer element is not constant where ERR_PTR() can't be used. Signed-off-by: Christian Marangi Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20251031130835.7953-2-ansuelsmth@gmail.com [bjorn: Added () suffix on macro references] Signed-off-by: Bjorn Andersson --- include/linux/err.h | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/include/linux/err.h b/include/linux/err.h index 1d60aa86db53..8c37be0620ab 100644 --- a/include/linux/err.h +++ b/include/linux/err.h @@ -41,6 +41,14 @@ static inline void * __must_check ERR_PTR(long error) return (void *) error; } +/** + * INIT_ERR_PTR - Init a const error pointer. + * @error: A negative error code. + * + * Like ERR_PTR(), but usable to initialize static variables. + */ +#define INIT_ERR_PTR(error) ((void *)(error)) + /* Return the pointer in the percpu address space. */ #define ERR_PTR_PCPU(error) ((void __percpu *)(unsigned long)ERR_PTR(error)) From 7a94d5f31b549e18f908cb669c59f066f45a21c7 Mon Sep 17 00:00:00 2001 From: Christian Marangi Date: Fri, 31 Oct 2025 14:08:33 +0100 Subject: [PATCH 065/114] soc: qcom: smem: better track SMEM uninitialized state There is currently a problem where, in the specific case of SMEM not initialized by SBL, any SMEM API wrongly returns PROBE_DEFER communicating wrong info to any user of this API. A better way to handle this would be to track the SMEM state and return a different kind of error than PROBE_DEFER. Rework the __smem handle to always init it to the error pointer -EPROBE_DEFER following what is already done by the SMEM API. If we detect that the SBL didn't initialized SMEM, set the __smem handle to the error pointer -ENODEV. Also rework the SMEM API to handle the __smem handle to be an error pointer and return it appropriately. This way user of the API can react and return a proper error or use fallback way for the failing API. While at it, change the return error when SMEM is not initialized by SBL also to -ENODEV to make it consistent with the __smem handle and use dev_err_probe() helper to return the message. Signed-off-by: Christian Marangi Link: https://lore.kernel.org/r/20251031130835.7953-3-ansuelsmth@gmail.com Signed-off-by: Bjorn Andersson --- drivers/soc/qcom/smem.c | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/drivers/soc/qcom/smem.c b/drivers/soc/qcom/smem.c index f1d1b5aa5e4d..f4a4acfefba9 100644 --- a/drivers/soc/qcom/smem.c +++ b/drivers/soc/qcom/smem.c @@ -353,8 +353,12 @@ static void *cached_entry_to_item(struct smem_private_entry *e) return p - le32_to_cpu(e->size); } -/* Pointer to the one and only smem handle */ -static struct qcom_smem *__smem; +/* + * Pointer to the one and only smem handle. + * Init to -EPROBE_DEFER to signal SMEM still has to be probed. + * Can be set to -ENODEV if SMEM is not initialized by SBL. + */ +static struct qcom_smem *__smem = INIT_ERR_PTR(-EPROBE_DEFER); /* Timeout (ms) for the trylock of remote spinlocks */ #define HWSPINLOCK_TIMEOUT 1000 @@ -508,8 +512,8 @@ int qcom_smem_alloc(unsigned host, unsigned item, size_t size) unsigned long flags; int ret; - if (!__smem) - return -EPROBE_DEFER; + if (IS_ERR(__smem)) + return PTR_ERR(__smem); if (item < SMEM_ITEM_LAST_FIXED) { dev_err(__smem->dev, @@ -685,10 +689,10 @@ static void *qcom_smem_get_private(struct qcom_smem *smem, void *qcom_smem_get(unsigned host, unsigned item, size_t *size) { struct smem_partition *part; - void *ptr = ERR_PTR(-EPROBE_DEFER); + void *ptr; - if (!__smem) - return ptr; + if (IS_ERR(__smem)) + return __smem; if (WARN_ON(item >= __smem->item_count)) return ERR_PTR(-EINVAL); @@ -723,8 +727,8 @@ int qcom_smem_get_free_space(unsigned host) struct smem_header *header; unsigned ret; - if (!__smem) - return -EPROBE_DEFER; + if (IS_ERR(__smem)) + return PTR_ERR(__smem); if (host < SMEM_HOST_COUNT && __smem->partitions[host].virt_base) { part = &__smem->partitions[host]; @@ -1181,8 +1185,8 @@ static int qcom_smem_probe(struct platform_device *pdev) header = smem->regions[0].virt_base; if (le32_to_cpu(header->initialized) != 1 || le32_to_cpu(header->reserved)) { - dev_err(&pdev->dev, "SMEM is not initialized by SBL\n"); - return -EINVAL; + __smem = ERR_PTR(-ENODEV); + return dev_err_probe(&pdev->dev, PTR_ERR(__smem), "SMEM is not initialized by SBL\n"); } hwlock_id = of_hwspin_lock_get_id(pdev->dev.of_node, 0); From bea18c67a0ec75cc602aabc523d726a4626e1341 Mon Sep 17 00:00:00 2001 From: Tudor Ambarus Date: Fri, 31 Oct 2025 12:56:01 +0000 Subject: [PATCH 066/114] soc: samsung: exynos-chipid: use a local dev variable Use a local variable for struct device to avoid dereferencing. Signed-off-by: Tudor Ambarus Link: https://patch.msgid.link/20251031-gs101-chipid-v1-2-d78d1076b210@linaro.org Signed-off-by: Krzysztof Kozlowski --- drivers/soc/samsung/exynos-chipid.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/soc/samsung/exynos-chipid.c b/drivers/soc/samsung/exynos-chipid.c index 0f9f83a00679..d3b4b5508e0c 100644 --- a/drivers/soc/samsung/exynos-chipid.c +++ b/drivers/soc/samsung/exynos-chipid.c @@ -109,16 +109,17 @@ static int exynos_chipid_probe(struct platform_device *pdev) const struct exynos_chipid_variant *drv_data; struct exynos_chipid_info soc_info; struct soc_device_attribute *soc_dev_attr; + struct device *dev = &pdev->dev; struct soc_device *soc_dev; struct device_node *root; struct regmap *regmap; int ret; - drv_data = of_device_get_match_data(&pdev->dev); + drv_data = of_device_get_match_data(dev); if (!drv_data) return -EINVAL; - regmap = device_node_to_regmap(pdev->dev.of_node); + regmap = device_node_to_regmap(dev->of_node); if (IS_ERR(regmap)) return PTR_ERR(regmap); @@ -126,8 +127,7 @@ static int exynos_chipid_probe(struct platform_device *pdev) if (ret < 0) return ret; - soc_dev_attr = devm_kzalloc(&pdev->dev, sizeof(*soc_dev_attr), - GFP_KERNEL); + soc_dev_attr = devm_kzalloc(dev, sizeof(*soc_dev_attr), GFP_KERNEL); if (!soc_dev_attr) return -ENOMEM; @@ -137,8 +137,8 @@ static int exynos_chipid_probe(struct platform_device *pdev) of_property_read_string(root, "model", &soc_dev_attr->machine); of_node_put(root); - soc_dev_attr->revision = devm_kasprintf(&pdev->dev, GFP_KERNEL, - "%x", soc_info.revision); + soc_dev_attr->revision = devm_kasprintf(dev, GFP_KERNEL, "%x", + soc_info.revision); if (!soc_dev_attr->revision) return -ENOMEM; soc_dev_attr->soc_id = product_id_to_soc_id(soc_info.product_id); @@ -152,13 +152,13 @@ static int exynos_chipid_probe(struct platform_device *pdev) if (IS_ERR(soc_dev)) return PTR_ERR(soc_dev); - ret = exynos_asv_init(&pdev->dev, regmap); + ret = exynos_asv_init(dev, regmap); if (ret) goto err; platform_set_drvdata(pdev, soc_dev); - dev_info(&pdev->dev, "Exynos: CPU[%s] PRO_ID[0x%x] REV[0x%x] Detected\n", + dev_info(dev, "Exynos: CPU[%s] PRO_ID[0x%x] REV[0x%x] Detected\n", soc_dev_attr->soc_id, soc_info.product_id, soc_info.revision); return 0; From 7a4cd87e76fb4547d7843e3124611bf13004b18b Mon Sep 17 00:00:00 2001 From: "Thomas Richard (TI.com)" Date: Tue, 14 Oct 2025 10:35:23 +0200 Subject: [PATCH 067/114] firmware: ti_sci: Replace ifdeffery by pm_sleep_ptr() macro Using pm_sleep_ptr() macro allows to remove ifdeffery and '__maybe_unused' annotations. Signed-off-by: Thomas Richard (TI.com) Link: https://patch.msgid.link/20251014-ti-sci-pm-ops-cleanup-v1-1-70b50b73ac85@bootlin.com Signed-off-by: Nishanth Menon --- drivers/firmware/ti_sci.c | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/drivers/firmware/ti_sci.c b/drivers/firmware/ti_sci.c index 49fd2ae01055..99a2e0e2960f 100644 --- a/drivers/firmware/ti_sci.c +++ b/drivers/firmware/ti_sci.c @@ -3706,7 +3706,7 @@ static int ti_sci_prepare_system_suspend(struct ti_sci_info *info) } } -static int __maybe_unused ti_sci_suspend(struct device *dev) +static int ti_sci_suspend(struct device *dev) { struct ti_sci_info *info = dev_get_drvdata(dev); struct device *cpu_dev, *cpu_dev_max = NULL; @@ -3746,7 +3746,7 @@ static int __maybe_unused ti_sci_suspend(struct device *dev) return 0; } -static int __maybe_unused ti_sci_suspend_noirq(struct device *dev) +static int ti_sci_suspend_noirq(struct device *dev) { struct ti_sci_info *info = dev_get_drvdata(dev); int ret = 0; @@ -3758,7 +3758,7 @@ static int __maybe_unused ti_sci_suspend_noirq(struct device *dev) return 0; } -static int __maybe_unused ti_sci_resume_noirq(struct device *dev) +static int ti_sci_resume_noirq(struct device *dev) { struct ti_sci_info *info = dev_get_drvdata(dev); int ret = 0; @@ -3780,7 +3780,7 @@ static int __maybe_unused ti_sci_resume_noirq(struct device *dev) return 0; } -static void __maybe_unused ti_sci_pm_complete(struct device *dev) +static void ti_sci_pm_complete(struct device *dev) { struct ti_sci_info *info = dev_get_drvdata(dev); @@ -3791,12 +3791,10 @@ static void __maybe_unused ti_sci_pm_complete(struct device *dev) } static const struct dev_pm_ops ti_sci_pm_ops = { -#ifdef CONFIG_PM_SLEEP - .suspend = ti_sci_suspend, - .suspend_noirq = ti_sci_suspend_noirq, - .resume_noirq = ti_sci_resume_noirq, - .complete = ti_sci_pm_complete, -#endif + .suspend = pm_sleep_ptr(ti_sci_suspend), + .suspend_noirq = pm_sleep_ptr(ti_sci_suspend_noirq), + .resume_noirq = pm_sleep_ptr(ti_sci_resume_noirq), + .complete = pm_sleep_ptr(ti_sci_pm_complete), }; /* Description for K2G */ From 999e9bc953e321651d69556fdd5dfd178f96f128 Mon Sep 17 00:00:00 2001 From: "Thomas Richard (TI.com)" Date: Fri, 31 Oct 2025 13:44:56 +0100 Subject: [PATCH 068/114] firmware: ti_sci: Set IO Isolation only if the firmware is capable Prevent calling ti_sci_cmd_set_io_isolation() on firmware that does not support the IO_ISOLATION capability. Add the MSG_FLAG_CAPS_IO_ISOLATION capability flag and check it before attempting to set IO isolation during suspend/resume operations. Without this check, systems with older firmware may experience undefined behavior or errors when entering/exiting suspend states. Fixes: ec24643bdd62 ("firmware: ti_sci: Add system suspend and resume call") Signed-off-by: Thomas Richard (TI.com) Reviewed-by: Kevin Hilman Link: https://patch.msgid.link/20251031-ti-sci-io-isolation-v2-1-60d826b65949@bootlin.com Signed-off-by: Nishanth Menon --- drivers/firmware/ti_sci.c | 21 +++++++++++++-------- drivers/firmware/ti_sci.h | 2 ++ 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/drivers/firmware/ti_sci.c b/drivers/firmware/ti_sci.c index 99a2e0e2960f..34df75cf42fd 100644 --- a/drivers/firmware/ti_sci.c +++ b/drivers/firmware/ti_sci.c @@ -3751,9 +3751,11 @@ static int ti_sci_suspend_noirq(struct device *dev) struct ti_sci_info *info = dev_get_drvdata(dev); int ret = 0; - ret = ti_sci_cmd_set_io_isolation(&info->handle, TISCI_MSG_VALUE_IO_ENABLE); - if (ret) - return ret; + if (info->fw_caps & MSG_FLAG_CAPS_IO_ISOLATION) { + ret = ti_sci_cmd_set_io_isolation(&info->handle, TISCI_MSG_VALUE_IO_ENABLE); + if (ret) + return ret; + } return 0; } @@ -3767,9 +3769,11 @@ static int ti_sci_resume_noirq(struct device *dev) u8 pin; u8 mode; - ret = ti_sci_cmd_set_io_isolation(&info->handle, TISCI_MSG_VALUE_IO_DISABLE); - if (ret) - return ret; + if (info->fw_caps & MSG_FLAG_CAPS_IO_ISOLATION) { + ret = ti_sci_cmd_set_io_isolation(&info->handle, TISCI_MSG_VALUE_IO_DISABLE); + if (ret) + return ret; + } ret = ti_sci_msg_cmd_lpm_wake_reason(&info->handle, &source, &time, &pin, &mode); /* Do not fail to resume on error as the wake reason is not critical */ @@ -3926,11 +3930,12 @@ static int ti_sci_probe(struct platform_device *pdev) } ti_sci_msg_cmd_query_fw_caps(&info->handle, &info->fw_caps); - dev_dbg(dev, "Detected firmware capabilities: %s%s%s%s\n", + dev_dbg(dev, "Detected firmware capabilities: %s%s%s%s%s\n", info->fw_caps & MSG_FLAG_CAPS_GENERIC ? "Generic" : "", info->fw_caps & MSG_FLAG_CAPS_LPM_PARTIAL_IO ? " Partial-IO" : "", info->fw_caps & MSG_FLAG_CAPS_LPM_DM_MANAGED ? " DM-Managed" : "", - info->fw_caps & MSG_FLAG_CAPS_LPM_ABORT ? " LPM-Abort" : "" + info->fw_caps & MSG_FLAG_CAPS_LPM_ABORT ? " LPM-Abort" : "", + info->fw_caps & MSG_FLAG_CAPS_IO_ISOLATION ? " IO-Isolation" : "" ); ti_sci_setup_ops(info); diff --git a/drivers/firmware/ti_sci.h b/drivers/firmware/ti_sci.h index 701c416b2e78..7559cde17b6c 100644 --- a/drivers/firmware/ti_sci.h +++ b/drivers/firmware/ti_sci.h @@ -149,6 +149,7 @@ struct ti_sci_msg_req_reboot { * MSG_FLAG_CAPS_LPM_PARTIAL_IO: Partial IO in LPM * MSG_FLAG_CAPS_LPM_DM_MANAGED: LPM can be managed by DM * MSG_FLAG_CAPS_LPM_ABORT: Abort entry to LPM + * MSG_FLAG_CAPS_IO_ISOLATION: IO Isolation support * * Response to a generic message with message type TI_SCI_MSG_QUERY_FW_CAPS * providing currently available SOC/firmware capabilities. SoC that don't @@ -160,6 +161,7 @@ struct ti_sci_msg_resp_query_fw_caps { #define MSG_FLAG_CAPS_LPM_PARTIAL_IO TI_SCI_MSG_FLAG(4) #define MSG_FLAG_CAPS_LPM_DM_MANAGED TI_SCI_MSG_FLAG(5) #define MSG_FLAG_CAPS_LPM_ABORT TI_SCI_MSG_FLAG(9) +#define MSG_FLAG_CAPS_IO_ISOLATION TI_SCI_MSG_FLAG(7) #define MSG_MASK_CAPS_LPM GENMASK_ULL(4, 1) u64 fw_caps; } __packed; From d92ebadda5e30085e5294935e7c1c35801752cbd Mon Sep 17 00:00:00 2001 From: Neeraj Soni Date: Thu, 30 Oct 2025 21:40:12 +0530 Subject: [PATCH 069/114] soc: qcom: ice: Add HWKM v1 support for wrapped keys HWKM v1 and v2 differ slightly in wrapped key size and the bit fields for certain status registers and operating mode (legacy or standard). Add support to select HWKM version based on the major and minor revisions. Use this HWKM version to select wrapped key size and to configure the bit fields in registers for operating modes and hardware status. Support for SCM calls for wrapped keys is being added in the TrustZone for few SoCs with HWKM v1. Existing check of qcom_scm_has_wrapped_key_support() API ensures that HWKM is used only if these SCM calls are supported in TrustZone for that SoC. Signed-off-by: Neeraj Soni Reviewed-by: Konrad Dybcio Link: https://lore.kernel.org/r/20251030161012.3391239-1-neeraj.soni@oss.qualcomm.com Signed-off-by: Bjorn Andersson --- drivers/soc/qcom/ice.c | 81 ++++++++++++++++++++++++++++++------------ 1 file changed, 58 insertions(+), 23 deletions(-) diff --git a/drivers/soc/qcom/ice.c b/drivers/soc/qcom/ice.c index c467b55b4174..b203bc685cad 100644 --- a/drivers/soc/qcom/ice.c +++ b/drivers/soc/qcom/ice.c @@ -22,7 +22,18 @@ #include #define AES_256_XTS_KEY_SIZE 64 /* for raw keys only */ -#define QCOM_ICE_HWKM_WRAPPED_KEY_SIZE 100 /* assuming HWKM v2 */ + +#define QCOM_ICE_HWKM_V1 1 /* HWKM version 1 */ +#define QCOM_ICE_HWKM_V2 2 /* HWKM version 2 */ + +#define QCOM_ICE_HWKM_MAX_WRAPPED_KEY_SIZE 100 /* Maximum HWKM wrapped key size */ + +/* + * Wrapped key size depends upon HWKM version: + * HWKM version 1 supports 68 bytes + * HWKM version 2 supports 100 bytes + */ +#define QCOM_ICE_HWKM_WRAPPED_KEY_SIZE(v) ((v) == QCOM_ICE_HWKM_V1 ? 68 : 100) /* QCOM ICE registers */ @@ -62,13 +73,15 @@ union crypto_cfg { #define QCOM_ICE_REG_HWKM_TZ_KM_CTL (HWKM_OFFSET + 0x1000) #define QCOM_ICE_HWKM_DISABLE_CRC_CHECKS_VAL (BIT(1) | BIT(2)) +/* In HWKM v1 the ICE legacy mode is controlled from HWKM register space */ +#define QCOM_ICE_HWKM_ICE_LEGACY_MODE_ENABLED BIT(5) #define QCOM_ICE_REG_HWKM_TZ_KM_STATUS (HWKM_OFFSET + 0x1004) #define QCOM_ICE_HWKM_KT_CLEAR_DONE BIT(0) #define QCOM_ICE_HWKM_BOOT_CMD_LIST0_DONE BIT(1) #define QCOM_ICE_HWKM_BOOT_CMD_LIST1_DONE BIT(2) -#define QCOM_ICE_HWKM_CRYPTO_BIST_DONE_V2 BIT(7) -#define QCOM_ICE_HWKM_BIST_DONE_V2 BIT(9) +#define QCOM_ICE_HWKM_CRYPTO_BIST_DONE(v) (((v) == QCOM_ICE_HWKM_V1) ? BIT(14) : BIT(7)) +#define QCOM_ICE_HWKM_BIST_DONE(v) (((v) == QCOM_ICE_HWKM_V1) ? BIT(16) : BIT(9)) #define QCOM_ICE_REG_HWKM_BANK0_BANKN_IRQ_STATUS (HWKM_OFFSET + 0x2008) #define QCOM_ICE_HWKM_RSP_FIFO_CLEAR_VAL BIT(3) @@ -97,6 +110,7 @@ struct qcom_ice { struct clk *core_clk; bool use_hwkm; bool hwkm_init_complete; + u8 hwkm_version; }; static bool qcom_ice_check_supported(struct qcom_ice *ice) @@ -114,9 +128,24 @@ static bool qcom_ice_check_supported(struct qcom_ice *ice) return false; } + /* HWKM version v2 is present from ICE 3.2.1 onwards while version v1 + * is present only in ICE 3.2.0. Earlier ICE version don't have HWKM. + */ + if (major > 3 || + (major == 3 && (minor >= 3 || (minor == 2 && step >= 1)))) + ice->hwkm_version = QCOM_ICE_HWKM_V2; + else if ((major == 3) && (minor == 2)) + ice->hwkm_version = QCOM_ICE_HWKM_V1; + else + ice->hwkm_version = 0; + dev_info(dev, "Found QC Inline Crypto Engine (ICE) v%d.%d.%d\n", major, minor, step); + if (ice->hwkm_version) + dev_info(dev, "QC Hardware Key Manager (HWKM) version v%d\n", + ice->hwkm_version); + /* If fuses are blown, ICE might not work in the standard way. */ regval = qcom_ice_readl(ice, QCOM_ICE_REG_FUSE_SETTING); if (regval & (QCOM_ICE_FUSE_SETTING_MASK | @@ -131,19 +160,18 @@ static bool qcom_ice_check_supported(struct qcom_ice *ice) * v3.2.1 and later have HWKM v2. ICE v3.2.0 has HWKM v1. Earlier ICE * versions don't have HWKM at all. However, for HWKM to be fully * usable by Linux, the TrustZone software also needs to support certain - * SCM calls including the ones to generate and prepare keys. That - * effectively makes the earliest supported SoC be SM8650, which has - * HWKM v2. Therefore, this driver doesn't include support for HWKM v1, - * and it checks for the SCM call support before it decides to use HWKM. + * SCM calls including the ones to generate and prepare keys. Support + * for these SCM calls is present for SoCs with HWKM v2 and is being + * added for SoCs with HWKM v1 as well but not every SoC with HWKM v1 + * currently supports this. So, this driver checks for the SCM call + * support before it decides to use HWKM. * * Also, since HWKM and legacy mode are mutually exclusive, and * ICE-capable storage driver(s) need to know early on whether to * advertise support for raw keys or wrapped keys, HWKM cannot be used * unconditionally. A module parameter is used to opt into using it. */ - if ((major >= 4 || - (major == 3 && (minor >= 3 || (minor == 2 && step >= 1)))) && - qcom_scm_has_wrapped_key_support()) { + if (ice->hwkm_version && qcom_scm_has_wrapped_key_support()) { if (qcom_ice_use_wrapped_keys) { dev_info(dev, "Using HWKM. Supporting wrapped keys only.\n"); ice->use_hwkm = true; @@ -212,8 +240,8 @@ static int qcom_ice_wait_bist_status(struct qcom_ice *ice) (QCOM_ICE_HWKM_KT_CLEAR_DONE | QCOM_ICE_HWKM_BOOT_CMD_LIST0_DONE | QCOM_ICE_HWKM_BOOT_CMD_LIST1_DONE | - QCOM_ICE_HWKM_CRYPTO_BIST_DONE_V2 | - QCOM_ICE_HWKM_BIST_DONE_V2)) { + QCOM_ICE_HWKM_CRYPTO_BIST_DONE(ice->hwkm_version) | + QCOM_ICE_HWKM_BIST_DONE(ice->hwkm_version))) { dev_err(ice->dev, "HWKM self-test error!\n"); /* * Too late to revoke use_hwkm here, as it was already @@ -230,7 +258,7 @@ static void qcom_ice_hwkm_init(struct qcom_ice *ice) if (!ice->use_hwkm) return; - BUILD_BUG_ON(QCOM_ICE_HWKM_WRAPPED_KEY_SIZE > + BUILD_BUG_ON(QCOM_ICE_HWKM_MAX_WRAPPED_KEY_SIZE > BLK_CRYPTO_MAX_HW_WRAPPED_KEY_SIZE); /* * When ICE is in HWKM mode, it only supports wrapped keys. @@ -238,9 +266,15 @@ static void qcom_ice_hwkm_init(struct qcom_ice *ice) * * Put ICE in HWKM mode. ICE defaults to legacy mode. */ - regval = qcom_ice_readl(ice, QCOM_ICE_REG_CONTROL); - regval &= ~QCOM_ICE_LEGACY_MODE_ENABLED; - qcom_ice_writel(ice, regval, QCOM_ICE_REG_CONTROL); + if (ice->hwkm_version == QCOM_ICE_HWKM_V2) { + regval = qcom_ice_readl(ice, QCOM_ICE_REG_CONTROL); + regval &= ~QCOM_ICE_LEGACY_MODE_ENABLED; + qcom_ice_writel(ice, regval, QCOM_ICE_REG_CONTROL); + } else if (ice->hwkm_version == QCOM_ICE_HWKM_V1) { + regval = qcom_ice_readl(ice, QCOM_ICE_REG_HWKM_TZ_KM_CTL); + regval &= ~QCOM_ICE_HWKM_ICE_LEGACY_MODE_ENABLED; + qcom_ice_writel(ice, regval, QCOM_ICE_REG_HWKM_TZ_KM_CTL); + } /* Disable CRC checks. This HWKM feature is not used. */ qcom_ice_writel(ice, QCOM_ICE_HWKM_DISABLE_CRC_CHECKS_VAL, @@ -298,7 +332,7 @@ EXPORT_SYMBOL_GPL(qcom_ice_suspend); static unsigned int translate_hwkm_slot(struct qcom_ice *ice, unsigned int slot) { - return slot * 2; + return ice->hwkm_version == QCOM_ICE_HWKM_V1 ? slot : slot * 2; } static int qcom_ice_program_wrapped_key(struct qcom_ice *ice, unsigned int slot, @@ -451,11 +485,12 @@ int qcom_ice_generate_key(struct qcom_ice *ice, { int err; - err = qcom_scm_generate_ice_key(lt_key, QCOM_ICE_HWKM_WRAPPED_KEY_SIZE); + err = qcom_scm_generate_ice_key(lt_key, + QCOM_ICE_HWKM_WRAPPED_KEY_SIZE(ice->hwkm_version)); if (err) return err; - return QCOM_ICE_HWKM_WRAPPED_KEY_SIZE; + return QCOM_ICE_HWKM_WRAPPED_KEY_SIZE(ice->hwkm_version); } EXPORT_SYMBOL_GPL(qcom_ice_generate_key); @@ -478,13 +513,13 @@ int qcom_ice_prepare_key(struct qcom_ice *ice, int err; err = qcom_scm_prepare_ice_key(lt_key, lt_key_size, - eph_key, QCOM_ICE_HWKM_WRAPPED_KEY_SIZE); + eph_key, QCOM_ICE_HWKM_WRAPPED_KEY_SIZE(ice->hwkm_version)); if (err == -EIO || err == -EINVAL) err = -EBADMSG; /* probably invalid key */ if (err) return err; - return QCOM_ICE_HWKM_WRAPPED_KEY_SIZE; + return QCOM_ICE_HWKM_WRAPPED_KEY_SIZE(ice->hwkm_version); } EXPORT_SYMBOL_GPL(qcom_ice_prepare_key); @@ -506,11 +541,11 @@ int qcom_ice_import_key(struct qcom_ice *ice, int err; err = qcom_scm_import_ice_key(raw_key, raw_key_size, - lt_key, QCOM_ICE_HWKM_WRAPPED_KEY_SIZE); + lt_key, QCOM_ICE_HWKM_WRAPPED_KEY_SIZE(ice->hwkm_version)); if (err) return err; - return QCOM_ICE_HWKM_WRAPPED_KEY_SIZE; + return QCOM_ICE_HWKM_WRAPPED_KEY_SIZE(ice->hwkm_version); } EXPORT_SYMBOL_GPL(qcom_ice_import_key); From 98c92de40f6ab05452f8919cc2ff800ade5dd9a3 Mon Sep 17 00:00:00 2001 From: Komal Bajaj Date: Mon, 3 Nov 2025 16:53:10 +0530 Subject: [PATCH 070/114] dt-bindings: arm: qcom,ids: Add SoC ID for QCS6490 Add unique ID for Qualcomm QCS6490 SoC. Signed-off-by: Komal Bajaj Link: https://lore.kernel.org/r/20251103-qcs6490_soc_id-v1-1-c139dd1e32c8@oss.qualcomm.com Signed-off-by: Bjorn Andersson --- include/dt-bindings/arm/qcom,ids.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/dt-bindings/arm/qcom,ids.h b/include/dt-bindings/arm/qcom,ids.h index 19598ed4679e..8776844e0eeb 100644 --- a/include/dt-bindings/arm/qcom,ids.h +++ b/include/dt-bindings/arm/qcom,ids.h @@ -240,6 +240,7 @@ #define QCOM_ID_SC7280 487 #define QCOM_ID_SC7180P 495 #define QCOM_ID_QCM6490 497 +#define QCOM_ID_QCS6490 498 #define QCOM_ID_SM7325P 499 #define QCOM_ID_IPQ5000 503 #define QCOM_ID_IPQ0509 504 From 40360803622c180747096aa2f165a02fef3628a5 Mon Sep 17 00:00:00 2001 From: Komal Bajaj Date: Mon, 3 Nov 2025 16:53:11 +0530 Subject: [PATCH 071/114] soc: qcom: socinfo: Add SoC ID for QCS6490 Add SoC ID table entry for Qualcomm QCS6490. Signed-off-by: Komal Bajaj Link: https://lore.kernel.org/r/20251103-qcs6490_soc_id-v1-2-c139dd1e32c8@oss.qualcomm.com Signed-off-by: Bjorn Andersson --- drivers/soc/qcom/socinfo.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/soc/qcom/socinfo.c b/drivers/soc/qcom/socinfo.c index 4fd09e2bfd02..69642891ad57 100644 --- a/drivers/soc/qcom/socinfo.c +++ b/drivers/soc/qcom/socinfo.c @@ -449,6 +449,7 @@ static const struct soc_id soc_id[] = { { qcom_board_id(SC7280) }, { qcom_board_id(SC7180P) }, { qcom_board_id(QCM6490) }, + { qcom_board_id(QCS6490) }, { qcom_board_id(SM7325P) }, { qcom_board_id(IPQ5000) }, { qcom_board_id(IPQ0509) }, From 85d55d8cc3ef7f77b249c97e9fac6a0fc5f5daa7 Mon Sep 17 00:00:00 2001 From: Akhil P Oommen Date: Tue, 30 Sep 2025 11:18:06 +0530 Subject: [PATCH 072/114] soc: qcom: ubwc: Add config for Kaanapali Add the ubwc configuration for Kaanapali chipset. This chipset brings support for UBWC v6 version. The rest of the configurations remains as usual. Signed-off-by: Akhil P Oommen Reviewed-by: Konrad Dybcio Reviewed-by: Dmitry Baryshkov Link: https://lore.kernel.org/r/20250930-kaana-gpu-support-v1-1-73530b0700ed@oss.qualcomm.com Signed-off-by: Bjorn Andersson --- drivers/soc/qcom/ubwc_config.c | 11 +++++++++++ include/linux/soc/qcom/ubwc.h | 1 + 2 files changed, 12 insertions(+) diff --git a/drivers/soc/qcom/ubwc_config.c b/drivers/soc/qcom/ubwc_config.c index 942fe6c17612..1c09796163b0 100644 --- a/drivers/soc/qcom/ubwc_config.c +++ b/drivers/soc/qcom/ubwc_config.c @@ -16,6 +16,16 @@ static const struct qcom_ubwc_cfg_data no_ubwc_data = { /* no UBWC, no HBB */ }; +static const struct qcom_ubwc_cfg_data kaanapali_data = { + .ubwc_enc_version = UBWC_6_0, + .ubwc_dec_version = UBWC_6_0, + .ubwc_swizzle = UBWC_SWIZZLE_ENABLE_LVL2 | + UBWC_SWIZZLE_ENABLE_LVL3, + .ubwc_bank_spread = true, + .highest_bank_bit = 16, + .macrotile_mode = true, +}; + static const struct qcom_ubwc_cfg_data msm8937_data = { .ubwc_enc_version = UBWC_1_0, .ubwc_dec_version = UBWC_1_0, @@ -234,6 +244,7 @@ static const struct of_device_id qcom_ubwc_configs[] __maybe_unused = { { .compatible = "qcom,apq8026", .data = &no_ubwc_data }, { .compatible = "qcom,apq8074", .data = &no_ubwc_data }, { .compatible = "qcom,apq8096", .data = &msm8998_data }, + { .compatible = "qcom,kaanapali", .data = &kaanapali_data, }, { .compatible = "qcom,glymur", .data = &glymur_data}, { .compatible = "qcom,msm8226", .data = &no_ubwc_data }, { .compatible = "qcom,msm8916", .data = &no_ubwc_data }, diff --git a/include/linux/soc/qcom/ubwc.h b/include/linux/soc/qcom/ubwc.h index 1ed8b1b16bc9..0a4edfe3d96d 100644 --- a/include/linux/soc/qcom/ubwc.h +++ b/include/linux/soc/qcom/ubwc.h @@ -52,6 +52,7 @@ struct qcom_ubwc_cfg_data { #define UBWC_4_0 0x40000000 #define UBWC_4_3 0x40030000 #define UBWC_5_0 0x50000000 +#define UBWC_6_0 0x60000000 #if IS_ENABLED(CONFIG_QCOM_UBWC_CONFIG) const struct qcom_ubwc_cfg_data *qcom_ubwc_config_get_data(void); From d403276969b2aae147f671506a6c69089587ddd7 Mon Sep 17 00:00:00 2001 From: Kathiravan Thirumoorthy Date: Fri, 31 Oct 2025 11:21:01 +0530 Subject: [PATCH 073/114] soc: qcom: smem: drop the WARN_ON() on SMEM item validation When a SMEM item is allocated or retrieved, sanity check on the SMEM item is performed and backtrace is printed if it is invalid. But there is no benefit in dumping that information in the logs. Lets drop it. Signed-off-by: Kathiravan Thirumoorthy Link: https://lore.kernel.org/r/20251031-image-crm-part2-v2-1-c224c45c381a@oss.qualcomm.com Signed-off-by: Bjorn Andersson --- drivers/soc/qcom/smem.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/soc/qcom/smem.c b/drivers/soc/qcom/smem.c index f4a4acfefba9..fef840b54574 100644 --- a/drivers/soc/qcom/smem.c +++ b/drivers/soc/qcom/smem.c @@ -521,7 +521,7 @@ int qcom_smem_alloc(unsigned host, unsigned item, size_t size) return -EINVAL; } - if (WARN_ON(item >= __smem->item_count)) + if (item >= __smem->item_count) return -EINVAL; ret = hwspin_lock_timeout_irqsave(__smem->hwlock, @@ -694,7 +694,7 @@ void *qcom_smem_get(unsigned host, unsigned item, size_t *size) if (IS_ERR(__smem)) return __smem; - if (WARN_ON(item >= __smem->item_count)) + if (item >= __smem->item_count) return ERR_PTR(-EINVAL); if (host < SMEM_HOST_COUNT && __smem->partitions[host].virt_base) { From db252c105648d1c15826b24dd4251b005e243c30 Mon Sep 17 00:00:00 2001 From: Kathiravan Thirumoorthy Date: Fri, 31 Oct 2025 11:21:02 +0530 Subject: [PATCH 074/114] soc: qcom: socinfo: add support to extract more than 32 image versions SMEM_IMAGE_VERSION_TABLE contains the version of the first 32 images. Add images beyond that and read these from SMEM_IMAGE_VERSION_TABLE_2. Signed-off-by: Kathiravan Thirumoorthy Link: https://lore.kernel.org/r/20251031-image-crm-part2-v2-2-c224c45c381a@oss.qualcomm.com Signed-off-by: Bjorn Andersson --- drivers/soc/qcom/socinfo.c | 45 +++++++++++++++++++++++++++++++------- 1 file changed, 37 insertions(+), 8 deletions(-) diff --git a/drivers/soc/qcom/socinfo.c b/drivers/soc/qcom/socinfo.c index 69642891ad57..af0188bd3880 100644 --- a/drivers/soc/qcom/socinfo.c +++ b/drivers/soc/qcom/socinfo.c @@ -67,7 +67,17 @@ #define SMEM_IMAGE_TABLE_GEARVM_INDEX 29 #define SMEM_IMAGE_TABLE_UEFI_INDEX 30 #define SMEM_IMAGE_TABLE_CDSP3_INDEX 31 +#define SMEM_IMAGE_TABLE_AUDIOPD_ADSP1_INDEX 32 +#define SMEM_IMAGE_TABLE_AUDIOPD_ADSP2_INDEX 33 +#define SMEM_IMAGE_TABLE_DCP_INDEX 34 +#define SMEM_IMAGE_TABLE_OOBS_INDEX 35 +#define SMEM_IMAGE_TABLE_OOBNS_INDEX 36 +#define SMEM_IMAGE_TABLE_DEVCFG_INDEX 37 +#define SMEM_IMAGE_TABLE_BTPD_INDEX 38 +#define SMEM_IMAGE_TABLE_QECP_INDEX 39 + #define SMEM_IMAGE_VERSION_TABLE 469 +#define SMEM_IMAGE_VERSION_TABLE_2 667 /* * SMEM Image table names @@ -79,13 +89,18 @@ static const char *const socinfo_image_names[] = { [SMEM_IMAGE_TABLE_APPSBL_INDEX] = "appsbl", [SMEM_IMAGE_TABLE_APPS_INDEX] = "apps", [SMEM_IMAGE_TABLE_AUDIOPD_INDEX] = "audiopd", + [SMEM_IMAGE_TABLE_AUDIOPD_ADSP1_INDEX] = "audiopd_adsp1", + [SMEM_IMAGE_TABLE_AUDIOPD_ADSP2_INDEX] = "audiopd_adsp2", [SMEM_IMAGE_TABLE_BOOT_INDEX] = "boot", + [SMEM_IMAGE_TABLE_BTPD_INDEX] = "btpd", [SMEM_IMAGE_TABLE_CDSP1_INDEX] = "cdsp1", [SMEM_IMAGE_TABLE_CDSP2_INDEX] = "cdsp2", [SMEM_IMAGE_TABLE_CDSP3_INDEX] = "cdsp3", [SMEM_IMAGE_TABLE_CDSP_INDEX] = "cdsp", [SMEM_IMAGE_TABLE_CHARGERPD_INDEX] = "chargerpd", [SMEM_IMAGE_TABLE_CNSS_INDEX] = "cnss", + [SMEM_IMAGE_TABLE_DCP_INDEX] = "dcp", + [SMEM_IMAGE_TABLE_DEVCFG_INDEX] = "devcfg", [SMEM_IMAGE_TABLE_DSPS_INDEX] = "dsps", [SMEM_IMAGE_TABLE_GEARVM_INDEX] = "gearvm", [SMEM_IMAGE_TABLE_GPDSP1_INDEX] = "gpdsp1", @@ -95,6 +110,9 @@ static const char *const socinfo_image_names[] = { [SMEM_IMAGE_TABLE_NPU_INDEX] = "npu", [SMEM_IMAGE_TABLE_OEMPD_INDEX] = "oempd", [SMEM_IMAGE_TABLE_OISPD_INDEX] = "oispd", + [SMEM_IMAGE_TABLE_OOBNS_INDEX] = "oobns", + [SMEM_IMAGE_TABLE_OOBS_INDEX] = "oobs", + [SMEM_IMAGE_TABLE_QECP_INDEX] = "qecp", [SMEM_IMAGE_TABLE_RPM_INDEX] = "rpm", [SMEM_IMAGE_TABLE_SDI_INDEX] = "sdi", [SMEM_IMAGE_TABLE_SENSORPD_INDEX] = "sensorpd", @@ -645,7 +663,7 @@ static void socinfo_debugfs_init(struct qcom_socinfo *qcom_socinfo, struct smem_image_version *versions; struct dentry *dentry; size_t size; - int i; + int i, j; unsigned int num_pmics; unsigned int pmic_array_offset; @@ -789,20 +807,31 @@ static void socinfo_debugfs_init(struct qcom_socinfo *qcom_socinfo, break; } - versions = qcom_smem_get(QCOM_SMEM_HOST_ANY, SMEM_IMAGE_VERSION_TABLE, - &size); - - for (i = 0; i < ARRAY_SIZE(socinfo_image_names); i++) { + for (i = 0, j = 0; i < ARRAY_SIZE(socinfo_image_names); i++, j++) { if (!socinfo_image_names[i]) continue; + if (i == 0) { + versions = qcom_smem_get(QCOM_SMEM_HOST_ANY, + SMEM_IMAGE_VERSION_TABLE, + &size); + } else if (i == 32) { + versions = qcom_smem_get(QCOM_SMEM_HOST_ANY, + SMEM_IMAGE_VERSION_TABLE_2, + &size); + if (IS_ERR(versions)) + break; + + j = 0; + } + dentry = debugfs_create_dir(socinfo_image_names[i], qcom_socinfo->dbg_root); - debugfs_create_file("name", 0444, dentry, &versions[i], + debugfs_create_file("name", 0444, dentry, &versions[j], &qcom_image_name_ops); - debugfs_create_file("variant", 0444, dentry, &versions[i], + debugfs_create_file("variant", 0444, dentry, &versions[j], &qcom_image_variant_ops); - debugfs_create_file("oem", 0444, dentry, &versions[i], + debugfs_create_file("oem", 0444, dentry, &versions[j], &qcom_image_oem_ops); } } From 682921ab33129ec46392b27e9dafcb206c2a08dd Mon Sep 17 00:00:00 2001 From: Jingyi Wang Date: Sun, 2 Nov 2025 23:25:07 -0800 Subject: [PATCH 075/114] dt-bindings: firmware: qcom,scm: Document SCM on Kaanapali SOC Document SCM compatible for the Qualcomm Kaanapali SoC. Reviewed-by: Eugen Hristev Acked-by: Rob Herring (Arm) Signed-off-by: Jingyi Wang Link: https://lore.kernel.org/r/20251102-knp-soc-binding-v3-2-11255ec4a535@oss.qualcomm.com Signed-off-by: Bjorn Andersson --- Documentation/devicetree/bindings/firmware/qcom,scm.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Documentation/devicetree/bindings/firmware/qcom,scm.yaml b/Documentation/devicetree/bindings/firmware/qcom,scm.yaml index 38c64c3783f8..d66459f1d84e 100644 --- a/Documentation/devicetree/bindings/firmware/qcom,scm.yaml +++ b/Documentation/devicetree/bindings/firmware/qcom,scm.yaml @@ -32,6 +32,7 @@ properties: - qcom,scm-ipq806x - qcom,scm-ipq8074 - qcom,scm-ipq9574 + - qcom,scm-kaanapali - qcom,scm-mdm9607 - qcom,scm-milos - qcom,scm-msm8226 @@ -203,6 +204,7 @@ allOf: compatible: contains: enum: + - qcom,scm-kaanapali - qcom,scm-milos - qcom,scm-sm8450 - qcom,scm-sm8550 From 3f61783920504b2cf99330b372d82914bb004d8e Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Mon, 25 Aug 2025 15:11:13 +0200 Subject: [PATCH 076/114] ti-sysc: allow OMAP2 and OMAP4 timers to be reserved on AM33xx am33xx.dtsi has the same clock setup as am35xx.dtsi, setting ti,no-reset-on-init and ti,no-idle on timer1_target and timer2_target, so AM33 needs the same workaround as AM35 to avoid ti-sysc probe failing on certain target modules. Signed-off-by: Matthias Schiffer Signed-off-by: Alexander Stein Link: https://lore.kernel.org/r/20250825131114.2206804-1-alexander.stein@ew.tq-group.com Signed-off-by: Kevin Hilman --- drivers/bus/ti-sysc.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/drivers/bus/ti-sysc.c b/drivers/bus/ti-sysc.c index 5566ad11399e..610354ce7f8f 100644 --- a/drivers/bus/ti-sysc.c +++ b/drivers/bus/ti-sysc.c @@ -48,6 +48,7 @@ enum sysc_soc { SOC_UNKNOWN, SOC_2420, SOC_2430, + SOC_AM33, SOC_3430, SOC_AM35, SOC_3630, @@ -2912,6 +2913,7 @@ static void ti_sysc_idle(struct work_struct *work) static const struct soc_device_attribute sysc_soc_match[] = { SOC_FLAG("OMAP242*", SOC_2420), SOC_FLAG("OMAP243*", SOC_2430), + SOC_FLAG("AM33*", SOC_AM33), SOC_FLAG("AM35*", SOC_AM35), SOC_FLAG("OMAP3[45]*", SOC_3430), SOC_FLAG("OMAP3[67]*", SOC_3630), @@ -3117,10 +3119,15 @@ static int sysc_check_active_timer(struct sysc *ddata) * can be dropped if we stop supporting old beagleboard revisions * A to B4 at some point. */ - if (sysc_soc->soc == SOC_3430 || sysc_soc->soc == SOC_AM35) + switch (sysc_soc->soc) { + case SOC_AM33: + case SOC_3430: + case SOC_AM35: error = -ENXIO; - else + break; + default: error = -EBUSY; + } if ((ddata->cfg.quirks & SYSC_QUIRK_NO_RESET_ON_INIT) && (ddata->cfg.quirks & SYSC_QUIRK_NO_IDLE)) From 81280d39a2f9e7dc12056db889da52cce067b1b6 Mon Sep 17 00:00:00 2001 From: Kaustabh Chakraborty Date: Fri, 31 Oct 2025 00:50:15 +0530 Subject: [PATCH 077/114] dt-bindings: soc: samsung: exynos-pmu: allow mipi-phy subnode for Exynos7870 PMU Exynos7870 PMU is already documented in schema. Add Exynos7870's PMU compatible to the list of nodes which allow a MIPI PHY driver. Signed-off-by: Kaustabh Chakraborty Acked-by: Rob Herring (Arm) Link: https://patch.msgid.link/20251031-exynos7870-drm-dts-v4-1-c1f77fb16b87@disroot.org Signed-off-by: Krzysztof Kozlowski --- Documentation/devicetree/bindings/soc/samsung/exynos-pmu.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/soc/samsung/exynos-pmu.yaml b/Documentation/devicetree/bindings/soc/samsung/exynos-pmu.yaml index be1441193fee..6de47489ee42 100644 --- a/Documentation/devicetree/bindings/soc/samsung/exynos-pmu.yaml +++ b/Documentation/devicetree/bindings/soc/samsung/exynos-pmu.yaml @@ -173,6 +173,7 @@ allOf: - samsung,exynos5250-pmu - samsung,exynos5420-pmu - samsung,exynos5433-pmu + - samsung,exynos7870-pmu then: properties: mipi-phy: true From 6a571d762cda6c25517c5533b8bd06d56028cdcb Mon Sep 17 00:00:00 2001 From: Mukesh Ojha Date: Tue, 4 Nov 2025 18:39:05 +0530 Subject: [PATCH 078/114] soc: qcom: socinfo: Add support for new fields in revision 20 Add support for socinfo version 20. Version 20 adds a new field package id and its zeroth bit contain information that can be can be used to tune temperature thresholds on devices which might be able to withstand higher temperatures. Zeroth bit value 1 means that its heat dissipation is better and more relaxed thermal scheme can be put in place and 0 means a more aggressive scheme may be needed. Reviewed-by: Konrad Dybcio Reviewed-by: Dmitry Baryshkov Signed-off-by: Mukesh Ojha Link: https://lore.kernel.org/r/20251104130906.167666-1-mukesh.ojha@oss.qualcomm.com Signed-off-by: Bjorn Andersson --- drivers/soc/qcom/socinfo.c | 6 ++++++ include/linux/soc/qcom/socinfo.h | 2 ++ 2 files changed, 8 insertions(+) diff --git a/drivers/soc/qcom/socinfo.c b/drivers/soc/qcom/socinfo.c index af0188bd3880..37567f5492fa 100644 --- a/drivers/soc/qcom/socinfo.c +++ b/drivers/soc/qcom/socinfo.c @@ -213,6 +213,7 @@ struct socinfo_params { u32 num_func_clusters; u32 boot_cluster; u32 boot_core; + u32 raw_package_type; }; struct smem_image_version { @@ -675,6 +676,11 @@ static void socinfo_debugfs_init(struct qcom_socinfo *qcom_socinfo, &qcom_socinfo->info.fmt); switch (qcom_socinfo->info.fmt) { + case SOCINFO_VERSION(0, 20): + qcom_socinfo->info.raw_package_type = __le32_to_cpu(info->raw_package_type); + debugfs_create_u32("raw_package_type", 0444, qcom_socinfo->dbg_root, + &qcom_socinfo->info.raw_package_type); + fallthrough; case SOCINFO_VERSION(0, 19): qcom_socinfo->info.num_func_clusters = __le32_to_cpu(info->num_func_clusters); qcom_socinfo->info.boot_cluster = __le32_to_cpu(info->boot_cluster); diff --git a/include/linux/soc/qcom/socinfo.h b/include/linux/soc/qcom/socinfo.h index 608950443eee..c4dae173cc30 100644 --- a/include/linux/soc/qcom/socinfo.h +++ b/include/linux/soc/qcom/socinfo.h @@ -82,6 +82,8 @@ struct socinfo { __le32 num_func_clusters; __le32 boot_cluster; __le32 boot_core; + /* Version 20 */ + __le32 raw_package_type; }; /* Internal feature codes */ From 6918667af5a7315eff3c56d871be4c5439f7f9d2 Mon Sep 17 00:00:00 2001 From: Mukesh Ojha Date: Tue, 4 Nov 2025 18:39:06 +0530 Subject: [PATCH 079/114] soc: qcom: socinfo: Add reserve field to support future extension Some of the new field added to socinfo structure with version 21, 22 and 23 which is only used by boot firmware and it is of no use for Linux.Add reserve field in socinfo so that the structure remain updated and prepared if we get any new field in future which could be used by Linux. While at it, also updates switch case for backward compatibility if the SoC runs with boot firmware which has these new version added. Signed-off-by: Mukesh Ojha Link: https://lore.kernel.org/r/20251104130906.167666-2-mukesh.ojha@oss.qualcomm.com Signed-off-by: Bjorn Andersson --- drivers/soc/qcom/socinfo.c | 3 +++ include/linux/soc/qcom/socinfo.h | 2 ++ 2 files changed, 5 insertions(+) diff --git a/drivers/soc/qcom/socinfo.c b/drivers/soc/qcom/socinfo.c index 37567f5492fa..003a2304d535 100644 --- a/drivers/soc/qcom/socinfo.c +++ b/drivers/soc/qcom/socinfo.c @@ -676,6 +676,9 @@ static void socinfo_debugfs_init(struct qcom_socinfo *qcom_socinfo, &qcom_socinfo->info.fmt); switch (qcom_socinfo->info.fmt) { + case SOCINFO_VERSION(0, 23): + case SOCINFO_VERSION(0, 22): + case SOCINFO_VERSION(0, 21): case SOCINFO_VERSION(0, 20): qcom_socinfo->info.raw_package_type = __le32_to_cpu(info->raw_package_type); debugfs_create_u32("raw_package_type", 0444, qcom_socinfo->dbg_root, diff --git a/include/linux/soc/qcom/socinfo.h b/include/linux/soc/qcom/socinfo.h index c4dae173cc30..ba823a0013c5 100644 --- a/include/linux/soc/qcom/socinfo.h +++ b/include/linux/soc/qcom/socinfo.h @@ -84,6 +84,8 @@ struct socinfo { __le32 boot_core; /* Version 20 */ __le32 raw_package_type; + /* Version 21, 22, 23 */ + __le32 reserve1[4]; }; /* Internal feature codes */ From 0cda8823b176a5303a2c4bc2366908e3049c416e Mon Sep 17 00:00:00 2001 From: Gabor Juhos Date: Tue, 11 Nov 2025 08:40:10 +0100 Subject: [PATCH 080/114] soc: qcom: mdt_loader: merge __qcom_mdt_load() and qcom_mdt_load_no_init() The qcom_mdt_load_no_init() function is just a simple wrapper around of __qcom_mdt_load(). Since commit 0daf35da397b ("soc: qcom: mdt_loader: Remove pas id parameter") both functions are using the same type of parameters and providing the same functionality. Keeping two functions for the same purpose is superfluous, so rename the __qcom_mdt_load() function to qcom_mdt_load_no_init() and remove the wrapper. No functional changes. Signed-off-by: Gabor Juhos Reviewed-by: Dmitry Baryshkov Link: https://lore.kernel.org/r/20251111-mdt-loader-cleanup-v1-1-71afee094dce@gmail.com Signed-off-by: Bjorn Andersson --- drivers/soc/qcom/mdt_loader.c | 46 +++++++++++++++-------------------- 1 file changed, 19 insertions(+), 27 deletions(-) diff --git a/drivers/soc/qcom/mdt_loader.c b/drivers/soc/qcom/mdt_loader.c index a5c80d4fcc36..a68a22d17420 100644 --- a/drivers/soc/qcom/mdt_loader.c +++ b/drivers/soc/qcom/mdt_loader.c @@ -332,10 +332,22 @@ static bool qcom_mdt_bins_are_split(const struct firmware *fw) return false; } -static int __qcom_mdt_load(struct device *dev, const struct firmware *fw, - const char *fw_name, void *mem_region, - phys_addr_t mem_phys, size_t mem_size, - phys_addr_t *reloc_base) +/** + * qcom_mdt_load_no_init() - load the firmware which header is loaded as fw + * @dev: device handle to associate resources with + * @fw: firmware object for the mdt file + * @fw_name: name of the firmware, for construction of segment file names + * @mem_region: allocated memory region to load firmware into + * @mem_phys: physical address of allocated memory region + * @mem_size: size of the allocated memory region + * @reloc_base: adjusted physical address after relocation + * + * Returns 0 on success, negative errno otherwise. + */ +int qcom_mdt_load_no_init(struct device *dev, const struct firmware *fw, + const char *fw_name, void *mem_region, + phys_addr_t mem_phys, size_t mem_size, + phys_addr_t *reloc_base) { const struct elf32_phdr *phdrs; const struct elf32_phdr *phdr; @@ -435,6 +447,7 @@ static int __qcom_mdt_load(struct device *dev, const struct firmware *fw, return ret; } +EXPORT_SYMBOL_GPL(qcom_mdt_load_no_init); /** * qcom_mdt_load() - load the firmware which header is loaded as fw @@ -460,31 +473,10 @@ int qcom_mdt_load(struct device *dev, const struct firmware *fw, if (ret) return ret; - return __qcom_mdt_load(dev, fw, firmware, mem_region, mem_phys, - mem_size, reloc_base); + return qcom_mdt_load_no_init(dev, fw, firmware, mem_region, mem_phys, + mem_size, reloc_base); } EXPORT_SYMBOL_GPL(qcom_mdt_load); -/** - * qcom_mdt_load_no_init() - load the firmware which header is loaded as fw - * @dev: device handle to associate resources with - * @fw: firmware object for the mdt file - * @firmware: name of the firmware, for construction of segment file names - * @mem_region: allocated memory region to load firmware into - * @mem_phys: physical address of allocated memory region - * @mem_size: size of the allocated memory region - * @reloc_base: adjusted physical address after relocation - * - * Returns 0 on success, negative errno otherwise. - */ -int qcom_mdt_load_no_init(struct device *dev, const struct firmware *fw, - const char *firmware, void *mem_region, phys_addr_t mem_phys, - size_t mem_size, phys_addr_t *reloc_base) -{ - return __qcom_mdt_load(dev, fw, firmware, mem_region, mem_phys, - mem_size, reloc_base); -} -EXPORT_SYMBOL_GPL(qcom_mdt_load_no_init); - MODULE_DESCRIPTION("Firmware parser for Qualcomm MDT format"); MODULE_LICENSE("GPL v2"); From 186b8f8fcc86949eaf0c3bd11a47048ec4c78b5b Mon Sep 17 00:00:00 2001 From: Gabor Juhos Date: Tue, 11 Nov 2025 08:40:11 +0100 Subject: [PATCH 081/114] soc: qcom: mdt_loader: rename 'firmware' parameter of qcom_mdt_load() In the 'mdt_loader.h' header, both the prototype and the inline version of the qcom_mdt_load() function uses 'fw_name' as name for the firmware name parameter. Additionally, the other qcom_mdt_* functions are using that as well. For consistency, rename the 'firmware' parameter in the implementation of the qcom_mdt_load() to 'fw_name' and update the function accordingly. No functional changes. Signed-off-by: Gabor Juhos Reviewed-by: Dmitry Baryshkov Link: https://lore.kernel.org/r/20251111-mdt-loader-cleanup-v1-2-71afee094dce@gmail.com Signed-off-by: Bjorn Andersson --- drivers/soc/qcom/mdt_loader.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/soc/qcom/mdt_loader.c b/drivers/soc/qcom/mdt_loader.c index a68a22d17420..c239107cb930 100644 --- a/drivers/soc/qcom/mdt_loader.c +++ b/drivers/soc/qcom/mdt_loader.c @@ -453,7 +453,7 @@ EXPORT_SYMBOL_GPL(qcom_mdt_load_no_init); * qcom_mdt_load() - load the firmware which header is loaded as fw * @dev: device handle to associate resources with * @fw: firmware object for the mdt file - * @firmware: name of the firmware, for construction of segment file names + * @fw_name: name of the firmware, for construction of segment file names * @pas_id: PAS identifier * @mem_region: allocated memory region to load firmware into * @mem_phys: physical address of allocated memory region @@ -463,17 +463,17 @@ EXPORT_SYMBOL_GPL(qcom_mdt_load_no_init); * Returns 0 on success, negative errno otherwise. */ int qcom_mdt_load(struct device *dev, const struct firmware *fw, - const char *firmware, int pas_id, void *mem_region, + const char *fw_name, int pas_id, void *mem_region, phys_addr_t mem_phys, size_t mem_size, phys_addr_t *reloc_base) { int ret; - ret = qcom_mdt_pas_init(dev, fw, firmware, pas_id, mem_phys, NULL); + ret = qcom_mdt_pas_init(dev, fw, fw_name, pas_id, mem_phys, NULL); if (ret) return ret; - return qcom_mdt_load_no_init(dev, fw, firmware, mem_region, mem_phys, + return qcom_mdt_load_no_init(dev, fw, fw_name, mem_region, mem_phys, mem_size, reloc_base); } EXPORT_SYMBOL_GPL(qcom_mdt_load); From 170a3ef6052cfa2462b3bb572a6bb985bf83d21e Mon Sep 17 00:00:00 2001 From: "Markus Schneider-Pargmann (TI.com)" Date: Mon, 3 Nov 2025 13:42:19 +0100 Subject: [PATCH 082/114] firmware: ti_sci: Support transfers without response Check the header flags if an response is expected or not. If it is not expected skip the receive part of ti_sci_do_xfer(). This prepares the driver for one-way messages as prepare_sleep for Partial-IO. Reviewed-by: Kendall Willis Signed-off-by: Markus Schneider-Pargmann (TI.com) Reviewed-by: Dhruva Gole Reviewed-by: Sebin Francis Link: https://patch.msgid.link/20251103-topic-am62-partialio-v6-12-b4-v10-1-0557e858d747@baylibre.com Signed-off-by: Nishanth Menon --- drivers/firmware/ti_sci.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/firmware/ti_sci.c b/drivers/firmware/ti_sci.c index 34df75cf42fd..c49294ca3c94 100644 --- a/drivers/firmware/ti_sci.c +++ b/drivers/firmware/ti_sci.c @@ -398,6 +398,9 @@ static void ti_sci_put_one_xfer(struct ti_sci_xfers_info *minfo, static inline int ti_sci_do_xfer(struct ti_sci_info *info, struct ti_sci_xfer *xfer) { + struct ti_sci_msg_hdr *hdr = (struct ti_sci_msg_hdr *)xfer->tx_message.buf; + bool response_expected = !!(hdr->flags & (TI_SCI_FLAG_REQ_ACK_ON_PROCESSED | + TI_SCI_FLAG_REQ_ACK_ON_RECEIVED)); int ret; int timeout; struct device *dev = info->dev; @@ -409,12 +412,12 @@ static inline int ti_sci_do_xfer(struct ti_sci_info *info, ret = 0; - if (system_state <= SYSTEM_RUNNING) { + if (response_expected && system_state <= SYSTEM_RUNNING) { /* And we wait for the response. */ timeout = msecs_to_jiffies(info->desc->max_rx_timeout_ms); if (!wait_for_completion_timeout(&xfer->done, timeout)) ret = -ETIMEDOUT; - } else { + } else if (response_expected) { /* * If we are !running, we cannot use wait_for_completion_timeout * during noirq phase, so we must manually poll the completion. From e0431ff998bd32dcc1e591a45b4e156fcb0325a3 Mon Sep 17 00:00:00 2001 From: "Markus Schneider-Pargmann (TI.com)" Date: Mon, 3 Nov 2025 13:42:20 +0100 Subject: [PATCH 083/114] firmware: ti_sci: Partial-IO support Add support for Partial-IO poweroff. In Partial-IO pins of a few hardware units can generate system wakeups while DDR memory is not powered resulting in a fresh boot of the system. These hardware units in the SoC are always powered so that some logic can detect pin activity. If the system supports Partial-IO as described in the fw capabilities, a sys_off handler is added. This sys_off handler decides if the poweroff is executed by entering normal poweroff or Partial-IO instead. The decision is made by checking if wakeup is enabled on all devices that may wake up the SoC from Partial-IO. The possible wakeup devices are found by checking which devices reference a "Partial-IO" system state in the list of wakeup-source system states. Only devices that are actually enabled by the user will be considered as an active wakeup source. If none of the wakeup sources is enabled the system will do a normal poweroff. If at least one wakeup source is enabled it will instead send a TI_SCI_MSG_PREPARE_SLEEP message from the sys_off handler. Sending this message will result in an immediate shutdown of the system. No execution is expected after this point. The code will wait for 5s and do an emergency_restart afterwards if Partial-IO wasn't entered at that point. A short documentation about Partial-IO can be found in section 6.2.4.5 of the TRM at https://www.ti.com/lit/pdf/spruiv7 Signed-off-by: Markus Schneider-Pargmann (TI.com) Reviewed-by: Dhruva Gole Reviewed-by: Kendall Willis Reviewed-by: Sebin Francis Link: https://patch.msgid.link/20251103-topic-am62-partialio-v6-12-b4-v10-2-0557e858d747@baylibre.com Signed-off-by: Nishanth Menon --- drivers/firmware/ti_sci.c | 109 +++++++++++++++++++++++++++++++++++--- drivers/firmware/ti_sci.h | 5 ++ 2 files changed, 107 insertions(+), 7 deletions(-) diff --git a/drivers/firmware/ti_sci.c b/drivers/firmware/ti_sci.c index c49294ca3c94..e027a2bd8f26 100644 --- a/drivers/firmware/ti_sci.c +++ b/drivers/firmware/ti_sci.c @@ -1673,6 +1673,9 @@ static int ti_sci_cmd_clk_get_freq(const struct ti_sci_handle *handle, static int ti_sci_cmd_prepare_sleep(const struct ti_sci_handle *handle, u8 mode, u32 ctx_lo, u32 ctx_hi, u32 debug_flags) { + u32 msg_flags = mode == TISCI_MSG_VALUE_SLEEP_MODE_PARTIAL_IO ? + TI_SCI_FLAG_REQ_GENERIC_NORESPONSE : + TI_SCI_FLAG_REQ_ACK_ON_PROCESSED; struct ti_sci_info *info; struct ti_sci_msg_req_prepare_sleep *req; struct ti_sci_msg_hdr *resp; @@ -1689,7 +1692,7 @@ static int ti_sci_cmd_prepare_sleep(const struct ti_sci_handle *handle, u8 mode, dev = info->dev; xfer = ti_sci_get_one_xfer(info, TI_SCI_MSG_PREPARE_SLEEP, - TI_SCI_FLAG_REQ_ACK_ON_PROCESSED, + msg_flags, sizeof(*req), sizeof(*resp)); if (IS_ERR(xfer)) { ret = PTR_ERR(xfer); @@ -1709,11 +1712,12 @@ static int ti_sci_cmd_prepare_sleep(const struct ti_sci_handle *handle, u8 mode, goto fail; } - resp = (struct ti_sci_msg_hdr *)xfer->xfer_buf; - - if (!ti_sci_is_response_ack(resp)) { - dev_err(dev, "Failed to prepare sleep\n"); - ret = -ENODEV; + if (msg_flags == TI_SCI_FLAG_REQ_ACK_ON_PROCESSED) { + resp = (struct ti_sci_msg_hdr *)xfer->xfer_buf; + if (!ti_sci_is_response_ack(resp)) { + dev_err(dev, "Failed to prepare sleep\n"); + ret = -ENODEV; + } } fail: @@ -3667,6 +3671,78 @@ devm_ti_sci_get_resource(const struct ti_sci_handle *handle, struct device *dev, } EXPORT_SYMBOL_GPL(devm_ti_sci_get_resource); +/* + * Iterate all device nodes that have a wakeup-source property and check if one + * of the possible phandles points to a Partial-IO system state. If it + * does resolve the device node to an actual device and check if wakeup is + * enabled. + */ +static bool ti_sci_partial_io_wakeup_enabled(struct ti_sci_info *info) +{ + struct device_node *wakeup_node = NULL; + + for_each_node_with_property(wakeup_node, "wakeup-source") { + struct of_phandle_iterator it; + int err; + + of_for_each_phandle(&it, err, wakeup_node, "wakeup-source", NULL, 0) { + struct platform_device *pdev; + bool may_wakeup; + + /* + * Continue if idle-state-name is not off-wake. Return + * value is the index of the string which should be 0 if + * off-wake is present. + */ + if (of_property_match_string(it.node, "idle-state-name", "off-wake")) + continue; + + pdev = of_find_device_by_node(wakeup_node); + if (!pdev) + continue; + + may_wakeup = device_may_wakeup(&pdev->dev); + put_device(&pdev->dev); + + if (may_wakeup) { + dev_dbg(info->dev, "%pOF identified as wakeup source for Partial-IO\n", + wakeup_node); + of_node_put(it.node); + of_node_put(wakeup_node); + return true; + } + } + } + + return false; +} + +static int ti_sci_sys_off_handler(struct sys_off_data *data) +{ + struct ti_sci_info *info = data->cb_data; + const struct ti_sci_handle *handle = &info->handle; + bool enter_partial_io = ti_sci_partial_io_wakeup_enabled(info); + int ret; + + if (!enter_partial_io) + return NOTIFY_DONE; + + dev_info(info->dev, "Entering Partial-IO because a powered wakeup-enabled device was found.\n"); + + ret = ti_sci_cmd_prepare_sleep(handle, TISCI_MSG_VALUE_SLEEP_MODE_PARTIAL_IO, 0, 0, 0); + if (ret) { + dev_err(info->dev, + "Failed to enter Partial-IO %pe, trying to do an emergency restart\n", + ERR_PTR(ret)); + emergency_restart(); + } + + mdelay(5000); + emergency_restart(); + + return NOTIFY_DONE; +} + static int tisci_reboot_handler(struct sys_off_data *data) { struct ti_sci_info *info = data->cb_data; @@ -3949,6 +4025,19 @@ static int ti_sci_probe(struct platform_device *pdev) goto out; } + if (info->fw_caps & MSG_FLAG_CAPS_LPM_PARTIAL_IO) { + ret = devm_register_sys_off_handler(dev, + SYS_OFF_MODE_POWER_OFF, + SYS_OFF_PRIO_FIRMWARE, + ti_sci_sys_off_handler, + info); + if (ret) { + dev_err(dev, "Failed to register sys_off_handler %pe\n", + ERR_PTR(ret)); + goto out; + } + } + dev_info(dev, "ABI: %d.%d (firmware rev 0x%04x '%s')\n", info->handle.version.abi_major, info->handle.version.abi_minor, info->handle.version.firmware_revision, @@ -3958,7 +4047,13 @@ static int ti_sci_probe(struct platform_device *pdev) list_add_tail(&info->node, &ti_sci_list); mutex_unlock(&ti_sci_list_mutex); - return of_platform_populate(dev->of_node, NULL, NULL, dev); + ret = of_platform_populate(dev->of_node, NULL, NULL, dev); + if (ret) { + dev_err(dev, "platform_populate failed %pe\n", ERR_PTR(ret)); + goto out; + } + return 0; + out: if (!IS_ERR(info->chan_tx)) mbox_free_channel(info->chan_tx); diff --git a/drivers/firmware/ti_sci.h b/drivers/firmware/ti_sci.h index 7559cde17b6c..91f234550c43 100644 --- a/drivers/firmware/ti_sci.h +++ b/drivers/firmware/ti_sci.h @@ -597,6 +597,11 @@ struct ti_sci_msg_resp_get_clock_freq { struct ti_sci_msg_req_prepare_sleep { struct ti_sci_msg_hdr hdr; +/* + * When sending prepare_sleep with MODE_PARTIAL_IO no response will be sent, + * no further steps are required. + */ +#define TISCI_MSG_VALUE_SLEEP_MODE_PARTIAL_IO 0x03 #define TISCI_MSG_VALUE_SLEEP_MODE_DM_MANAGED 0xfd u8 mode; u32 ctx_lo; From 4ff787433ba6d564b00334b4bfd6350f5b6f4bb3 Mon Sep 17 00:00:00 2001 From: Claudiu Beznea Date: Wed, 5 Nov 2025 09:05:25 +0200 Subject: [PATCH 084/114] soc: renesas: r9a09g056-sys: Populate max_register Populate max_register to avoid external aborts. Fixes: 2da2740fb9c8 ("soc: renesas: rz-sysc: Add syscon/regmap support") Signed-off-by: Claudiu Beznea Reviewed-by: Geert Uytterhoeven Link: https://patch.msgid.link/20251105070526.264445-2-claudiu.beznea.uj@bp.renesas.com Signed-off-by: Geert Uytterhoeven --- drivers/soc/renesas/r9a09g056-sys.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/soc/renesas/r9a09g056-sys.c b/drivers/soc/renesas/r9a09g056-sys.c index 3ad1422eba36..16b4e433c337 100644 --- a/drivers/soc/renesas/r9a09g056-sys.c +++ b/drivers/soc/renesas/r9a09g056-sys.c @@ -72,4 +72,5 @@ static const struct rz_sysc_soc_id_init_data rzv2n_sys_soc_id_init_data __initco const struct rz_sysc_init_data rzv2n_sys_init_data = { .soc_id_init_data = &rzv2n_sys_soc_id_init_data, + .max_register = 0x170c, }; From c432180a7d95081353a96fd6d5bd75b0fc8a27c3 Mon Sep 17 00:00:00 2001 From: Claudiu Beznea Date: Wed, 5 Nov 2025 09:05:26 +0200 Subject: [PATCH 085/114] soc: renesas: rz-sysc: Populate readable_reg/writeable_reg in regmap config Not all system controller registers are accessible from Linux. Accessing such registers generates synchronous external abort. Populate the readable_reg and writeable_reg members of the regmap config to inform the regmap core which registers can be accessed. The list will need to be updated whenever new system controller functionality is exported through regmap. Fixes: 2da2740fb9c8 ("soc: renesas: rz-sysc: Add syscon/regmap support") Signed-off-by: Claudiu Beznea Reviewed-by: Geert Uytterhoeven Link: https://patch.msgid.link/20251105070526.264445-3-claudiu.beznea.uj@bp.renesas.com Signed-off-by: Geert Uytterhoeven --- drivers/soc/renesas/r9a08g045-sysc.c | 69 ++++++++++++++++++ drivers/soc/renesas/r9a09g047-sys.c | 79 +++++++++++++++++++++ drivers/soc/renesas/r9a09g056-sys.c | 68 ++++++++++++++++++ drivers/soc/renesas/r9a09g057-sys.c | 101 +++++++++++++++++++++++++++ drivers/soc/renesas/rz-sysc.c | 2 + drivers/soc/renesas/rz-sysc.h | 4 ++ 6 files changed, 323 insertions(+) diff --git a/drivers/soc/renesas/r9a08g045-sysc.c b/drivers/soc/renesas/r9a08g045-sysc.c index 0504d4e68761..03d653d5cde5 100644 --- a/drivers/soc/renesas/r9a08g045-sysc.c +++ b/drivers/soc/renesas/r9a08g045-sysc.c @@ -6,10 +6,29 @@ */ #include +#include #include #include "rz-sysc.h" +#define SYS_XSPI_MAP_STAADD_CS0 0x348 +#define SYS_XSPI_MAP_ENDADD_CS0 0x34c +#define SYS_XSPI_MAP_STAADD_CS1 0x350 +#define SYS_XSPI_MAP_ENDADD_CS1 0x354 +#define SYS_GETH0_CFG 0x380 +#define SYS_GETH1_CFG 0x390 +#define SYS_PCIE_CFG 0x3a0 +#define SYS_PCIE_MON 0x3a4 +#define SYS_PCIE_ERR_MON 0x3ac +#define SYS_PCIE_PHY 0x3b4 +#define SYS_I2C0_CFG 0x400 +#define SYS_I2C1_CFG 0x410 +#define SYS_I2C2_CFG 0x420 +#define SYS_I2C3_CFG 0x430 +#define SYS_I3C_CFG 0x440 +#define SYS_USB_PWRRDY 0xd70 +#define SYS_PCIE_RST_RSM_B 0xd74 + static const struct rz_sysc_soc_id_init_data rzg3s_sysc_soc_id_init_data __initconst = { .family = "RZ/G3S", .id = 0x85e0447, @@ -18,7 +37,57 @@ static const struct rz_sysc_soc_id_init_data rzg3s_sysc_soc_id_init_data __initc .specific_id_mask = GENMASK(27, 0), }; +static bool rzg3s_regmap_readable_reg(struct device *dev, unsigned int reg) +{ + switch (reg) { + case SYS_XSPI_MAP_STAADD_CS0: + case SYS_XSPI_MAP_ENDADD_CS0: + case SYS_XSPI_MAP_STAADD_CS1: + case SYS_XSPI_MAP_ENDADD_CS1: + case SYS_GETH0_CFG: + case SYS_GETH1_CFG: + case SYS_PCIE_CFG: + case SYS_PCIE_MON: + case SYS_PCIE_ERR_MON: + case SYS_PCIE_PHY: + case SYS_I2C0_CFG: + case SYS_I2C1_CFG: + case SYS_I2C2_CFG: + case SYS_I2C3_CFG: + case SYS_I3C_CFG: + case SYS_USB_PWRRDY: + case SYS_PCIE_RST_RSM_B: + return true; + default: + return false; + } +} + +static bool rzg3s_regmap_writeable_reg(struct device *dev, unsigned int reg) +{ + switch (reg) { + case SYS_XSPI_MAP_STAADD_CS0: + case SYS_XSPI_MAP_ENDADD_CS0: + case SYS_XSPI_MAP_STAADD_CS1: + case SYS_XSPI_MAP_ENDADD_CS1: + case SYS_PCIE_CFG: + case SYS_PCIE_PHY: + case SYS_I2C0_CFG: + case SYS_I2C1_CFG: + case SYS_I2C2_CFG: + case SYS_I2C3_CFG: + case SYS_I3C_CFG: + case SYS_USB_PWRRDY: + case SYS_PCIE_RST_RSM_B: + return true; + default: + return false; + } +} + const struct rz_sysc_init_data rzg3s_sysc_init_data __initconst = { .soc_id_init_data = &rzg3s_sysc_soc_id_init_data, + .readable_reg = rzg3s_regmap_readable_reg, + .writeable_reg = rzg3s_regmap_writeable_reg, .max_register = 0xe20, }; diff --git a/drivers/soc/renesas/r9a09g047-sys.c b/drivers/soc/renesas/r9a09g047-sys.c index 2e8426c03050..e413b0eff9bf 100644 --- a/drivers/soc/renesas/r9a09g047-sys.c +++ b/drivers/soc/renesas/r9a09g047-sys.c @@ -29,6 +29,27 @@ #define SYS_LSI_PRR_CA55_DIS BIT(8) #define SYS_LSI_PRR_NPU_DIS BIT(1) +#define SYS_LSI_OTPTSU1TRMVAL0 0x330 +#define SYS_LSI_OTPTSU1TRMVAL1 0x334 +#define SYS_SPI_STAADDCS0 0x900 +#define SYS_SPI_ENDADDCS0 0x904 +#define SYS_SPI_STAADDCS1 0x908 +#define SYS_SPI_ENDADDCS1 0x90c +#define SYS_VSP_CLK 0xe00 +#define SYS_GBETH0_CFG 0xf00 +#define SYS_GBETH1_CFG 0xf04 +#define SYS_PCIE_INTX_CH0 0x1000 +#define SYS_PCIE_MSI1_CH0 0x1004 +#define SYS_PCIE_MSI2_CH0 0x1008 +#define SYS_PCIE_MSI3_CH0 0x100c +#define SYS_PCIE_MSI4_CH0 0x1010 +#define SYS_PCIE_MSI5_CH0 0x1014 +#define SYS_PCIE_PME_CH0 0x1018 +#define SYS_PCIE_ACK_CH0 0x101c +#define SYS_PCIE_MISC_CH0 0x1020 +#define SYS_PCIE_MODE_CH0 0x1024 +#define SYS_ADC_CFG 0x1600 + static void rzg3e_sys_print_id(struct device *dev, void __iomem *sysc_base, struct soc_device_attribute *soc_dev_attr) @@ -62,7 +83,65 @@ static const struct rz_sysc_soc_id_init_data rzg3e_sys_soc_id_init_data __initco .print_id = rzg3e_sys_print_id, }; +static bool rzg3e_regmap_readable_reg(struct device *dev, unsigned int reg) +{ + switch (reg) { + case SYS_LSI_OTPTSU1TRMVAL0: + case SYS_LSI_OTPTSU1TRMVAL1: + case SYS_SPI_STAADDCS0: + case SYS_SPI_ENDADDCS0: + case SYS_SPI_STAADDCS1: + case SYS_SPI_ENDADDCS1: + case SYS_VSP_CLK: + case SYS_GBETH0_CFG: + case SYS_GBETH1_CFG: + case SYS_PCIE_INTX_CH0: + case SYS_PCIE_MSI1_CH0: + case SYS_PCIE_MSI2_CH0: + case SYS_PCIE_MSI3_CH0: + case SYS_PCIE_MSI4_CH0: + case SYS_PCIE_MSI5_CH0: + case SYS_PCIE_PME_CH0: + case SYS_PCIE_ACK_CH0: + case SYS_PCIE_MISC_CH0: + case SYS_PCIE_MODE_CH0: + case SYS_ADC_CFG: + return true; + default: + return false; + } +} + +static bool rzg3e_regmap_writeable_reg(struct device *dev, unsigned int reg) +{ + switch (reg) { + case SYS_SPI_STAADDCS0: + case SYS_SPI_ENDADDCS0: + case SYS_SPI_STAADDCS1: + case SYS_SPI_ENDADDCS1: + case SYS_VSP_CLK: + case SYS_GBETH0_CFG: + case SYS_GBETH1_CFG: + case SYS_PCIE_INTX_CH0: + case SYS_PCIE_MSI1_CH0: + case SYS_PCIE_MSI2_CH0: + case SYS_PCIE_MSI3_CH0: + case SYS_PCIE_MSI4_CH0: + case SYS_PCIE_MSI5_CH0: + case SYS_PCIE_PME_CH0: + case SYS_PCIE_ACK_CH0: + case SYS_PCIE_MISC_CH0: + case SYS_PCIE_MODE_CH0: + case SYS_ADC_CFG: + return true; + default: + return false; + } +} + const struct rz_sysc_init_data rzg3e_sys_init_data = { .soc_id_init_data = &rzg3e_sys_soc_id_init_data, + .readable_reg = rzg3e_regmap_readable_reg, + .writeable_reg = rzg3e_regmap_writeable_reg, .max_register = 0x170c, }; diff --git a/drivers/soc/renesas/r9a09g056-sys.c b/drivers/soc/renesas/r9a09g056-sys.c index 16b4e433c337..42f5eff291fd 100644 --- a/drivers/soc/renesas/r9a09g056-sys.c +++ b/drivers/soc/renesas/r9a09g056-sys.c @@ -34,6 +34,24 @@ #define SYS_RZV2N_FEATURE_C55 BIT(1) #define SYS_RZV2N_FEATURE_SEC BIT(2) +#define SYS_LSI_OTPTSU0TRMVAL0 0x320 +#define SYS_LSI_OTPTSU0TRMVAL1 0x324 +#define SYS_LSI_OTPTSU1TRMVAL0 0x330 +#define SYS_LSI_OTPTSU1TRMVAL1 0x334 +#define SYS_GBETH0_CFG 0xf00 +#define SYS_GBETH1_CFG 0xf04 +#define SYS_PCIE_INTX_CH0 0x1000 +#define SYS_PCIE_MSI1_CH0 0x1004 +#define SYS_PCIE_MSI2_CH0 0x1008 +#define SYS_PCIE_MSI3_CH0 0x100c +#define SYS_PCIE_MSI4_CH0 0x1010 +#define SYS_PCIE_MSI5_CH0 0x1014 +#define SYS_PCIE_PME_CH0 0x1018 +#define SYS_PCIE_ACK_CH0 0x101c +#define SYS_PCIE_MISC_CH0 0x1020 +#define SYS_PCIE_MODE_CH0 0x1024 +#define SYS_ADC_CFG 0x1600 + static void rzv2n_sys_print_id(struct device *dev, void __iomem *sysc_base, struct soc_device_attribute *soc_dev_attr) @@ -70,7 +88,57 @@ static const struct rz_sysc_soc_id_init_data rzv2n_sys_soc_id_init_data __initco .print_id = rzv2n_sys_print_id, }; +static bool rzv2n_regmap_readable_reg(struct device *dev, unsigned int reg) +{ + switch (reg) { + case SYS_LSI_OTPTSU0TRMVAL0: + case SYS_LSI_OTPTSU0TRMVAL1: + case SYS_LSI_OTPTSU1TRMVAL0: + case SYS_LSI_OTPTSU1TRMVAL1: + case SYS_GBETH0_CFG: + case SYS_GBETH1_CFG: + case SYS_PCIE_INTX_CH0: + case SYS_PCIE_MSI1_CH0: + case SYS_PCIE_MSI2_CH0: + case SYS_PCIE_MSI3_CH0: + case SYS_PCIE_MSI4_CH0: + case SYS_PCIE_MSI5_CH0: + case SYS_PCIE_PME_CH0: + case SYS_PCIE_ACK_CH0: + case SYS_PCIE_MISC_CH0: + case SYS_PCIE_MODE_CH0: + case SYS_ADC_CFG: + return true; + default: + return false; + } +} + +static bool rzv2n_regmap_writeable_reg(struct device *dev, unsigned int reg) +{ + switch (reg) { + case SYS_GBETH0_CFG: + case SYS_GBETH1_CFG: + case SYS_PCIE_INTX_CH0: + case SYS_PCIE_MSI1_CH0: + case SYS_PCIE_MSI2_CH0: + case SYS_PCIE_MSI3_CH0: + case SYS_PCIE_MSI4_CH0: + case SYS_PCIE_MSI5_CH0: + case SYS_PCIE_PME_CH0: + case SYS_PCIE_ACK_CH0: + case SYS_PCIE_MISC_CH0: + case SYS_PCIE_MODE_CH0: + case SYS_ADC_CFG: + return true; + default: + return false; + } +} + const struct rz_sysc_init_data rzv2n_sys_init_data = { .soc_id_init_data = &rzv2n_sys_soc_id_init_data, + .readable_reg = rzv2n_regmap_readable_reg, + .writeable_reg = rzv2n_regmap_writeable_reg, .max_register = 0x170c, }; diff --git a/drivers/soc/renesas/r9a09g057-sys.c b/drivers/soc/renesas/r9a09g057-sys.c index e3390e7c7fe5..827c718ac7c5 100644 --- a/drivers/soc/renesas/r9a09g057-sys.c +++ b/drivers/soc/renesas/r9a09g057-sys.c @@ -29,6 +29,35 @@ #define SYS_LSI_PRR_GPU_DIS BIT(0) #define SYS_LSI_PRR_ISP_DIS BIT(4) +#define SYS_LSI_OTPTSU0TRMVAL0 0x320 +#define SYS_LSI_OTPTSU0TRMVAL1 0x324 +#define SYS_LSI_OTPTSU1TRMVAL0 0x330 +#define SYS_LSI_OTPTSU1TRMVAL1 0x334 +#define SYS_GBETH0_CFG 0xf00 +#define SYS_GBETH1_CFG 0xf04 +#define SYS_PCIE_INTX_CH0 0x1000 +#define SYS_PCIE_MSI1_CH0 0x1004 +#define SYS_PCIE_MSI2_CH0 0x1008 +#define SYS_PCIE_MSI3_CH0 0x100c +#define SYS_PCIE_MSI4_CH0 0x1010 +#define SYS_PCIE_MSI5_CH0 0x1014 +#define SYS_PCIE_PME_CH0 0x1018 +#define SYS_PCIE_ACK_CH0 0x101c +#define SYS_PCIE_MISC_CH0 0x1020 +#define SYS_PCIE_MODE_CH0 0x1024 +#define SYS_PCIE_INTX_CH1 0x1030 +#define SYS_PCIE_MSI1_CH1 0x1034 +#define SYS_PCIE_MSI2_CH1 0x1038 +#define SYS_PCIE_MSI3_CH1 0x103c +#define SYS_PCIE_MSI4_CH1 0x1040 +#define SYS_PCIE_MSI5_CH1 0x1044 +#define SYS_PCIE_PME_CH1 0x1048 +#define SYS_PCIE_ACK_CH1 0x104c +#define SYS_PCIE_MISC_CH1 0x1050 +#define SYS_PCIE_MODE_CH1 0x1054 +#define SYS_PCIE_MODE 0x1060 +#define SYS_ADC_CFG 0x1600 + static void rzv2h_sys_print_id(struct device *dev, void __iomem *sysc_base, struct soc_device_attribute *soc_dev_attr) @@ -62,7 +91,79 @@ static const struct rz_sysc_soc_id_init_data rzv2h_sys_soc_id_init_data __initco .print_id = rzv2h_sys_print_id, }; +static bool rzv2h_regmap_readable_reg(struct device *dev, unsigned int reg) +{ + switch (reg) { + case SYS_LSI_OTPTSU0TRMVAL0: + case SYS_LSI_OTPTSU0TRMVAL1: + case SYS_LSI_OTPTSU1TRMVAL0: + case SYS_LSI_OTPTSU1TRMVAL1: + case SYS_GBETH0_CFG: + case SYS_GBETH1_CFG: + case SYS_PCIE_INTX_CH0: + case SYS_PCIE_MSI1_CH0: + case SYS_PCIE_MSI2_CH0: + case SYS_PCIE_MSI3_CH0: + case SYS_PCIE_MSI4_CH0: + case SYS_PCIE_MSI5_CH0: + case SYS_PCIE_PME_CH0: + case SYS_PCIE_ACK_CH0: + case SYS_PCIE_MISC_CH0: + case SYS_PCIE_MODE_CH0: + case SYS_PCIE_INTX_CH1: + case SYS_PCIE_MSI1_CH1: + case SYS_PCIE_MSI2_CH1: + case SYS_PCIE_MSI3_CH1: + case SYS_PCIE_MSI4_CH1: + case SYS_PCIE_MSI5_CH1: + case SYS_PCIE_PME_CH1: + case SYS_PCIE_ACK_CH1: + case SYS_PCIE_MISC_CH1: + case SYS_PCIE_MODE_CH1: + case SYS_PCIE_MODE: + case SYS_ADC_CFG: + return true; + default: + return false; + } +} + +static bool rzv2h_regmap_writeable_reg(struct device *dev, unsigned int reg) +{ + switch (reg) { + case SYS_GBETH0_CFG: + case SYS_GBETH1_CFG: + case SYS_PCIE_INTX_CH0: + case SYS_PCIE_MSI1_CH0: + case SYS_PCIE_MSI2_CH0: + case SYS_PCIE_MSI3_CH0: + case SYS_PCIE_MSI4_CH0: + case SYS_PCIE_MSI5_CH0: + case SYS_PCIE_PME_CH0: + case SYS_PCIE_ACK_CH0: + case SYS_PCIE_MISC_CH0: + case SYS_PCIE_MODE_CH0: + case SYS_PCIE_INTX_CH1: + case SYS_PCIE_MSI1_CH1: + case SYS_PCIE_MSI2_CH1: + case SYS_PCIE_MSI3_CH1: + case SYS_PCIE_MSI4_CH1: + case SYS_PCIE_MSI5_CH1: + case SYS_PCIE_PME_CH1: + case SYS_PCIE_ACK_CH1: + case SYS_PCIE_MISC_CH1: + case SYS_PCIE_MODE_CH1: + case SYS_PCIE_MODE: + case SYS_ADC_CFG: + return true; + default: + return false; + } +} + const struct rz_sysc_init_data rzv2h_sys_init_data = { .soc_id_init_data = &rzv2h_sys_soc_id_init_data, + .readable_reg = rzv2h_regmap_readable_reg, + .writeable_reg = rzv2h_regmap_writeable_reg, .max_register = 0x170c, }; diff --git a/drivers/soc/renesas/rz-sysc.c b/drivers/soc/renesas/rz-sysc.c index 9f79e299e6f4..19c1e666279b 100644 --- a/drivers/soc/renesas/rz-sysc.c +++ b/drivers/soc/renesas/rz-sysc.c @@ -140,6 +140,8 @@ static int rz_sysc_probe(struct platform_device *pdev) regmap_cfg->val_bits = 32; regmap_cfg->fast_io = true; regmap_cfg->max_register = data->max_register; + regmap_cfg->readable_reg = data->readable_reg; + regmap_cfg->writeable_reg = data->writeable_reg; regmap = devm_regmap_init_mmio(dev, sysc->base, regmap_cfg); if (IS_ERR(regmap)) diff --git a/drivers/soc/renesas/rz-sysc.h b/drivers/soc/renesas/rz-sysc.h index 8eec355d5d56..88929bf21cb1 100644 --- a/drivers/soc/renesas/rz-sysc.h +++ b/drivers/soc/renesas/rz-sysc.h @@ -34,10 +34,14 @@ struct rz_sysc_soc_id_init_data { /** * struct rz_sysc_init_data - RZ SYSC initialization data * @soc_id_init_data: RZ SYSC SoC ID initialization data + * @writeable_reg: Regmap writeable register check function + * @readable_reg: Regmap readable register check function * @max_register: Maximum SYSC register offset to be used by the regmap config */ struct rz_sysc_init_data { const struct rz_sysc_soc_id_init_data *soc_id_init_data; + bool (*writeable_reg)(struct device *dev, unsigned int reg); + bool (*readable_reg)(struct device *dev, unsigned int reg); u32 max_register; }; From d50807fee6aced4d82e14fd7894ad5ed8db438b1 Mon Sep 17 00:00:00 2001 From: Gatien Chevallier Date: Thu, 6 Nov 2025 10:31:48 +0100 Subject: [PATCH 086/114] dt-bindings: bus: add stm32mp21 RIFSC compatible The STM32MP21x platforms have a slightly different RIFSC. While its core functionalities are similar, the wiring is not the same. Hence, declare a new compatible. Signed-off-by: Gatien Chevallier Acked-by: Conor Dooley Link: https://lore.kernel.org/r/20251106-rifsc_debugfs-v2-1-f90e94ae756d@foss.st.com Signed-off-by: Alexandre Torgue --- .../devicetree/bindings/bus/st,stm32mp25-rifsc.yaml | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/bus/st,stm32mp25-rifsc.yaml b/Documentation/devicetree/bindings/bus/st,stm32mp25-rifsc.yaml index 20acd1a6b173..3952c99cac6b 100644 --- a/Documentation/devicetree/bindings/bus/st,stm32mp25-rifsc.yaml +++ b/Documentation/devicetree/bindings/bus/st,stm32mp25-rifsc.yaml @@ -33,14 +33,18 @@ select: properties: compatible: contains: - const: st,stm32mp25-rifsc + enum: + - st,stm32mp21-rifsc + - st,stm32mp25-rifsc required: - compatible properties: compatible: items: - - const: st,stm32mp25-rifsc + - enum: + - st,stm32mp21-rifsc + - st,stm32mp25-rifsc - const: simple-bus reg: From 3bae4748c1cdd51f5d25b6c2fcf5a5634ab686f1 Mon Sep 17 00:00:00 2001 From: Gatien Chevallier Date: Thu, 6 Nov 2025 10:31:50 +0100 Subject: [PATCH 087/114] bus: rifsc: add debugfs entry to dump the firewall configuration RIFSC configuration can be difficult to debug. Add a debugfs entry that dumps the configuration of the RISUPs, the RISALs and the RIMUs. This will allow to display the whole RIFSC firewall configuration at runtime. While there, fix a bug on the computation of firewall entries in the probe function. Signed-off-by: Gatien Chevallier Link: https://lore.kernel.org/r/20251106-rifsc_debugfs-v2-3-f90e94ae756d@foss.st.com Signed-off-by: Alexandre Torgue --- drivers/bus/stm32_rifsc.c | 597 +++++++++++++++++++++++++++++++++++++- 1 file changed, 593 insertions(+), 4 deletions(-) diff --git a/drivers/bus/stm32_rifsc.c b/drivers/bus/stm32_rifsc.c index 4cf1b60014b7..debeaf8ea1bd 100644 --- a/drivers/bus/stm32_rifsc.c +++ b/drivers/bus/stm32_rifsc.c @@ -5,6 +5,7 @@ #include #include +#include #include #include #include @@ -25,6 +26,8 @@ #define RIFSC_RISC_PRIVCFGR0 0x30 #define RIFSC_RISC_PER0_CIDCFGR 0x100 #define RIFSC_RISC_PER0_SEMCR 0x104 +#define RIFSC_RISC_REG0_ACFGR 0x900 +#define RIFSC_RISC_REG3_AADDR 0x924 #define RIFSC_RISC_HWCFGR2 0xFEC /* @@ -70,6 +73,565 @@ #define RIF_CID0 0x0 #define RIF_CID1 0x1 +#if defined(CONFIG_DEBUG_FS) +#define RIFSC_RISUP_ENTRIES 128 +#define RIFSC_RIMU_ENTRIES 16 +#define RIFSC_RISAL_SUBREGIONS 2 +#define RIFSC_RISAL_GRANULARITY 8 + +#define RIFSC_RIMC_ATTR0 0xC10 + +#define RIFSC_RIMC_CIDSEL BIT(2) +#define RIFSC_RIMC_MCID_MASK GENMASK(6, 4) +#define RIFSC_RIMC_MSEC BIT(8) +#define RIFSC_RIMC_MPRIV BIT(9) + +#define RIFSC_RISC_SRCID_MASK GENMASK(6, 4) +#define RIFSC_RISC_SRPRIV BIT(9) +#define RIFSC_RISC_SRSEC BIT(8) +#define RIFSC_RISC_SRRLOCK BIT(1) +#define RIFSC_RISC_SREN BIT(0) +#define RIFSC_RISC_SRLENGTH_MASK GENMASK(27, 16) +#define RIFSC_RISC_SRSTART_MASK GENMASK(10, 0) + +static const char *stm32mp21_rifsc_rimu_names[RIFSC_RIMU_ENTRIES] = { + "ETR", + "SDMMC1", + "SDMMC2", + "SDMMC3", + "OTG_HS", + "USBH", + "ETH1", + "ETH2", + "RESERVED", + "RESERVED", + "DCMIPP", + "LTDC_L1/L2", + "LTDC_L3", + "RESERVED", + "RESERVED", + "RESERVED", +}; + +static const char *stm32mp25_rifsc_rimu_names[RIFSC_RIMU_ENTRIES] = { + "ETR", + "SDMMC1", + "SDMMC2", + "SDMMC3", + "USB3DR", + "USBH", + "ETH1", + "ETH2", + "PCIE", + "GPU", + "DMCIPP", + "LTDC_L0/L1", + "LTDC_L2", + "LTDC_ROT", + "VDEC", + "VENC" +}; + +static const char *stm32mp21_rifsc_risup_names[RIFSC_RISUP_ENTRIES] = { + "TIM1", + "TIM2", + "TIM3", + "TIM4", + "TIM5", + "TIM6", + "TIM7", + "TIM8", + "TIM10", + "TIM11", + "TIM12", + "TIM13", + "TIM14", + "TIM15", + "TIM16", + "TIM17", + "RESERVED", + "LPTIM1", + "LPTIM2", + "LPTIM3", + "LPTIM4", + "LPTIM5", + "SPI1", + "SPI2", + "SPI3", + "SPI4", + "SPI5", + "SPI6", + "RESERVED", + "RESERVED", + "SPDIFRX", + "USART1", + "USART2", + "USART3", + "UART4", + "UART5", + "USART6", + "UART7", + "RESERVED", + "RESERVED", + "LPUART1", + "I2C1", + "I2C2", + "I2C3", + "RESERVED", + "RESERVED", + "RESERVED", + "RESERVED", + "RESERVED", + "SAI1", + "SAI2", + "SAI3", + "SAI4", + "RESERVED", + "MDF1", + "RESERVED", + "FDCAN", + "HDP", + "ADC1", + "ADC2", + "ETH1", + "ETH2", + "RESERVED", + "USBH", + "RESERVED", + "RESERVED", + "OTG_HS", + "DDRPERFM", + "RESERVED", + "RESERVED", + "RESERVED", + "RESERVED", + "RESERVED", + "STGEN", + "OCTOSPI1", + "RESERVED", + "SDMMC1", + "SDMMC2", + "SDMMC3", + "RESERVED", + "LTDC_CMN", + "RESERVED", + "RESERVED", + "RESERVED", + "RESERVED", + "RESERVED", + "CSI", + "DCMIPP", + "DCMI_PSSI", + "RESERVED", + "RESERVED", + "RESERVED", + "RNG1", + "RNG2", + "PKA", + "SAES", + "HASH1", + "HASH2", + "CRYP1", + "CRYP2", + "IWDG1", + "IWDG2", + "IWDG3", + "IWDG4", + "WWDG1", + "RESERVED", + "VREFBUF", + "DTS", + "RAMCFG", + "CRC", + "SERC", + "RESERVED", + "RESERVED", + "RESERVED", + "I3C1", + "I3C2", + "I3C3", + "RESERVED", + "ICACHE_DCACHE", + "LTDC_L1L2", + "LTDC_L3", + "RESERVED", + "RESERVED", + "RESERVED", + "RESERVED", + "OTFDEC1", + "RESERVED", + "IAC", +}; + +static const char *stm32mp25_rifsc_risup_names[RIFSC_RISUP_ENTRIES] = { + "TIM1", + "TIM2", + "TIM3", + "TIM4", + "TIM5", + "TIM6", + "TIM7", + "TIM8", + "TIM10", + "TIM11", + "TIM12", + "TIM13", + "TIM14", + "TIM15", + "TIM16", + "TIM17", + "TIM20", + "LPTIM1", + "LPTIM2", + "LPTIM3", + "LPTIM4", + "LPTIM5", + "SPI1", + "SPI2", + "SPI3", + "SPI4", + "SPI5", + "SPI6", + "SPI7", + "SPI8", + "SPDIFRX", + "USART1", + "USART2", + "USART3", + "UART4", + "UART5", + "USART6", + "UART7", + "UART8", + "UART9", + "LPUART1", + "I2C1", + "I2C2", + "I2C3", + "I2C4", + "I2C5", + "I2C6", + "I2C7", + "I2C8", + "SAI1", + "SAI2", + "SAI3", + "SAI4", + "RESERVED", + "MDF1", + "ADF1", + "FDCAN", + "HDP", + "ADC12", + "ADC3", + "ETH1", + "ETH2", + "RESERVED", + "USBH", + "RESERVED", + "RESERVED", + "USB3DR", + "COMBOPHY", + "PCIE", + "UCPD1", + "ETHSW_DEIP", + "ETHSW_ACM_CF", + "ETHSW_ACM_MSGBU", + "STGEN", + "OCTOSPI1", + "OCTOSPI2", + "SDMMC1", + "SDMMC2", + "SDMMC3", + "GPU", + "LTDC_CMN", + "DSI_CMN", + "RESERVED", + "RESERVED", + "LVDS", + "RESERVED", + "CSI", + "DCMIPP", + "DCMI_PSSI", + "VDEC", + "VENC", + "RESERVED", + "RNG", + "PKA", + "SAES", + "HASH", + "CRYP1", + "CRYP2", + "IWDG1", + "IWDG2", + "IWDG3", + "IWDG4", + "IWDG5", + "WWDG1", + "WWDG2", + "RESERVED", + "VREFBUF", + "DTS", + "RAMCFG", + "CRC", + "SERC", + "OCTOSPIM", + "GICV2M", + "RESERVED", + "I3C1", + "I3C2", + "I3C3", + "I3C4", + "ICACHE_DCACHE", + "LTDC_L0L1", + "LTDC_L2", + "LTDC_ROT", + "DSI_TRIG", + "DSI_RDFIFO", + "RESERVED", + "OTFDEC1", + "OTFDEC2", + "IAC", +}; +struct rifsc_risup_debug_data { + char dev_name[15]; + u8 dev_cid; + u8 dev_sem_cids; + u8 dev_id; + bool dev_cid_filt_en; + bool dev_sem_en; + bool dev_priv; + bool dev_sec; +}; + +struct rifsc_rimu_debug_data { + char m_name[11]; + u8 m_cid; + bool cidsel; + bool m_sec; + bool m_priv; +}; + +struct rifsc_subreg_debug_data { + bool sr_sec; + bool sr_priv; + u8 sr_cid; + bool sr_rlock; + bool sr_enable; + u16 sr_start; + u16 sr_length; +}; + +struct stm32_rifsc_resources_names { + const char **device_names; + const char **initiator_names; +}; +struct rifsc_dbg_private { + const struct stm32_rifsc_resources_names *res_names; + void __iomem *mmio; + unsigned int nb_risup; + unsigned int nb_rimu; + unsigned int nb_risal; +}; + +static const struct stm32_rifsc_resources_names rifsc_mp21_res_names = { + .device_names = stm32mp21_rifsc_risup_names, + .initiator_names = stm32mp21_rifsc_rimu_names, +}; + +static const struct stm32_rifsc_resources_names rifsc_mp25_res_names = { + .device_names = stm32mp25_rifsc_risup_names, + .initiator_names = stm32mp25_rifsc_rimu_names, +}; + +static void stm32_rifsc_fill_rimu_dbg_entry(struct rifsc_dbg_private *rifsc, + struct rifsc_rimu_debug_data *dbg_entry, int i) +{ + const struct stm32_rifsc_resources_names *dbg_names = rifsc->res_names; + u32 rimc_attr = readl_relaxed(rifsc->mmio + RIFSC_RIMC_ATTR0 + 0x4 * i); + + snprintf(dbg_entry->m_name, sizeof(dbg_entry->m_name), "%s", dbg_names->initiator_names[i]); + dbg_entry->m_cid = FIELD_GET(RIFSC_RIMC_MCID_MASK, rimc_attr); + dbg_entry->cidsel = rimc_attr & RIFSC_RIMC_CIDSEL; + dbg_entry->m_sec = rimc_attr & RIFSC_RIMC_MSEC; + dbg_entry->m_priv = rimc_attr & RIFSC_RIMC_MPRIV; +} + +static void stm32_rifsc_fill_dev_dbg_entry(struct rifsc_dbg_private *rifsc, + struct rifsc_risup_debug_data *dbg_entry, int i) +{ + const struct stm32_rifsc_resources_names *dbg_names = rifsc->res_names; + u32 cid_cfgr, sec_cfgr, priv_cfgr; + u8 reg_id = i / IDS_PER_RISC_SEC_PRIV_REGS; + u8 reg_offset = i % IDS_PER_RISC_SEC_PRIV_REGS; + + cid_cfgr = readl_relaxed(rifsc->mmio + RIFSC_RISC_PER0_CIDCFGR + 0x8 * i); + sec_cfgr = readl_relaxed(rifsc->mmio + RIFSC_RISC_SECCFGR0 + 0x4 * reg_id); + priv_cfgr = readl_relaxed(rifsc->mmio + RIFSC_RISC_PRIVCFGR0 + 0x4 * reg_id); + + snprintf(dbg_entry->dev_name, sizeof(dbg_entry->dev_name), "%s", + dbg_names->device_names[i]); + dbg_entry->dev_id = i; + dbg_entry->dev_cid_filt_en = cid_cfgr & CIDCFGR_CFEN; + dbg_entry->dev_sem_en = cid_cfgr & CIDCFGR_SEMEN; + dbg_entry->dev_cid = FIELD_GET(RIFSC_RISC_SCID_MASK, cid_cfgr); + dbg_entry->dev_sem_cids = FIELD_GET(RIFSC_RISC_SEMWL_MASK, cid_cfgr); + dbg_entry->dev_sec = sec_cfgr & BIT(reg_offset) ? true : false; + dbg_entry->dev_priv = priv_cfgr & BIT(reg_offset) ? true : false; +} + + +static void stm32_rifsc_fill_subreg_dbg_entry(struct rifsc_dbg_private *rifsc, + struct rifsc_subreg_debug_data *dbg_entry, int i, + int j) +{ + u32 risc_xcfgr = readl_relaxed(rifsc->mmio + RIFSC_RISC_REG0_ACFGR + 0x10 * i + 0x8 * j); + u32 risc_xaddr; + + dbg_entry->sr_sec = risc_xcfgr & RIFSC_RISC_SRSEC; + dbg_entry->sr_priv = risc_xcfgr & RIFSC_RISC_SRPRIV; + dbg_entry->sr_cid = FIELD_GET(RIFSC_RISC_SRCID_MASK, risc_xcfgr); + dbg_entry->sr_rlock = risc_xcfgr & RIFSC_RISC_SRRLOCK; + dbg_entry->sr_enable = risc_xcfgr & RIFSC_RISC_SREN; + if (i == 2) { + risc_xaddr = readl_relaxed(rifsc->mmio + RIFSC_RISC_REG3_AADDR + 0x8 * j); + dbg_entry->sr_length = FIELD_GET(RIFSC_RISC_SRLENGTH_MASK, risc_xaddr); + dbg_entry->sr_start = FIELD_GET(RIFSC_RISC_SRSTART_MASK, risc_xaddr); + } else { + dbg_entry->sr_start = 0; + dbg_entry->sr_length = U16_MAX; + } +} + +static int stm32_rifsc_conf_dump_show(struct seq_file *s, void *data) +{ + struct rifsc_dbg_private *rifsc = (struct rifsc_dbg_private *)s->private; + int i, j; + + seq_puts(s, "\n=============================================\n"); + seq_puts(s, " RIFSC dump\n"); + seq_puts(s, "=============================================\n\n"); + + seq_puts(s, "\n=============================================\n"); + seq_puts(s, " RISUP dump\n"); + seq_puts(s, "=============================================\n"); + + seq_printf(s, "\n| %-15s |", "Peripheral name"); + seq_puts(s, "| Firewall ID |"); + seq_puts(s, "| N/SECURE |"); + seq_puts(s, "| N/PRIVILEGED |"); + seq_puts(s, "| CID filtering |"); + seq_puts(s, "| Semaphore mode |"); + seq_puts(s, "| SCID |"); + seq_printf(s, "| %7s |\n", "SEMWL"); + + for (i = 0; i < RIFSC_RISUP_ENTRIES && i < rifsc->nb_risup; i++) { + struct rifsc_risup_debug_data d_dbg_entry; + + stm32_rifsc_fill_dev_dbg_entry(rifsc, &d_dbg_entry, i); + + seq_printf(s, "| %-15s |", d_dbg_entry.dev_name); + seq_printf(s, "| %-11d |", d_dbg_entry.dev_id); + seq_printf(s, "| %-8s |", d_dbg_entry.dev_sec ? "SEC" : "NSEC"); + seq_printf(s, "| %-12s |", d_dbg_entry.dev_priv ? "PRIV" : "NPRIV"); + seq_printf(s, "| %-13s |", str_enabled_disabled(d_dbg_entry.dev_cid_filt_en)); + seq_printf(s, "| %-14s |", str_enabled_disabled(d_dbg_entry.dev_sem_en)); + seq_printf(s, "| %-4d |", d_dbg_entry.dev_cid); + seq_printf(s, "| %#-7x |\n", d_dbg_entry.dev_sem_cids); + } + + seq_puts(s, "\n=============================================\n"); + seq_puts(s, " RIMU dump\n"); + seq_puts(s, "=============================================\n"); + + seq_puts(s, "| RIMU's name |"); + seq_puts(s, "| CIDSEL |"); + seq_puts(s, "| MCID |"); + seq_puts(s, "| N/SECURE |"); + seq_puts(s, "| N/PRIVILEGED |\n"); + + for (i = 0; i < RIFSC_RIMU_ENTRIES && rifsc->nb_rimu; i++) { + struct rifsc_rimu_debug_data m_dbg_entry; + + stm32_rifsc_fill_rimu_dbg_entry(rifsc, &m_dbg_entry, i); + + seq_printf(s, "| %-11s |", m_dbg_entry.m_name); + seq_printf(s, "| %-6s |", m_dbg_entry.cidsel ? "CIDSEL" : ""); + seq_printf(s, "| %-4d |", m_dbg_entry.m_cid); + seq_printf(s, "| %-8s |", m_dbg_entry.m_sec ? "SEC" : "NSEC"); + seq_printf(s, "| %-12s |\n", m_dbg_entry.m_priv ? "PRIV" : "NPRIV"); + } + + if (rifsc->nb_risal > 0) { + seq_puts(s, "\n=============================================\n"); + seq_puts(s, " RISAL dump\n"); + seq_puts(s, "=============================================\n"); + + seq_puts(s, "| Memory |"); + seq_puts(s, "| Subreg. |"); + seq_puts(s, "| N/SECURE |"); + seq_puts(s, "| N/PRIVILEGED |"); + seq_puts(s, "| Subreg. CID |"); + seq_puts(s, "| Resource lock |"); + seq_puts(s, "| Subreg. enable |"); + seq_puts(s, "| Subreg. start |"); + seq_puts(s, "| Subreg. end |\n"); + + for (i = 0; i < rifsc->nb_risal; i++) { + for (j = 0; j < RIFSC_RISAL_SUBREGIONS; j++) { + struct rifsc_subreg_debug_data sr_dbg_entry; + + stm32_rifsc_fill_subreg_dbg_entry(rifsc, &sr_dbg_entry, i, j); + + seq_printf(s, "| LPSRAM%1d |", i + 1); + seq_printf(s, "| %1s |", (j == 0) ? "A" : "B"); + seq_printf(s, "| %-8s |", sr_dbg_entry.sr_sec ? "SEC" : "NSEC"); + seq_printf(s, "| %-12s |", sr_dbg_entry.sr_priv ? "PRIV" : "NPRIV"); + seq_printf(s, "| 0x%-9x |", sr_dbg_entry.sr_cid); + seq_printf(s, "| %-13s |", + sr_dbg_entry.sr_rlock ? "locked (1)" : "unlocked (0)"); + seq_printf(s, "| %-14s |", + str_enabled_disabled(sr_dbg_entry.sr_enable)); + seq_printf(s, "| 0x%-11x |", sr_dbg_entry.sr_start); + seq_printf(s, "| 0x%-11x |\n", sr_dbg_entry.sr_start + + sr_dbg_entry.sr_length - 1); + } + } + } + + return 0; +} +DEFINE_SHOW_ATTRIBUTE(stm32_rifsc_conf_dump); + +static int stm32_rifsc_register_debugfs(struct stm32_firewall_controller *rifsc_controller, + u32 nb_risup, u32 nb_rimu, u32 nb_risal) +{ + struct rifsc_dbg_private *rifsc_priv; + struct dentry *root = NULL; + + rifsc_priv = devm_kzalloc(rifsc_controller->dev, sizeof(*rifsc_priv), GFP_KERNEL); + if (!rifsc_priv) + return -ENOMEM; + + rifsc_priv->mmio = rifsc_controller->mmio; + rifsc_priv->nb_risup = nb_risup; + rifsc_priv->nb_rimu = nb_rimu; + rifsc_priv->nb_risal = nb_risal; + rifsc_priv->res_names = of_device_get_match_data(rifsc_controller->dev); + + root = debugfs_lookup("stm32_firewall", NULL); + if (!root) + root = debugfs_create_dir("stm32_firewall", NULL); + + if (IS_ERR(root)) + return PTR_ERR(root); + + debugfs_create_file("rifsc", 0444, root, rifsc_priv, &stm32_rifsc_conf_dump_fops); + + return 0; +} +#endif /* defined(CONFIG_DEBUG_FS) */ + static bool stm32_rifsc_is_semaphore_available(void __iomem *addr) { return !(readl(addr) & SEMCR_MUTEX); @@ -207,9 +769,19 @@ static int stm32_rifsc_probe(struct platform_device *pdev) rifsc_controller->release_access = stm32_rifsc_release_access; /* Get number of RIFSC entries*/ - nb_risup = readl(rifsc_controller->mmio + RIFSC_RISC_HWCFGR2) & HWCFGR2_CONF1_MASK; - nb_rimu = readl(rifsc_controller->mmio + RIFSC_RISC_HWCFGR2) & HWCFGR2_CONF2_MASK; - nb_risal = readl(rifsc_controller->mmio + RIFSC_RISC_HWCFGR2) & HWCFGR2_CONF3_MASK; + nb_risup = FIELD_GET(HWCFGR2_CONF1_MASK, + readl(rifsc_controller->mmio + RIFSC_RISC_HWCFGR2)); + nb_rimu = FIELD_GET(HWCFGR2_CONF2_MASK, + readl(rifsc_controller->mmio + RIFSC_RISC_HWCFGR2)); + nb_risal = FIELD_GET(HWCFGR2_CONF3_MASK, + readl(rifsc_controller->mmio + RIFSC_RISC_HWCFGR2)); + /* + * On STM32MP21, RIFSC_RISC_HWCFGR2 shows an incorrect number of RISAL (NUM_RISAL is 3 + * instead of 0). A software workaround is implemented using the st,mem-map property in the + * device tree. This property is absent or left empty if there is no RISAL. + */ + if (of_device_is_compatible(np, "st,stm32mp21-rifsc")) + nb_risal = 0; rifsc_controller->max_entries = nb_risup + nb_rimu + nb_risal; platform_set_drvdata(pdev, rifsc_controller); @@ -228,12 +800,29 @@ static int stm32_rifsc_probe(struct platform_device *pdev) return rc; } +#if defined(CONFIG_DEBUG_FS) + rc = stm32_rifsc_register_debugfs(rifsc_controller, nb_risup, nb_rimu, nb_risal); + if (rc) + return dev_err_probe(rifsc_controller->dev, rc, "Failed creating debugfs entry\n"); +#endif + /* Populate all allowed nodes */ return of_platform_populate(np, NULL, NULL, &pdev->dev); } static const struct of_device_id stm32_rifsc_of_match[] = { - { .compatible = "st,stm32mp25-rifsc" }, + { + .compatible = "st,stm32mp25-rifsc", +#if defined(CONFIG_DEBUG_FS) + .data = &rifsc_mp25_res_names, +#endif + }, + { + .compatible = "st,stm32mp21-rifsc", +#if defined(CONFIG_DEBUG_FS) + .data = &rifsc_mp21_res_names, +#endif + }, {} }; MODULE_DEVICE_TABLE(of, stm32_rifsc_of_match); From a97fbc3ee3e2a536fafaff04f21f45472db71769 Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Wed, 29 Oct 2025 17:33:30 +0100 Subject: [PATCH 088/114] syscore: Pass context data to callbacks Several drivers can benefit from registering per-instance data along with the syscore operations. To achieve this, move the modifiable fields out of the syscore_ops structure and into a separate struct syscore that can be registered with the framework. Add a void * driver data field for drivers to store contextual data that will be passed to the syscore ops. Acked-by: Rafael J. Wysocki (Intel) Signed-off-by: Thierry Reding --- arch/arm/mach-exynos/mcpm-exynos.c | 12 ++-- arch/arm/mach-exynos/suspend.c | 48 +++++++------ arch/arm/mach-pxa/generic.h | 6 +- arch/arm/mach-pxa/irq.c | 10 ++- arch/arm/mach-pxa/mfp-pxa2xx.c | 10 ++- arch/arm/mach-pxa/mfp-pxa3xx.c | 10 ++- arch/arm/mach-pxa/pxa25x.c | 4 +- arch/arm/mach-pxa/pxa27x.c | 4 +- arch/arm/mach-pxa/pxa3xx.c | 4 +- arch/arm/mach-pxa/smemc.c | 12 ++-- arch/arm/mach-s3c/irq-pm-s3c64xx.c | 12 ++-- arch/arm/mach-s5pv210/pm.c | 10 ++- arch/arm/mach-versatile/integrator_ap.c | 12 ++-- arch/arm/mm/cache-b15-rac.c | 12 ++-- arch/loongarch/kernel/smp.c | 12 ++-- arch/mips/alchemy/common/dbdma.c | 12 ++-- arch/mips/alchemy/common/irq.c | 24 ++++--- arch/mips/alchemy/common/usb.c | 12 ++-- arch/mips/pci/pci-alchemy.c | 16 +++-- arch/powerpc/platforms/cell/spu_base.c | 10 ++- arch/powerpc/platforms/powermac/pic.c | 12 ++-- arch/powerpc/sysdev/fsl_lbc.c | 12 ++-- arch/powerpc/sysdev/fsl_pci.c | 12 ++-- arch/powerpc/sysdev/ipic.c | 12 ++-- arch/powerpc/sysdev/mpic.c | 14 ++-- arch/powerpc/sysdev/mpic_timer.c | 10 ++- arch/sh/mm/pmb.c | 10 ++- arch/x86/events/amd/ibs.c | 12 ++-- arch/x86/hyperv/hv_init.c | 12 ++-- arch/x86/kernel/amd_gart_64.c | 10 ++- arch/x86/kernel/apic/apic.c | 12 ++-- arch/x86/kernel/apic/io_apic.c | 17 +++-- arch/x86/kernel/cpu/aperfmperf.c | 20 +++--- arch/x86/kernel/cpu/intel_epb.c | 16 +++-- arch/x86/kernel/cpu/mce/core.c | 14 ++-- arch/x86/kernel/cpu/microcode/core.c | 15 ++++- arch/x86/kernel/cpu/mtrr/legacy.c | 12 ++-- arch/x86/kernel/cpu/umwait.c | 10 ++- arch/x86/kernel/i8237.c | 10 ++- arch/x86/kernel/i8259.c | 14 ++-- arch/x86/kernel/kvm.c | 12 ++-- drivers/acpi/pci_link.c | 10 ++- drivers/acpi/sleep.c | 12 ++-- drivers/base/firmware_loader/main.c | 12 ++-- drivers/base/syscore.c | 82 ++++++++++++----------- drivers/bus/mvebu-mbus.c | 16 +++-- drivers/clk/at91/pmc.c | 12 ++-- drivers/clk/imx/clk-vf610.c | 12 ++-- drivers/clk/ingenic/jz4725b-cgu.c | 2 +- drivers/clk/ingenic/jz4740-cgu.c | 2 +- drivers/clk/ingenic/jz4755-cgu.c | 2 +- drivers/clk/ingenic/jz4760-cgu.c | 2 +- drivers/clk/ingenic/jz4770-cgu.c | 2 +- drivers/clk/ingenic/jz4780-cgu.c | 2 +- drivers/clk/ingenic/pm.c | 14 ++-- drivers/clk/ingenic/pm.h | 2 +- drivers/clk/ingenic/tcu.c | 12 ++-- drivers/clk/ingenic/x1000-cgu.c | 2 +- drivers/clk/ingenic/x1830-cgu.c | 2 +- drivers/clk/mvebu/common.c | 12 ++-- drivers/clk/rockchip/clk-rk3288.c | 12 ++-- drivers/clk/samsung/clk-s5pv210-audss.c | 12 ++-- drivers/clk/samsung/clk.c | 12 ++-- drivers/clk/tegra/clk-tegra210.c | 12 ++-- drivers/clocksource/timer-armada-370-xp.c | 12 ++-- drivers/cpuidle/cpuidle-psci.c | 12 ++-- drivers/gpio/gpio-mxc.c | 12 ++-- drivers/gpio/gpio-pxa.c | 12 ++-- drivers/gpio/gpio-sa1100.c | 12 ++-- drivers/hv/vmbus_drv.c | 14 ++-- drivers/iommu/amd/init.c | 16 +++-- drivers/iommu/intel/iommu.c | 12 ++-- drivers/irqchip/exynos-combiner.c | 14 ++-- drivers/irqchip/irq-armada-370-xp.c | 12 ++-- drivers/irqchip/irq-bcm7038-l1.c | 12 ++-- drivers/irqchip/irq-gic-v3-its.c | 12 ++-- drivers/irqchip/irq-i8259.c | 12 ++-- drivers/irqchip/irq-imx-gpcv2.c | 16 +++-- drivers/irqchip/irq-loongson-eiointc.c | 12 ++-- drivers/irqchip/irq-loongson-htpic.c | 10 ++- drivers/irqchip/irq-loongson-htvec.c | 12 ++-- drivers/irqchip/irq-loongson-pch-lpc.c | 12 ++-- drivers/irqchip/irq-loongson-pch-pic.c | 12 ++-- drivers/irqchip/irq-mchp-eic.c | 12 ++-- drivers/irqchip/irq-mst-intc.c | 12 ++-- drivers/irqchip/irq-mtk-cirq.c | 12 ++-- drivers/irqchip/irq-renesas-rzg2l.c | 12 ++-- drivers/irqchip/irq-sa11x0.c | 12 ++-- drivers/irqchip/irq-sifive-plic.c | 12 ++-- drivers/irqchip/irq-sun6i-r.c | 18 +++-- drivers/irqchip/irq-tegra.c | 12 ++-- drivers/irqchip/irq-vic.c | 12 ++-- drivers/leds/trigger/ledtrig-cpu.c | 14 ++-- drivers/macintosh/via-pmu.c | 12 ++-- drivers/power/reset/sc27xx-poweroff.c | 10 ++- drivers/sh/clk/core.c | 10 ++- drivers/sh/intc/core.c | 12 ++-- drivers/soc/bcm/brcmstb/biuctrl.c | 12 ++-- drivers/soc/tegra/pmc.c | 17 +++-- drivers/thermal/intel/intel_hfi.c | 12 ++-- drivers/xen/xen-acpi-processor.c | 12 ++-- include/linux/syscore_ops.h | 17 +++-- kernel/cpu_pm.c | 12 ++-- kernel/irq/generic-chip.c | 14 ++-- kernel/irq/pm.c | 11 ++- kernel/printk/printk.c | 11 ++- kernel/time/sched_clock.c | 22 ++++-- kernel/time/timekeeping.c | 22 ++++-- virt/kvm/kvm_main.c | 18 +++-- 109 files changed, 899 insertions(+), 471 deletions(-) diff --git a/arch/arm/mach-exynos/mcpm-exynos.c b/arch/arm/mach-exynos/mcpm-exynos.c index fd0dbeb93357..cb7d8a7b14e0 100644 --- a/arch/arm/mach-exynos/mcpm-exynos.c +++ b/arch/arm/mach-exynos/mcpm-exynos.c @@ -215,7 +215,7 @@ static const struct of_device_id exynos_dt_mcpm_match[] = { {}, }; -static void exynos_mcpm_setup_entry_point(void) +static void exynos_mcpm_setup_entry_point(void *data) { /* * U-Boot SPL is hardcoded to jump to the start of ns_sram_base_addr @@ -228,10 +228,14 @@ static void exynos_mcpm_setup_entry_point(void) __raw_writel(__pa_symbol(mcpm_entry_point), ns_sram_base_addr + 8); } -static struct syscore_ops exynos_mcpm_syscore_ops = { +static const struct syscore_ops exynos_mcpm_syscore_ops = { .resume = exynos_mcpm_setup_entry_point, }; +static struct syscore exynos_mcpm_syscore = { + .ops = &exynos_mcpm_syscore_ops, +}; + static int __init exynos_mcpm_init(void) { struct device_node *node; @@ -300,9 +304,9 @@ static int __init exynos_mcpm_init(void) pmu_raw_writel(value, EXYNOS_COMMON_OPTION(i)); } - exynos_mcpm_setup_entry_point(); + exynos_mcpm_setup_entry_point(NULL); - register_syscore_ops(&exynos_mcpm_syscore_ops); + register_syscore(&exynos_mcpm_syscore); return ret; } diff --git a/arch/arm/mach-exynos/suspend.c b/arch/arm/mach-exynos/suspend.c index 150a1e56dcae..22d723553f62 100644 --- a/arch/arm/mach-exynos/suspend.c +++ b/arch/arm/mach-exynos/suspend.c @@ -53,9 +53,9 @@ struct exynos_pm_data { void (*pm_prepare)(void); void (*pm_resume_prepare)(void); - void (*pm_resume)(void); - int (*pm_suspend)(void); int (*cpu_suspend)(unsigned long); + + const struct syscore_ops *syscore_ops; }; /* Used only on Exynos542x/5800 */ @@ -376,7 +376,7 @@ static void exynos5420_pm_prepare(void) } -static int exynos_pm_suspend(void) +static int exynos_pm_suspend(void *data) { exynos_pm_central_suspend(); @@ -390,7 +390,7 @@ static int exynos_pm_suspend(void) return 0; } -static int exynos5420_pm_suspend(void) +static int exynos5420_pm_suspend(void *data) { u32 this_cluster; @@ -408,7 +408,7 @@ static int exynos5420_pm_suspend(void) return 0; } -static void exynos_pm_resume(void) +static void exynos_pm_resume(void *data) { u32 cpuid = read_cpuid_part(); @@ -429,7 +429,7 @@ static void exynos_pm_resume(void) exynos_set_delayed_reset_assertion(true); } -static void exynos3250_pm_resume(void) +static void exynos3250_pm_resume(void *data) { u32 cpuid = read_cpuid_part(); @@ -473,7 +473,7 @@ static void exynos5420_prepare_pm_resume(void) } } -static void exynos5420_pm_resume(void) +static void exynos5420_pm_resume(void *data) { unsigned long tmp; @@ -596,41 +596,52 @@ static const struct platform_suspend_ops exynos_suspend_ops = { .valid = suspend_valid_only_mem, }; +static const struct syscore_ops exynos3250_syscore_ops = { + .suspend = exynos_pm_suspend, + .resume = exynos3250_pm_resume, +}; + static const struct exynos_pm_data exynos3250_pm_data = { .wkup_irq = exynos3250_wkup_irq, .wake_disable_mask = ((0xFF << 8) | (0x1F << 1)), - .pm_suspend = exynos_pm_suspend, - .pm_resume = exynos3250_pm_resume, .pm_prepare = exynos3250_pm_prepare, .cpu_suspend = exynos3250_cpu_suspend, + .syscore_ops = &exynos3250_syscore_ops, +}; + +static const struct syscore_ops exynos_syscore_ops = { + .suspend = exynos_pm_suspend, + .resume = exynos_pm_resume, }; static const struct exynos_pm_data exynos4_pm_data = { .wkup_irq = exynos4_wkup_irq, .wake_disable_mask = ((0xFF << 8) | (0x1F << 1)), - .pm_suspend = exynos_pm_suspend, - .pm_resume = exynos_pm_resume, .pm_prepare = exynos_pm_prepare, .cpu_suspend = exynos_cpu_suspend, + .syscore_ops = &exynos_syscore_ops, }; static const struct exynos_pm_data exynos5250_pm_data = { .wkup_irq = exynos5250_wkup_irq, .wake_disable_mask = ((0xFF << 8) | (0x1F << 1)), - .pm_suspend = exynos_pm_suspend, - .pm_resume = exynos_pm_resume, .pm_prepare = exynos_pm_prepare, .cpu_suspend = exynos_cpu_suspend, + .syscore_ops = &exynos_syscore_ops, +}; + +static const struct syscore_ops exynos5420_syscore_ops = { + .resume = exynos5420_pm_resume, + .suspend = exynos5420_pm_suspend, }; static const struct exynos_pm_data exynos5420_pm_data = { .wkup_irq = exynos5250_wkup_irq, .wake_disable_mask = (0x7F << 7) | (0x1F << 1), .pm_resume_prepare = exynos5420_prepare_pm_resume, - .pm_resume = exynos5420_pm_resume, - .pm_suspend = exynos5420_pm_suspend, .pm_prepare = exynos5420_pm_prepare, .cpu_suspend = exynos5420_cpu_suspend, + .syscore_ops = &exynos5420_syscore_ops, }; static const struct of_device_id exynos_pmu_of_device_ids[] __initconst = { @@ -656,7 +667,7 @@ static const struct of_device_id exynos_pmu_of_device_ids[] __initconst = { { /*sentinel*/ }, }; -static struct syscore_ops exynos_pm_syscore_ops; +static struct syscore exynos_pm_syscore; void __init exynos_pm_init(void) { @@ -684,10 +695,9 @@ void __init exynos_pm_init(void) tmp |= pm_data->wake_disable_mask; pmu_raw_writel(tmp, S5P_WAKEUP_MASK); - exynos_pm_syscore_ops.suspend = pm_data->pm_suspend; - exynos_pm_syscore_ops.resume = pm_data->pm_resume; + exynos_pm_syscore.ops = pm_data->syscore_ops; - register_syscore_ops(&exynos_pm_syscore_ops); + register_syscore(&exynos_pm_syscore); suspend_set_ops(&exynos_suspend_ops); /* diff --git a/arch/arm/mach-pxa/generic.h b/arch/arm/mach-pxa/generic.h index c9c2c46ecead..caad4fca8de3 100644 --- a/arch/arm/mach-pxa/generic.h +++ b/arch/arm/mach-pxa/generic.h @@ -34,9 +34,9 @@ extern void __init pxa27x_map_io(void); extern void __init pxa3xx_init_irq(void); extern void __init pxa3xx_map_io(void); -extern struct syscore_ops pxa_irq_syscore_ops; -extern struct syscore_ops pxa2xx_mfp_syscore_ops; -extern struct syscore_ops pxa3xx_mfp_syscore_ops; +extern struct syscore pxa_irq_syscore; +extern struct syscore pxa2xx_mfp_syscore; +extern struct syscore pxa3xx_mfp_syscore; void __init pxa_set_ffuart_info(void *info); void __init pxa_set_btuart_info(void *info); diff --git a/arch/arm/mach-pxa/irq.c b/arch/arm/mach-pxa/irq.c index 5bfce8aa4102..99acebbbf065 100644 --- a/arch/arm/mach-pxa/irq.c +++ b/arch/arm/mach-pxa/irq.c @@ -178,7 +178,7 @@ void __init pxa_init_irq(int irq_nr, int (*fn)(struct irq_data *, unsigned int)) static unsigned long saved_icmr[MAX_INTERNAL_IRQS/32]; static unsigned long saved_ipr[MAX_INTERNAL_IRQS]; -static int pxa_irq_suspend(void) +static int pxa_irq_suspend(void *data) { int i; @@ -197,7 +197,7 @@ static int pxa_irq_suspend(void) return 0; } -static void pxa_irq_resume(void) +static void pxa_irq_resume(void *data) { int i; @@ -219,11 +219,15 @@ static void pxa_irq_resume(void) #define pxa_irq_resume NULL #endif -struct syscore_ops pxa_irq_syscore_ops = { +static const struct syscore_ops pxa_irq_syscore_ops = { .suspend = pxa_irq_suspend, .resume = pxa_irq_resume, }; +struct syscore pxa_irq_syscore = { + .ops = &pxa_irq_syscore_ops, +}; + #ifdef CONFIG_OF static const struct of_device_id intc_ids[] __initconst = { { .compatible = "marvell,pxa-intc", }, diff --git a/arch/arm/mach-pxa/mfp-pxa2xx.c b/arch/arm/mach-pxa/mfp-pxa2xx.c index f5a3d890f682..d1347055fbe4 100644 --- a/arch/arm/mach-pxa/mfp-pxa2xx.c +++ b/arch/arm/mach-pxa/mfp-pxa2xx.c @@ -346,7 +346,7 @@ static unsigned long saved_gpdr[4]; static unsigned long saved_gplr[4]; static unsigned long saved_pgsr[4]; -static int pxa2xx_mfp_suspend(void) +static int pxa2xx_mfp_suspend(void *data) { int i; @@ -385,7 +385,7 @@ static int pxa2xx_mfp_suspend(void) return 0; } -static void pxa2xx_mfp_resume(void) +static void pxa2xx_mfp_resume(void *data) { int i; @@ -404,11 +404,15 @@ static void pxa2xx_mfp_resume(void) #define pxa2xx_mfp_resume NULL #endif -struct syscore_ops pxa2xx_mfp_syscore_ops = { +static const struct syscore_ops pxa2xx_mfp_syscore_ops = { .suspend = pxa2xx_mfp_suspend, .resume = pxa2xx_mfp_resume, }; +struct syscore pxa2xx_mfp_syscore = { + .ops = &pxa2xx_mfp_syscore_ops, +}; + static int __init pxa2xx_mfp_init(void) { int i; diff --git a/arch/arm/mach-pxa/mfp-pxa3xx.c b/arch/arm/mach-pxa/mfp-pxa3xx.c index d16ab7451efe..fe7498fbb62b 100644 --- a/arch/arm/mach-pxa/mfp-pxa3xx.c +++ b/arch/arm/mach-pxa/mfp-pxa3xx.c @@ -27,13 +27,13 @@ * a pull-down mode if they're an active low chip select, and we're * just entering standby. */ -static int pxa3xx_mfp_suspend(void) +static int pxa3xx_mfp_suspend(void *data) { mfp_config_lpm(); return 0; } -static void pxa3xx_mfp_resume(void) +static void pxa3xx_mfp_resume(void *data) { mfp_config_run(); @@ -49,7 +49,11 @@ static void pxa3xx_mfp_resume(void) #define pxa3xx_mfp_resume NULL #endif -struct syscore_ops pxa3xx_mfp_syscore_ops = { +static const struct syscore_ops pxa3xx_mfp_syscore_ops = { .suspend = pxa3xx_mfp_suspend, .resume = pxa3xx_mfp_resume, }; + +struct syscore pxa3xx_mfp_syscore = { + .ops = &pxa3xx_mfp_syscore_ops, +}; diff --git a/arch/arm/mach-pxa/pxa25x.c b/arch/arm/mach-pxa/pxa25x.c index 03e34841fc00..70509a599814 100644 --- a/arch/arm/mach-pxa/pxa25x.c +++ b/arch/arm/mach-pxa/pxa25x.c @@ -235,8 +235,8 @@ static int __init pxa25x_init(void) pxa25x_init_pm(); - register_syscore_ops(&pxa_irq_syscore_ops); - register_syscore_ops(&pxa2xx_mfp_syscore_ops); + register_syscore(&pxa_irq_syscore); + register_syscore(&pxa2xx_mfp_syscore); if (!of_have_populated_dt()) { software_node_register(&pxa2xx_gpiochip_node); diff --git a/arch/arm/mach-pxa/pxa27x.c b/arch/arm/mach-pxa/pxa27x.c index f8382477d629..ff6361979038 100644 --- a/arch/arm/mach-pxa/pxa27x.c +++ b/arch/arm/mach-pxa/pxa27x.c @@ -337,8 +337,8 @@ static int __init pxa27x_init(void) pxa27x_init_pm(); - register_syscore_ops(&pxa_irq_syscore_ops); - register_syscore_ops(&pxa2xx_mfp_syscore_ops); + register_syscore(&pxa_irq_syscore); + register_syscore(&pxa2xx_mfp_syscore); if (!of_have_populated_dt()) { software_node_register(&pxa2xx_gpiochip_node); diff --git a/arch/arm/mach-pxa/pxa3xx.c b/arch/arm/mach-pxa/pxa3xx.c index 1d1e5713464d..06c578ea658e 100644 --- a/arch/arm/mach-pxa/pxa3xx.c +++ b/arch/arm/mach-pxa/pxa3xx.c @@ -424,8 +424,8 @@ static int __init pxa3xx_init(void) if (cpu_is_pxa320()) enable_irq_wake(IRQ_WAKEUP1); - register_syscore_ops(&pxa_irq_syscore_ops); - register_syscore_ops(&pxa3xx_mfp_syscore_ops); + register_syscore(&pxa_irq_syscore); + register_syscore(&pxa3xx_mfp_syscore); } return ret; diff --git a/arch/arm/mach-pxa/smemc.c b/arch/arm/mach-pxa/smemc.c index 2d2a321d82f8..fb93a8f28356 100644 --- a/arch/arm/mach-pxa/smemc.c +++ b/arch/arm/mach-pxa/smemc.c @@ -18,7 +18,7 @@ static unsigned long msc[2]; static unsigned long sxcnfg, memclkcfg; static unsigned long csadrcfg[4]; -static int pxa3xx_smemc_suspend(void) +static int pxa3xx_smemc_suspend(void *data) { msc[0] = __raw_readl(MSC0); msc[1] = __raw_readl(MSC1); @@ -32,7 +32,7 @@ static int pxa3xx_smemc_suspend(void) return 0; } -static void pxa3xx_smemc_resume(void) +static void pxa3xx_smemc_resume(void *data) { __raw_writel(msc[0], MSC0); __raw_writel(msc[1], MSC1); @@ -46,11 +46,15 @@ static void pxa3xx_smemc_resume(void) __raw_writel(0x2, CSMSADRCFG); } -static struct syscore_ops smemc_syscore_ops = { +static const struct syscore_ops smemc_syscore_ops = { .suspend = pxa3xx_smemc_suspend, .resume = pxa3xx_smemc_resume, }; +static struct syscore smemc_syscore = { + .ops = &smemc_syscore_ops, +}; + static int __init smemc_init(void) { if (cpu_is_pxa3xx()) { @@ -64,7 +68,7 @@ static int __init smemc_init(void) */ __raw_writel(0x2, CSMSADRCFG); - register_syscore_ops(&smemc_syscore_ops); + register_syscore(&smemc_syscore); } return 0; diff --git a/arch/arm/mach-s3c/irq-pm-s3c64xx.c b/arch/arm/mach-s3c/irq-pm-s3c64xx.c index 4a1e935bada1..ab726c595001 100644 --- a/arch/arm/mach-s3c/irq-pm-s3c64xx.c +++ b/arch/arm/mach-s3c/irq-pm-s3c64xx.c @@ -58,7 +58,7 @@ static struct irq_grp_save { static u32 irq_uart_mask[SERIAL_SAMSUNG_UARTS]; -static int s3c64xx_irq_pm_suspend(void) +static int s3c64xx_irq_pm_suspend(void *data) { struct irq_grp_save *grp = eint_grp_save; int i; @@ -79,7 +79,7 @@ static int s3c64xx_irq_pm_suspend(void) return 0; } -static void s3c64xx_irq_pm_resume(void) +static void s3c64xx_irq_pm_resume(void *data) { struct irq_grp_save *grp = eint_grp_save; int i; @@ -100,18 +100,22 @@ static void s3c64xx_irq_pm_resume(void) S3C_PMDBG("%s: IRQ configuration restored\n", __func__); } -static struct syscore_ops s3c64xx_irq_syscore_ops = { +static const struct syscore_ops s3c64xx_irq_syscore_ops = { .suspend = s3c64xx_irq_pm_suspend, .resume = s3c64xx_irq_pm_resume, }; +static struct syscore s3c64xx_irq_syscore = { + .ops = &s3c64xx_irq_syscore_ops, +}; + static __init int s3c64xx_syscore_init(void) { /* Appropriate drivers (pinctrl, uart) handle this when using DT. */ if (of_have_populated_dt() || !soc_is_s3c64xx()) return 0; - register_syscore_ops(&s3c64xx_irq_syscore_ops); + register_syscore(&s3c64xx_irq_syscore); return 0; } diff --git a/arch/arm/mach-s5pv210/pm.c b/arch/arm/mach-s5pv210/pm.c index 6fa70f787df4..fa270750364c 100644 --- a/arch/arm/mach-s5pv210/pm.c +++ b/arch/arm/mach-s5pv210/pm.c @@ -195,20 +195,24 @@ static const struct platform_suspend_ops s5pv210_suspend_ops = { /* * Syscore operations used to delay restore of certain registers. */ -static void s5pv210_pm_resume(void) +static void s5pv210_pm_resume(void *data) { s3c_pm_do_restore_core(s5pv210_core_save, ARRAY_SIZE(s5pv210_core_save)); } -static struct syscore_ops s5pv210_pm_syscore_ops = { +static const struct syscore_ops s5pv210_pm_syscore_ops = { .resume = s5pv210_pm_resume, }; +static struct syscore s5pv210_pm_syscore = { + .ops = &s5pv210_pm_syscore_ops, +}; + /* * Initialization entry point. */ void __init s5pv210_pm_init(void) { - register_syscore_ops(&s5pv210_pm_syscore_ops); + register_syscore(&s5pv210_pm_syscore); suspend_set_ops(&s5pv210_suspend_ops); } diff --git a/arch/arm/mach-versatile/integrator_ap.c b/arch/arm/mach-versatile/integrator_ap.c index 4bd6712e9f52..ee90d6619d0d 100644 --- a/arch/arm/mach-versatile/integrator_ap.c +++ b/arch/arm/mach-versatile/integrator_ap.c @@ -63,13 +63,13 @@ static void __init ap_map_io(void) #ifdef CONFIG_PM static unsigned long ic_irq_enable; -static int irq_suspend(void) +static int irq_suspend(void *data) { ic_irq_enable = readl(VA_IC_BASE + IRQ_ENABLE); return 0; } -static void irq_resume(void) +static void irq_resume(void *data) { /* disable all irq sources */ cm_clear_irqs(); @@ -83,14 +83,18 @@ static void irq_resume(void) #define irq_resume NULL #endif -static struct syscore_ops irq_syscore_ops = { +static const struct syscore_ops irq_syscore_ops = { .suspend = irq_suspend, .resume = irq_resume, }; +static struct syscore irq_syscore = { + .ops = &irq_syscore_ops, +}; + static int __init irq_syscore_init(void) { - register_syscore_ops(&irq_syscore_ops); + register_syscore(&irq_syscore); return 0; } diff --git a/arch/arm/mm/cache-b15-rac.c b/arch/arm/mm/cache-b15-rac.c index 6f63b90f9e1a..e7807356dfab 100644 --- a/arch/arm/mm/cache-b15-rac.c +++ b/arch/arm/mm/cache-b15-rac.c @@ -256,7 +256,7 @@ static int b15_rac_dead_cpu(unsigned int cpu) return 0; } -static int b15_rac_suspend(void) +static int b15_rac_suspend(void *data) { /* Suspend the read-ahead cache oeprations, forcing our cache * implementation to fallback to the regular ARMv7 calls. @@ -271,7 +271,7 @@ static int b15_rac_suspend(void) return 0; } -static void b15_rac_resume(void) +static void b15_rac_resume(void *data) { /* Coming out of a S3 suspend/resume cycle, the read-ahead cache * register RAC_CONFIG0_REG will be restored to its default value, make @@ -282,11 +282,15 @@ static void b15_rac_resume(void) clear_bit(RAC_SUSPENDED, &b15_rac_flags); } -static struct syscore_ops b15_rac_syscore_ops = { +static const struct syscore_ops b15_rac_syscore_ops = { .suspend = b15_rac_suspend, .resume = b15_rac_resume, }; +static struct syscore b15_rac_syscore = { + .ops = &b15_rac_syscore_ops, +}; + static int __init b15_rac_init(void) { struct device_node *dn, *cpu_dn; @@ -347,7 +351,7 @@ static int __init b15_rac_init(void) } if (IS_ENABLED(CONFIG_PM_SLEEP)) - register_syscore_ops(&b15_rac_syscore_ops); + register_syscore(&b15_rac_syscore); spin_lock(&rac_lock); reg = __raw_readl(b15_rac_base + RAC_CONFIG0_REG); diff --git a/arch/loongarch/kernel/smp.c b/arch/loongarch/kernel/smp.c index 46036d98da75..8b2fcb3fb874 100644 --- a/arch/loongarch/kernel/smp.c +++ b/arch/loongarch/kernel/smp.c @@ -535,28 +535,32 @@ int hibernate_resume_nonboot_cpu_disable(void) */ #ifdef CONFIG_PM -static int loongson_ipi_suspend(void) +static int loongson_ipi_suspend(void *data) { return 0; } -static void loongson_ipi_resume(void) +static void loongson_ipi_resume(void *data) { iocsr_write32(0xffffffff, LOONGARCH_IOCSR_IPI_EN); } -static struct syscore_ops loongson_ipi_syscore_ops = { +static const struct syscore_ops loongson_ipi_syscore_ops = { .resume = loongson_ipi_resume, .suspend = loongson_ipi_suspend, }; +static struct syscore loongson_ipi_syscore = { + .ops = &loongson_ipi_syscore_ops, +}; + /* * Enable boot cpu ipi before enabling nonboot cpus * during syscore_resume. */ static int __init ipi_pm_init(void) { - register_syscore_ops(&loongson_ipi_syscore_ops); + register_syscore(&loongson_ipi_syscore); return 0; } diff --git a/arch/mips/alchemy/common/dbdma.c b/arch/mips/alchemy/common/dbdma.c index 6a3c890f7bbf..6c2c2010bbae 100644 --- a/arch/mips/alchemy/common/dbdma.c +++ b/arch/mips/alchemy/common/dbdma.c @@ -982,7 +982,7 @@ u32 au1xxx_dbdma_put_dscr(u32 chanid, au1x_ddma_desc_t *dscr) static unsigned long alchemy_dbdma_pm_data[NUM_DBDMA_CHANS + 1][6]; -static int alchemy_dbdma_suspend(void) +static int alchemy_dbdma_suspend(void *data) { int i; void __iomem *addr; @@ -1019,7 +1019,7 @@ static int alchemy_dbdma_suspend(void) return 0; } -static void alchemy_dbdma_resume(void) +static void alchemy_dbdma_resume(void *data) { int i; void __iomem *addr; @@ -1044,11 +1044,15 @@ static void alchemy_dbdma_resume(void) } } -static struct syscore_ops alchemy_dbdma_syscore_ops = { +static const struct syscore_ops alchemy_dbdma_syscore_ops = { .suspend = alchemy_dbdma_suspend, .resume = alchemy_dbdma_resume, }; +static struct syscore alchemy_dbdma_syscore = { + .ops = &alchemy_dbdma_syscore_ops, +}; + static int __init dbdma_setup(unsigned int irq, dbdev_tab_t *idtable) { int ret; @@ -1071,7 +1075,7 @@ static int __init dbdma_setup(unsigned int irq, dbdev_tab_t *idtable) printk(KERN_ERR "Cannot grab DBDMA interrupt!\n"); else { dbdma_initialized = 1; - register_syscore_ops(&alchemy_dbdma_syscore_ops); + register_syscore(&alchemy_dbdma_syscore); } return ret; diff --git a/arch/mips/alchemy/common/irq.c b/arch/mips/alchemy/common/irq.c index da9f9220048f..2403afcd2fb9 100644 --- a/arch/mips/alchemy/common/irq.c +++ b/arch/mips/alchemy/common/irq.c @@ -758,7 +758,7 @@ static inline void alchemy_ic_resume_one(void __iomem *base, unsigned long *d) wmb(); } -static int alchemy_ic_suspend(void) +static int alchemy_ic_suspend(void *data) { alchemy_ic_suspend_one((void __iomem *)KSEG1ADDR(AU1000_IC0_PHYS_ADDR), alchemy_gpic_pmdata); @@ -767,7 +767,7 @@ static int alchemy_ic_suspend(void) return 0; } -static void alchemy_ic_resume(void) +static void alchemy_ic_resume(void *data) { alchemy_ic_resume_one((void __iomem *)KSEG1ADDR(AU1000_IC1_PHYS_ADDR), &alchemy_gpic_pmdata[7]); @@ -775,7 +775,7 @@ static void alchemy_ic_resume(void) alchemy_gpic_pmdata); } -static int alchemy_gpic_suspend(void) +static int alchemy_gpic_suspend(void *data) { void __iomem *base = (void __iomem *)KSEG1ADDR(AU1300_GPIC_PHYS_ADDR); int i; @@ -806,7 +806,7 @@ static int alchemy_gpic_suspend(void) return 0; } -static void alchemy_gpic_resume(void) +static void alchemy_gpic_resume(void *data) { void __iomem *base = (void __iomem *)KSEG1ADDR(AU1300_GPIC_PHYS_ADDR); int i; @@ -837,16 +837,24 @@ static void alchemy_gpic_resume(void) wmb(); } -static struct syscore_ops alchemy_ic_pmops = { +static const struct syscore_ops alchemy_ic_pmops = { .suspend = alchemy_ic_suspend, .resume = alchemy_ic_resume, }; -static struct syscore_ops alchemy_gpic_pmops = { +static struct syscore alchemy_ic_pm = { + .ops = &alchemy_ic_pmops, +}; + +static const struct syscore_ops alchemy_gpic_pmops = { .suspend = alchemy_gpic_suspend, .resume = alchemy_gpic_resume, }; +static struct syscore alchemy_gpic_pm = { + .ops = &alchemy_gpic_pmops, +}; + /******************************************************************************/ /* create chained handlers for the 4 IC requests to the MIPS IRQ ctrl */ @@ -880,7 +888,7 @@ static void __init au1000_init_irq(struct alchemy_irqmap *map) ic_init((void __iomem *)KSEG1ADDR(AU1000_IC0_PHYS_ADDR)); ic_init((void __iomem *)KSEG1ADDR(AU1000_IC1_PHYS_ADDR)); - register_syscore_ops(&alchemy_ic_pmops); + register_syscore(&alchemy_ic_pm); mips_cpu_irq_init(); /* register all 64 possible IC0+IC1 irq sources as type "none". @@ -925,7 +933,7 @@ static void __init alchemy_gpic_init_irq(const struct alchemy_irqmap *dints) int i; void __iomem *bank_base; - register_syscore_ops(&alchemy_gpic_pmops); + register_syscore(&alchemy_gpic_pm); mips_cpu_irq_init(); /* disable & ack all possible interrupt sources */ diff --git a/arch/mips/alchemy/common/usb.c b/arch/mips/alchemy/common/usb.c index 5d618547ebf0..a55f32bf517c 100644 --- a/arch/mips/alchemy/common/usb.c +++ b/arch/mips/alchemy/common/usb.c @@ -580,22 +580,26 @@ static void alchemy_usb_pm(int susp) } } -static int alchemy_usb_suspend(void) +static int alchemy_usb_suspend(void *data) { alchemy_usb_pm(1); return 0; } -static void alchemy_usb_resume(void) +static void alchemy_usb_resume(void *data) { alchemy_usb_pm(0); } -static struct syscore_ops alchemy_usb_pm_ops = { +static const struct syscore_ops alchemy_usb_pm_syscore_ops = { .suspend = alchemy_usb_suspend, .resume = alchemy_usb_resume, }; +static struct syscore alchemy_usb_pm_syscore = { + .ops = &alchemy_usb_pm_syscore_ops, +}; + static int __init alchemy_usb_init(void) { int ret = 0; @@ -620,7 +624,7 @@ static int __init alchemy_usb_init(void) } if (!ret) - register_syscore_ops(&alchemy_usb_pm_ops); + register_syscore(&alchemy_usb_pm_syscore); return ret; } diff --git a/arch/mips/pci/pci-alchemy.c b/arch/mips/pci/pci-alchemy.c index 58625d1b6465..6bfee0f71803 100644 --- a/arch/mips/pci/pci-alchemy.c +++ b/arch/mips/pci/pci-alchemy.c @@ -304,7 +304,7 @@ static int alchemy_pci_def_idsel(unsigned int devsel, int assert) } /* save PCI controller register contents. */ -static int alchemy_pci_suspend(void) +static int alchemy_pci_suspend(void *data) { struct alchemy_pci_context *ctx = __alchemy_pci_ctx; if (!ctx) @@ -326,7 +326,7 @@ static int alchemy_pci_suspend(void) return 0; } -static void alchemy_pci_resume(void) +static void alchemy_pci_resume(void *data) { struct alchemy_pci_context *ctx = __alchemy_pci_ctx; if (!ctx) @@ -354,9 +354,13 @@ static void alchemy_pci_resume(void) alchemy_pci_wired_entry(ctx); /* install it */ } -static struct syscore_ops alchemy_pci_pmops = { - .suspend = alchemy_pci_suspend, - .resume = alchemy_pci_resume, +static const struct syscore_ops alchemy_pci_syscore_ops = { + .suspend = alchemy_pci_suspend, + .resume = alchemy_pci_resume, +}; + +static struct syscore alchemy_pci_syscore = { + .ops = &alchemy_pci_syscore_ops, }; static int alchemy_pci_probe(struct platform_device *pdev) @@ -478,7 +482,7 @@ static int alchemy_pci_probe(struct platform_device *pdev) __alchemy_pci_ctx = ctx; platform_set_drvdata(pdev, ctx); - register_syscore_ops(&alchemy_pci_pmops); + register_syscore(&alchemy_pci_syscore); register_pci_controller(&ctx->alchemy_pci_ctrl); dev_info(&pdev->dev, "PCI controller at %ld MHz\n", diff --git a/arch/powerpc/platforms/cell/spu_base.c b/arch/powerpc/platforms/cell/spu_base.c index 2c07387201d0..2ddb93df4817 100644 --- a/arch/powerpc/platforms/cell/spu_base.c +++ b/arch/powerpc/platforms/cell/spu_base.c @@ -726,7 +726,7 @@ static inline void crash_register_spus(struct list_head *list) } #endif -static void spu_shutdown(void) +static void spu_shutdown(void *data) { struct spu *spu; @@ -738,10 +738,14 @@ static void spu_shutdown(void) mutex_unlock(&spu_full_list_mutex); } -static struct syscore_ops spu_syscore_ops = { +static const struct syscore_ops spu_syscore_ops = { .shutdown = spu_shutdown, }; +static struct syscore spu_syscore = { + .ops = &spu_syscore_ops, +}; + static int __init init_spu_base(void) { int i, ret = 0; @@ -774,7 +778,7 @@ static int __init init_spu_base(void) crash_register_spus(&spu_full_list); mutex_unlock(&spu_full_list_mutex); spu_add_dev_attr(&dev_attr_stat); - register_syscore_ops(&spu_syscore_ops); + register_syscore(&spu_syscore); spu_init_affinity(); diff --git a/arch/powerpc/platforms/powermac/pic.c b/arch/powerpc/platforms/powermac/pic.c index c37783a03d25..1959cc13438f 100644 --- a/arch/powerpc/platforms/powermac/pic.c +++ b/arch/powerpc/platforms/powermac/pic.c @@ -600,7 +600,7 @@ static int pmacpic_find_viaint(void) return viaint; } -static int pmacpic_suspend(void) +static int pmacpic_suspend(void *data) { int viaint = pmacpic_find_viaint(); @@ -621,7 +621,7 @@ static int pmacpic_suspend(void) return 0; } -static void pmacpic_resume(void) +static void pmacpic_resume(void *data) { int i; @@ -634,15 +634,19 @@ static void pmacpic_resume(void) pmac_unmask_irq(irq_get_irq_data(i)); } -static struct syscore_ops pmacpic_syscore_ops = { +static const struct syscore_ops pmacpic_syscore_ops = { .suspend = pmacpic_suspend, .resume = pmacpic_resume, }; +static struct syscore pmacpic_syscore = { + .ops = &pmacpic_syscore_ops, +}; + static int __init init_pmacpic_syscore(void) { if (pmac_irq_hw[0]) - register_syscore_ops(&pmacpic_syscore_ops); + register_syscore(&pmacpic_syscore); return 0; } diff --git a/arch/powerpc/sysdev/fsl_lbc.c b/arch/powerpc/sysdev/fsl_lbc.c index 217cea150987..7ed07232a69a 100644 --- a/arch/powerpc/sysdev/fsl_lbc.c +++ b/arch/powerpc/sysdev/fsl_lbc.c @@ -350,7 +350,7 @@ static int fsl_lbc_ctrl_probe(struct platform_device *dev) #ifdef CONFIG_SUSPEND /* save lbc registers */ -static int fsl_lbc_syscore_suspend(void) +static int fsl_lbc_syscore_suspend(void *data) { struct fsl_lbc_ctrl *ctrl; struct fsl_lbc_regs __iomem *lbc; @@ -374,7 +374,7 @@ static int fsl_lbc_syscore_suspend(void) } /* restore lbc registers */ -static void fsl_lbc_syscore_resume(void) +static void fsl_lbc_syscore_resume(void *data) { struct fsl_lbc_ctrl *ctrl; struct fsl_lbc_regs __iomem *lbc; @@ -408,10 +408,14 @@ static const struct of_device_id fsl_lbc_match[] = { }; #ifdef CONFIG_SUSPEND -static struct syscore_ops lbc_syscore_pm_ops = { +static const struct syscore_ops lbc_syscore_pm_ops = { .suspend = fsl_lbc_syscore_suspend, .resume = fsl_lbc_syscore_resume, }; + +static struct syscore lbc_syscore_pm = { + .ops = &lbc_syscore_pm_ops, +}; #endif static struct platform_driver fsl_lbc_ctrl_driver = { @@ -425,7 +429,7 @@ static struct platform_driver fsl_lbc_ctrl_driver = { static int __init fsl_lbc_init(void) { #ifdef CONFIG_SUSPEND - register_syscore_ops(&lbc_syscore_pm_ops); + register_syscore(&lbc_syscore_pm); #endif return platform_driver_register(&fsl_lbc_ctrl_driver); } diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c index ef7707ea0db7..4e501654cb41 100644 --- a/arch/powerpc/sysdev/fsl_pci.c +++ b/arch/powerpc/sysdev/fsl_pci.c @@ -1258,7 +1258,7 @@ static void fsl_pci_syscore_do_suspend(struct pci_controller *hose) send_pme_turnoff_message(hose); } -static int fsl_pci_syscore_suspend(void) +static int fsl_pci_syscore_suspend(void *data) { struct pci_controller *hose, *tmp; @@ -1291,7 +1291,7 @@ static void fsl_pci_syscore_do_resume(struct pci_controller *hose) setup_pci_atmu(hose); } -static void fsl_pci_syscore_resume(void) +static void fsl_pci_syscore_resume(void *data) { struct pci_controller *hose, *tmp; @@ -1299,10 +1299,14 @@ static void fsl_pci_syscore_resume(void) fsl_pci_syscore_do_resume(hose); } -static struct syscore_ops pci_syscore_pm_ops = { +static const struct syscore_ops pci_syscore_pm_ops = { .suspend = fsl_pci_syscore_suspend, .resume = fsl_pci_syscore_resume, }; + +static struct syscore pci_syscore_pm = { + .ops = &pci_syscore_pm_ops, +}; #endif void fsl_pcibios_fixup_phb(struct pci_controller *phb) @@ -1359,7 +1363,7 @@ static struct platform_driver fsl_pci_driver = { static int __init fsl_pci_init(void) { #ifdef CONFIG_PM_SLEEP - register_syscore_ops(&pci_syscore_pm_ops); + register_syscore(&pci_syscore_pm); #endif return platform_driver_register(&fsl_pci_driver); } diff --git a/arch/powerpc/sysdev/ipic.c b/arch/powerpc/sysdev/ipic.c index 70be2105865d..290ba8427239 100644 --- a/arch/powerpc/sysdev/ipic.c +++ b/arch/powerpc/sysdev/ipic.c @@ -817,7 +817,7 @@ static struct { u32 sercr; } ipic_saved_state; -static int ipic_suspend(void) +static int ipic_suspend(void *data) { struct ipic *ipic = primary_ipic; @@ -848,7 +848,7 @@ static int ipic_suspend(void) return 0; } -static void ipic_resume(void) +static void ipic_resume(void *data) { struct ipic *ipic = primary_ipic; @@ -870,18 +870,22 @@ static void ipic_resume(void) #define ipic_resume NULL #endif -static struct syscore_ops ipic_syscore_ops = { +static const struct syscore_ops ipic_syscore_ops = { .suspend = ipic_suspend, .resume = ipic_resume, }; +static struct syscore ipic_syscore = { + .ops = &ipic_syscore_ops, +}; + static int __init init_ipic_syscore(void) { if (!primary_ipic || !primary_ipic->regs) return -ENODEV; printk(KERN_DEBUG "Registering ipic system core operations\n"); - register_syscore_ops(&ipic_syscore_ops); + register_syscore(&ipic_syscore); return 0; } diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c index ad7310bba00b..67e51998d1ae 100644 --- a/arch/powerpc/sysdev/mpic.c +++ b/arch/powerpc/sysdev/mpic.c @@ -1944,7 +1944,7 @@ static void mpic_suspend_one(struct mpic *mpic) } } -static int mpic_suspend(void) +static int mpic_suspend(void *data) { struct mpic *mpic = mpics; @@ -1986,7 +1986,7 @@ static void mpic_resume_one(struct mpic *mpic) } /* end for loop */ } -static void mpic_resume(void) +static void mpic_resume(void *data) { struct mpic *mpic = mpics; @@ -1996,19 +1996,23 @@ static void mpic_resume(void) } } -static struct syscore_ops mpic_syscore_ops = { +static const struct syscore_ops mpic_syscore_ops = { .resume = mpic_resume, .suspend = mpic_suspend, }; +static struct syscore mpic_syscore = { + .ops = &mpic_syscore_ops, +}; + static int mpic_init_sys(void) { int rc; - register_syscore_ops(&mpic_syscore_ops); + register_syscore(&mpic_syscore); rc = subsys_system_register(&mpic_subsys, NULL); if (rc) { - unregister_syscore_ops(&mpic_syscore_ops); + unregister_syscore(&mpic_syscore); pr_err("mpic: Failed to register subsystem!\n"); return rc; } diff --git a/arch/powerpc/sysdev/mpic_timer.c b/arch/powerpc/sysdev/mpic_timer.c index 7166e2e0baaf..60f5b3934b51 100644 --- a/arch/powerpc/sysdev/mpic_timer.c +++ b/arch/powerpc/sysdev/mpic_timer.c @@ -519,7 +519,7 @@ static void __init timer_group_init(struct device_node *np) kfree(priv); } -static void mpic_timer_resume(void) +static void mpic_timer_resume(void *data) { struct timer_group_priv *priv; @@ -535,10 +535,14 @@ static const struct of_device_id mpic_timer_ids[] = { {}, }; -static struct syscore_ops mpic_timer_syscore_ops = { +static const struct syscore_ops mpic_timer_syscore_ops = { .resume = mpic_timer_resume, }; +static struct syscore mpic_timer_syscore = { + .ops = &mpic_timer_syscore_ops, +}; + static int __init mpic_timer_init(void) { struct device_node *np = NULL; @@ -546,7 +550,7 @@ static int __init mpic_timer_init(void) for_each_matching_node(np, mpic_timer_ids) timer_group_init(np); - register_syscore_ops(&mpic_timer_syscore_ops); + register_syscore(&mpic_timer_syscore); if (list_empty(&timer_group_list)) return -ENODEV; diff --git a/arch/sh/mm/pmb.c b/arch/sh/mm/pmb.c index 68eb7cc6e564..482eec50f404 100644 --- a/arch/sh/mm/pmb.c +++ b/arch/sh/mm/pmb.c @@ -857,7 +857,7 @@ static int __init pmb_debugfs_init(void) subsys_initcall(pmb_debugfs_init); #ifdef CONFIG_PM -static void pmb_syscore_resume(void) +static void pmb_syscore_resume(void *data) { struct pmb_entry *pmbe; int i; @@ -874,13 +874,17 @@ static void pmb_syscore_resume(void) read_unlock(&pmb_rwlock); } -static struct syscore_ops pmb_syscore_ops = { +static const struct syscore_ops pmb_syscore_ops = { .resume = pmb_syscore_resume, }; +static struct syscore pmb_syscore = { + .ops = &pmb_syscore_ops, +}; + static int __init pmb_sysdev_init(void) { - register_syscore_ops(&pmb_syscore_ops); + register_syscore(&pmb_syscore); return 0; } subsys_initcall(pmb_sysdev_init); diff --git a/arch/x86/events/amd/ibs.c b/arch/x86/events/amd/ibs.c index 112f43b23ebf..aca89f23d2e0 100644 --- a/arch/x86/events/amd/ibs.c +++ b/arch/x86/events/amd/ibs.c @@ -1718,26 +1718,30 @@ static int x86_pmu_amd_ibs_starting_cpu(unsigned int cpu) #ifdef CONFIG_PM -static int perf_ibs_suspend(void) +static int perf_ibs_suspend(void *data) { clear_APIC_ibs(); return 0; } -static void perf_ibs_resume(void) +static void perf_ibs_resume(void *data) { ibs_eilvt_setup(); setup_APIC_ibs(); } -static struct syscore_ops perf_ibs_syscore_ops = { +static const struct syscore_ops perf_ibs_syscore_ops = { .resume = perf_ibs_resume, .suspend = perf_ibs_suspend, }; +static struct syscore perf_ibs_syscore = { + .ops = &perf_ibs_syscore_ops, +}; + static void perf_ibs_pm_init(void) { - register_syscore_ops(&perf_ibs_syscore_ops); + register_syscore(&perf_ibs_syscore); } #else diff --git a/arch/x86/hyperv/hv_init.c b/arch/x86/hyperv/hv_init.c index e890fd37e9c2..085ef4f2e73a 100644 --- a/arch/x86/hyperv/hv_init.c +++ b/arch/x86/hyperv/hv_init.c @@ -351,7 +351,7 @@ static int __init hv_pci_init(void) return 1; } -static int hv_suspend(void) +static int hv_suspend(void *data) { union hv_x64_msr_hypercall_contents hypercall_msr; int ret; @@ -378,7 +378,7 @@ static int hv_suspend(void) return ret; } -static void hv_resume(void) +static void hv_resume(void *data) { union hv_x64_msr_hypercall_contents hypercall_msr; int ret; @@ -405,11 +405,15 @@ static void hv_resume(void) } /* Note: when the ops are called, only CPU0 is online and IRQs are disabled. */ -static struct syscore_ops hv_syscore_ops = { +static const struct syscore_ops hv_syscore_ops = { .suspend = hv_suspend, .resume = hv_resume, }; +static struct syscore hv_syscore = { + .ops = &hv_syscore_ops, +}; + static void (* __initdata old_setup_percpu_clockev)(void); static void __init hv_stimer_setup_percpu_clockev(void) @@ -569,7 +573,7 @@ void __init hyperv_init(void) x86_init.pci.arch_init = hv_pci_init; - register_syscore_ops(&hv_syscore_ops); + register_syscore(&hv_syscore); if (ms_hyperv.priv_high & HV_ACCESS_PARTITION_ID) hv_get_partition_id(); diff --git a/arch/x86/kernel/amd_gart_64.c b/arch/x86/kernel/amd_gart_64.c index 3485d419c2f5..e6e68a31634c 100644 --- a/arch/x86/kernel/amd_gart_64.c +++ b/arch/x86/kernel/amd_gart_64.c @@ -591,7 +591,7 @@ static void gart_fixup_northbridges(void) } } -static void gart_resume(void) +static void gart_resume(void *data) { pr_info("PCI-DMA: Resuming GART IOMMU\n"); @@ -600,11 +600,15 @@ static void gart_resume(void) enable_gart_translations(); } -static struct syscore_ops gart_syscore_ops = { +static const struct syscore_ops gart_syscore_ops = { .resume = gart_resume, }; +static struct syscore gart_syscore = { + .ops = &gart_syscore_ops, +}; + /* * Private Northbridge GATT initialization in case we cannot use the * AGP driver for some reason. @@ -650,7 +654,7 @@ static __init int init_amd_gatt(struct agp_kern_info *info) agp_gatt_table = gatt; - register_syscore_ops(&gart_syscore_ops); + register_syscore(&gart_syscore); flush_gart(); diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c index 680d305589a3..fd87b1562c7e 100644 --- a/arch/x86/kernel/apic/apic.c +++ b/arch/x86/kernel/apic/apic.c @@ -2381,7 +2381,7 @@ static struct { unsigned int apic_cmci; } apic_pm_state; -static int lapic_suspend(void) +static int lapic_suspend(void *data) { unsigned long flags; int maxlvt; @@ -2429,7 +2429,7 @@ static int lapic_suspend(void) return 0; } -static void lapic_resume(void) +static void lapic_resume(void *data) { unsigned int l, h; unsigned long flags; @@ -2504,11 +2504,15 @@ static void lapic_resume(void) * are needed on every CPU up until machine_halt/restart/poweroff. */ -static struct syscore_ops lapic_syscore_ops = { +static const struct syscore_ops lapic_syscore_ops = { .resume = lapic_resume, .suspend = lapic_suspend, }; +static struct syscore lapic_syscore = { + .ops = &lapic_syscore_ops, +}; + static void apic_pm_activate(void) { apic_pm_state.active = 1; @@ -2518,7 +2522,7 @@ static int __init init_lapic_sysfs(void) { /* XXX: remove suspend/resume procs if !apic_pm_state.active? */ if (boot_cpu_has(X86_FEATURE_APIC)) - register_syscore_ops(&lapic_syscore_ops); + register_syscore(&lapic_syscore); return 0; } diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c index 5ba2feb2c04c..84e200662ce6 100644 --- a/arch/x86/kernel/apic/io_apic.c +++ b/arch/x86/kernel/apic/io_apic.c @@ -2308,7 +2308,12 @@ static void resume_ioapic_id(int ioapic_idx) } } -static void ioapic_resume(void) +static int ioapic_suspend(void *data) +{ + return save_ioapic_entries(); +} + +static void ioapic_resume(void *data) { int ioapic_idx; @@ -2318,14 +2323,18 @@ static void ioapic_resume(void) restore_ioapic_entries(); } -static struct syscore_ops ioapic_syscore_ops = { - .suspend = save_ioapic_entries, +static const struct syscore_ops ioapic_syscore_ops = { + .suspend = ioapic_suspend, .resume = ioapic_resume, }; +static struct syscore ioapic_syscore = { + .ops = &ioapic_syscore_ops, +}; + static int __init ioapic_init_ops(void) { - register_syscore_ops(&ioapic_syscore_ops); + register_syscore(&ioapic_syscore); return 0; } diff --git a/arch/x86/kernel/cpu/aperfmperf.c b/arch/x86/kernel/cpu/aperfmperf.c index a315b0627dfb..7ffc78d5ebf2 100644 --- a/arch/x86/kernel/cpu/aperfmperf.c +++ b/arch/x86/kernel/cpu/aperfmperf.c @@ -37,7 +37,7 @@ static DEFINE_PER_CPU_SHARED_ALIGNED(struct aperfmperf, cpu_samples) = { .seq = SEQCNT_ZERO(cpu_samples.seq) }; -static void init_counter_refs(void) +static void init_counter_refs(void *data) { u64 aperf, mperf; @@ -289,16 +289,20 @@ static bool __init intel_set_max_freq_ratio(void) } #ifdef CONFIG_PM_SLEEP -static struct syscore_ops freq_invariance_syscore_ops = { +static const struct syscore_ops freq_invariance_syscore_ops = { .resume = init_counter_refs, }; -static void register_freq_invariance_syscore_ops(void) +static struct syscore freq_invariance_syscore = { + .ops = &freq_invariance_syscore_ops, +}; + +static void register_freq_invariance_syscore(void) { - register_syscore_ops(&freq_invariance_syscore_ops); + register_syscore(&freq_invariance_syscore); } #else -static inline void register_freq_invariance_syscore_ops(void) {} +static inline void register_freq_invariance_syscore(void) {} #endif static void freq_invariance_enable(void) @@ -308,7 +312,7 @@ static void freq_invariance_enable(void) return; } static_branch_enable_cpuslocked(&arch_scale_freq_key); - register_freq_invariance_syscore_ops(); + register_freq_invariance_syscore(); pr_info("Estimated ratio of average max frequency by base frequency (times 1024): %llu\n", arch_max_freq_ratio); } @@ -535,7 +539,7 @@ static int __init bp_init_aperfmperf(void) if (!cpu_feature_enabled(X86_FEATURE_APERFMPERF)) return 0; - init_counter_refs(); + init_counter_refs(NULL); bp_init_freq_invariance(); return 0; } @@ -544,5 +548,5 @@ early_initcall(bp_init_aperfmperf); void ap_init_aperfmperf(void) { if (cpu_feature_enabled(X86_FEATURE_APERFMPERF)) - init_counter_refs(); + init_counter_refs(NULL); } diff --git a/arch/x86/kernel/cpu/intel_epb.c b/arch/x86/kernel/cpu/intel_epb.c index bc7671f920a7..2c56f8730f59 100644 --- a/arch/x86/kernel/cpu/intel_epb.c +++ b/arch/x86/kernel/cpu/intel_epb.c @@ -75,7 +75,7 @@ static u8 energ_perf_values[] = { [EPB_INDEX_POWERSAVE] = ENERGY_PERF_BIAS_POWERSAVE, }; -static int intel_epb_save(void) +static int intel_epb_save(void *data) { u64 epb; @@ -89,7 +89,7 @@ static int intel_epb_save(void) return 0; } -static void intel_epb_restore(void) +static void intel_epb_restore(void *data) { u64 val = this_cpu_read(saved_epb); u64 epb; @@ -114,11 +114,15 @@ static void intel_epb_restore(void) wrmsrq(MSR_IA32_ENERGY_PERF_BIAS, (epb & ~EPB_MASK) | val); } -static struct syscore_ops intel_epb_syscore_ops = { +static const struct syscore_ops intel_epb_syscore_ops = { .suspend = intel_epb_save, .resume = intel_epb_restore, }; +static struct syscore intel_epb_syscore = { + .ops = &intel_epb_syscore_ops, +}; + static const char * const energy_perf_strings[] = { [EPB_INDEX_PERFORMANCE] = "performance", [EPB_INDEX_BALANCE_PERFORMANCE] = "balance-performance", @@ -185,7 +189,7 @@ static int intel_epb_online(unsigned int cpu) { struct device *cpu_dev = get_cpu_device(cpu); - intel_epb_restore(); + intel_epb_restore(NULL); if (!cpuhp_tasks_frozen) sysfs_merge_group(&cpu_dev->kobj, &intel_epb_attr_group); @@ -199,7 +203,7 @@ static int intel_epb_offline(unsigned int cpu) if (!cpuhp_tasks_frozen) sysfs_unmerge_group(&cpu_dev->kobj, &intel_epb_attr_group); - intel_epb_save(); + intel_epb_save(NULL); return 0; } @@ -230,7 +234,7 @@ static __init int intel_epb_init(void) if (ret < 0) goto err_out_online; - register_syscore_ops(&intel_epb_syscore_ops); + register_syscore(&intel_epb_syscore); return 0; err_out_online: diff --git a/arch/x86/kernel/cpu/mce/core.c b/arch/x86/kernel/cpu/mce/core.c index 460e90a1a0b1..23bfbc7dfb8e 100644 --- a/arch/x86/kernel/cpu/mce/core.c +++ b/arch/x86/kernel/cpu/mce/core.c @@ -2410,13 +2410,13 @@ static void vendor_disable_error_reporting(void) mce_disable_error_reporting(); } -static int mce_syscore_suspend(void) +static int mce_syscore_suspend(void *data) { vendor_disable_error_reporting(); return 0; } -static void mce_syscore_shutdown(void) +static void mce_syscore_shutdown(void *data) { vendor_disable_error_reporting(); } @@ -2426,7 +2426,7 @@ static void mce_syscore_shutdown(void) * Only one CPU is active at this time, the others get re-added later using * CPU hotplug: */ -static void mce_syscore_resume(void) +static void mce_syscore_resume(void *data) { __mcheck_cpu_init_generic(); __mcheck_cpu_init_vendor(raw_cpu_ptr(&cpu_info)); @@ -2434,12 +2434,16 @@ static void mce_syscore_resume(void) cr4_set_bits(X86_CR4_MCE); } -static struct syscore_ops mce_syscore_ops = { +static const struct syscore_ops mce_syscore_ops = { .suspend = mce_syscore_suspend, .shutdown = mce_syscore_shutdown, .resume = mce_syscore_resume, }; +static struct syscore mce_syscore = { + .ops = &mce_syscore_ops, +}; + /* * mce_device: Sysfs support */ @@ -2840,7 +2844,7 @@ static __init int mcheck_init_device(void) if (err < 0) goto err_out_online; - register_syscore_ops(&mce_syscore_ops); + register_syscore(&mce_syscore); return 0; diff --git a/arch/x86/kernel/cpu/microcode/core.c b/arch/x86/kernel/cpu/microcode/core.c index f75c140906d0..3262756f8c32 100644 --- a/arch/x86/kernel/cpu/microcode/core.c +++ b/arch/x86/kernel/cpu/microcode/core.c @@ -812,8 +812,17 @@ void microcode_bsp_resume(void) reload_early_microcode(cpu); } -static struct syscore_ops mc_syscore_ops = { - .resume = microcode_bsp_resume, +static void microcode_bsp_syscore_resume(void *data) +{ + microcode_bsp_resume(); +} + +static const struct syscore_ops mc_syscore_ops = { + .resume = microcode_bsp_syscore_resume, +}; + +static struct syscore mc_syscore = { + .ops = &mc_syscore_ops, }; static int mc_cpu_online(unsigned int cpu) @@ -892,7 +901,7 @@ static int __init microcode_init(void) } } - register_syscore_ops(&mc_syscore_ops); + register_syscore(&mc_syscore); cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "x86/microcode:online", mc_cpu_online, mc_cpu_down_prep); diff --git a/arch/x86/kernel/cpu/mtrr/legacy.c b/arch/x86/kernel/cpu/mtrr/legacy.c index d25882fcf181..2415ffaaf02c 100644 --- a/arch/x86/kernel/cpu/mtrr/legacy.c +++ b/arch/x86/kernel/cpu/mtrr/legacy.c @@ -41,7 +41,7 @@ struct mtrr_value { static struct mtrr_value *mtrr_value; -static int mtrr_save(void) +static int mtrr_save(void *data) { int i; @@ -56,7 +56,7 @@ static int mtrr_save(void) return 0; } -static void mtrr_restore(void) +static void mtrr_restore(void *data) { int i; @@ -69,11 +69,15 @@ static void mtrr_restore(void) } } -static struct syscore_ops mtrr_syscore_ops = { +static const struct syscore_ops mtrr_syscore_ops = { .suspend = mtrr_save, .resume = mtrr_restore, }; +static struct syscore mtrr_syscore = { + .ops = &mtrr_syscore_ops, +}; + void mtrr_register_syscore(void) { mtrr_value = kcalloc(num_var_ranges, sizeof(*mtrr_value), GFP_KERNEL); @@ -86,5 +90,5 @@ void mtrr_register_syscore(void) * TBD: is there any system with such CPU which supports * suspend/resume? If no, we should remove the code. */ - register_syscore_ops(&mtrr_syscore_ops); + register_syscore(&mtrr_syscore); } diff --git a/arch/x86/kernel/cpu/umwait.c b/arch/x86/kernel/cpu/umwait.c index 933fcd7ff250..e4a31c536642 100644 --- a/arch/x86/kernel/cpu/umwait.c +++ b/arch/x86/kernel/cpu/umwait.c @@ -86,15 +86,19 @@ static int umwait_cpu_offline(unsigned int cpu) * trust the firmware nor does it matter if the same value is written * again. */ -static void umwait_syscore_resume(void) +static void umwait_syscore_resume(void *data) { umwait_update_control_msr(NULL); } -static struct syscore_ops umwait_syscore_ops = { +static const struct syscore_ops umwait_syscore_ops = { .resume = umwait_syscore_resume, }; +static struct syscore umwait_syscore = { + .ops = &umwait_syscore_ops, +}; + /* sysfs interface */ /* @@ -226,7 +230,7 @@ static int __init umwait_init(void) return ret; } - register_syscore_ops(&umwait_syscore_ops); + register_syscore(&umwait_syscore); /* * Add umwait control interface. Ignore failure, so at least the diff --git a/arch/x86/kernel/i8237.c b/arch/x86/kernel/i8237.c index 2cd124ad9380..896d46b44284 100644 --- a/arch/x86/kernel/i8237.c +++ b/arch/x86/kernel/i8237.c @@ -19,7 +19,7 @@ * in asm/dma.h. */ -static void i8237A_resume(void) +static void i8237A_resume(void *data) { unsigned long flags; int i; @@ -41,10 +41,14 @@ static void i8237A_resume(void) release_dma_lock(flags); } -static struct syscore_ops i8237_syscore_ops = { +static const struct syscore_ops i8237_syscore_ops = { .resume = i8237A_resume, }; +static struct syscore i8237_syscore = { + .ops = &i8237_syscore_ops, +}; + static int __init i8237A_init_ops(void) { /* @@ -70,7 +74,7 @@ static int __init i8237A_init_ops(void) if (x86_pnpbios_disabled() && dmi_get_bios_year() >= 2017) return -ENODEV; - register_syscore_ops(&i8237_syscore_ops); + register_syscore(&i8237_syscore); return 0; } device_initcall(i8237A_init_ops); diff --git a/arch/x86/kernel/i8259.c b/arch/x86/kernel/i8259.c index 2bade73f49e3..f67063df6723 100644 --- a/arch/x86/kernel/i8259.c +++ b/arch/x86/kernel/i8259.c @@ -247,19 +247,19 @@ static void save_ELCR(char *trigger) trigger[1] = inb(PIC_ELCR2) & 0xDE; } -static void i8259A_resume(void) +static void i8259A_resume(void *data) { init_8259A(i8259A_auto_eoi); restore_ELCR(irq_trigger); } -static int i8259A_suspend(void) +static int i8259A_suspend(void *data) { save_ELCR(irq_trigger); return 0; } -static void i8259A_shutdown(void) +static void i8259A_shutdown(void *data) { /* Put the i8259A into a quiescent state that * the kernel initialization code can get it @@ -269,12 +269,16 @@ static void i8259A_shutdown(void) outb(0xff, PIC_SLAVE_IMR); /* mask all of 8259A-2 */ } -static struct syscore_ops i8259_syscore_ops = { +static const struct syscore_ops i8259_syscore_ops = { .suspend = i8259A_suspend, .resume = i8259A_resume, .shutdown = i8259A_shutdown, }; +static struct syscore i8259_syscore = { + .ops = &i8259_syscore_ops, +}; + static void mask_8259A(void) { unsigned long flags; @@ -444,7 +448,7 @@ EXPORT_SYMBOL(legacy_pic); static int __init i8259A_init_ops(void) { if (legacy_pic == &default_legacy_pic) - register_syscore_ops(&i8259_syscore_ops); + register_syscore(&i8259_syscore); return 0; } diff --git a/arch/x86/kernel/kvm.c b/arch/x86/kernel/kvm.c index b67d7c59dca0..1500852ba03c 100644 --- a/arch/x86/kernel/kvm.c +++ b/arch/x86/kernel/kvm.c @@ -720,7 +720,7 @@ static int kvm_cpu_down_prepare(unsigned int cpu) #endif -static int kvm_suspend(void) +static int kvm_suspend(void *data) { u64 val = 0; @@ -734,7 +734,7 @@ static int kvm_suspend(void) return 0; } -static void kvm_resume(void) +static void kvm_resume(void *data) { kvm_cpu_online(raw_smp_processor_id()); @@ -744,11 +744,15 @@ static void kvm_resume(void) #endif } -static struct syscore_ops kvm_syscore_ops = { +static const struct syscore_ops kvm_syscore_ops = { .suspend = kvm_suspend, .resume = kvm_resume, }; +static struct syscore kvm_syscore = { + .ops = &kvm_syscore_ops, +}; + static void kvm_pv_guest_cpu_reboot(void *unused) { kvm_guest_cpu_offline(true); @@ -858,7 +862,7 @@ static void __init kvm_guest_init(void) machine_ops.crash_shutdown = kvm_crash_shutdown; #endif - register_syscore_ops(&kvm_syscore_ops); + register_syscore(&kvm_syscore); /* * Hard lockup detection is enabled by default. Disable it, as guests diff --git a/drivers/acpi/pci_link.c b/drivers/acpi/pci_link.c index e4560b33b8ad..bed7dc85612e 100644 --- a/drivers/acpi/pci_link.c +++ b/drivers/acpi/pci_link.c @@ -761,7 +761,7 @@ static int acpi_pci_link_resume(struct acpi_pci_link *link) return 0; } -static void irqrouter_resume(void) +static void irqrouter_resume(void *data) { struct acpi_pci_link *link; @@ -888,10 +888,14 @@ static int __init acpi_irq_balance_set(char *str) __setup("acpi_irq_balance", acpi_irq_balance_set); -static struct syscore_ops irqrouter_syscore_ops = { +static const struct syscore_ops irqrouter_syscore_ops = { .resume = irqrouter_resume, }; +static struct syscore irqrouter_syscore = { + .ops = &irqrouter_syscore_ops, +}; + void __init acpi_pci_link_init(void) { if (acpi_noirq) @@ -904,6 +908,6 @@ void __init acpi_pci_link_init(void) else acpi_irq_balance = 0; } - register_syscore_ops(&irqrouter_syscore_ops); + register_syscore(&irqrouter_syscore); acpi_scan_add_handler(&pci_link_handler); } diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c index c8ee8e42b0f6..aaf57d0aaa19 100644 --- a/drivers/acpi/sleep.c +++ b/drivers/acpi/sleep.c @@ -884,13 +884,13 @@ bool acpi_s2idle_wakeup(void) #ifdef CONFIG_PM_SLEEP static u32 saved_bm_rld; -static int acpi_save_bm_rld(void) +static int acpi_save_bm_rld(void *data) { acpi_read_bit_register(ACPI_BITREG_BUS_MASTER_RLD, &saved_bm_rld); return 0; } -static void acpi_restore_bm_rld(void) +static void acpi_restore_bm_rld(void *data) { u32 resumed_bm_rld = 0; @@ -901,14 +901,18 @@ static void acpi_restore_bm_rld(void) acpi_write_bit_register(ACPI_BITREG_BUS_MASTER_RLD, saved_bm_rld); } -static struct syscore_ops acpi_sleep_syscore_ops = { +static const struct syscore_ops acpi_sleep_syscore_ops = { .suspend = acpi_save_bm_rld, .resume = acpi_restore_bm_rld, }; +static struct syscore acpi_sleep_syscore = { + .ops = &acpi_sleep_syscore_ops, +}; + static void acpi_sleep_syscore_init(void) { - register_syscore_ops(&acpi_sleep_syscore_ops); + register_syscore(&acpi_sleep_syscore); } #else static inline void acpi_sleep_syscore_init(void) {} diff --git a/drivers/base/firmware_loader/main.c b/drivers/base/firmware_loader/main.c index 6942c62fa59d..8191dbab92c4 100644 --- a/drivers/base/firmware_loader/main.c +++ b/drivers/base/firmware_loader/main.c @@ -1585,16 +1585,20 @@ static int fw_pm_notify(struct notifier_block *notify_block, } /* stop caching firmware once syscore_suspend is reached */ -static int fw_suspend(void) +static int fw_suspend(void *data) { fw_cache.state = FW_LOADER_NO_CACHE; return 0; } -static struct syscore_ops fw_syscore_ops = { +static const struct syscore_ops fw_syscore_ops = { .suspend = fw_suspend, }; +static struct syscore fw_syscore = { + .ops = &fw_syscore_ops, +}; + static int __init register_fw_pm_ops(void) { int ret; @@ -1610,14 +1614,14 @@ static int __init register_fw_pm_ops(void) if (ret) return ret; - register_syscore_ops(&fw_syscore_ops); + register_syscore(&fw_syscore); return ret; } static inline void unregister_fw_pm_ops(void) { - unregister_syscore_ops(&fw_syscore_ops); + unregister_syscore(&fw_syscore); unregister_pm_notifier(&fw_cache.pm_notify); } #else diff --git a/drivers/base/syscore.c b/drivers/base/syscore.c index 13db1f78d2ce..483adb796654 100644 --- a/drivers/base/syscore.c +++ b/drivers/base/syscore.c @@ -11,32 +11,32 @@ #include #include -static LIST_HEAD(syscore_ops_list); -static DEFINE_MUTEX(syscore_ops_lock); +static LIST_HEAD(syscore_list); +static DEFINE_MUTEX(syscore_lock); /** - * register_syscore_ops - Register a set of system core operations. - * @ops: System core operations to register. + * register_syscore - Register a set of system core operations. + * @syscore: System core operations to register. */ -void register_syscore_ops(struct syscore_ops *ops) +void register_syscore(struct syscore *syscore) { - mutex_lock(&syscore_ops_lock); - list_add_tail(&ops->node, &syscore_ops_list); - mutex_unlock(&syscore_ops_lock); + mutex_lock(&syscore_lock); + list_add_tail(&syscore->node, &syscore_list); + mutex_unlock(&syscore_lock); } -EXPORT_SYMBOL_GPL(register_syscore_ops); +EXPORT_SYMBOL_GPL(register_syscore); /** - * unregister_syscore_ops - Unregister a set of system core operations. - * @ops: System core operations to unregister. + * unregister_syscore - Unregister a set of system core operations. + * @syscore: System core operations to unregister. */ -void unregister_syscore_ops(struct syscore_ops *ops) +void unregister_syscore(struct syscore *syscore) { - mutex_lock(&syscore_ops_lock); - list_del(&ops->node); - mutex_unlock(&syscore_ops_lock); + mutex_lock(&syscore_lock); + list_del(&syscore->node); + mutex_unlock(&syscore_lock); } -EXPORT_SYMBOL_GPL(unregister_syscore_ops); +EXPORT_SYMBOL_GPL(unregister_syscore); #ifdef CONFIG_PM_SLEEP /** @@ -46,7 +46,7 @@ EXPORT_SYMBOL_GPL(unregister_syscore_ops); */ int syscore_suspend(void) { - struct syscore_ops *ops; + struct syscore *syscore; int ret = 0; trace_suspend_resume(TPS("syscore_suspend"), 0, true); @@ -59,25 +59,27 @@ int syscore_suspend(void) WARN_ONCE(!irqs_disabled(), "Interrupts enabled before system core suspend.\n"); - list_for_each_entry_reverse(ops, &syscore_ops_list, node) - if (ops->suspend) { - pm_pr_dbg("Calling %pS\n", ops->suspend); - ret = ops->suspend(); + list_for_each_entry_reverse(syscore, &syscore_list, node) + if (syscore->ops->suspend) { + pm_pr_dbg("Calling %pS\n", syscore->ops->suspend); + ret = syscore->ops->suspend(syscore->data); if (ret) goto err_out; WARN_ONCE(!irqs_disabled(), - "Interrupts enabled after %pS\n", ops->suspend); + "Interrupts enabled after %pS\n", + syscore->ops->suspend); } trace_suspend_resume(TPS("syscore_suspend"), 0, false); return 0; err_out: - pr_err("PM: System core suspend callback %pS failed.\n", ops->suspend); + pr_err("PM: System core suspend callback %pS failed.\n", + syscore->ops->suspend); - list_for_each_entry_continue(ops, &syscore_ops_list, node) - if (ops->resume) - ops->resume(); + list_for_each_entry_continue(syscore, &syscore_list, node) + if (syscore->ops->resume) + syscore->ops->resume(syscore->data); return ret; } @@ -90,18 +92,19 @@ EXPORT_SYMBOL_GPL(syscore_suspend); */ void syscore_resume(void) { - struct syscore_ops *ops; + struct syscore *syscore; trace_suspend_resume(TPS("syscore_resume"), 0, true); WARN_ONCE(!irqs_disabled(), "Interrupts enabled before system core resume.\n"); - list_for_each_entry(ops, &syscore_ops_list, node) - if (ops->resume) { - pm_pr_dbg("Calling %pS\n", ops->resume); - ops->resume(); + list_for_each_entry(syscore, &syscore_list, node) + if (syscore->ops->resume) { + pm_pr_dbg("Calling %pS\n", syscore->ops->resume); + syscore->ops->resume(syscore->data); WARN_ONCE(!irqs_disabled(), - "Interrupts enabled after %pS\n", ops->resume); + "Interrupts enabled after %pS\n", + syscore->ops->resume); } trace_suspend_resume(TPS("syscore_resume"), 0, false); } @@ -113,16 +116,17 @@ EXPORT_SYMBOL_GPL(syscore_resume); */ void syscore_shutdown(void) { - struct syscore_ops *ops; + struct syscore *syscore; - mutex_lock(&syscore_ops_lock); + mutex_lock(&syscore_lock); - list_for_each_entry_reverse(ops, &syscore_ops_list, node) - if (ops->shutdown) { + list_for_each_entry_reverse(syscore, &syscore_list, node) + if (syscore->ops->shutdown) { if (initcall_debug) - pr_info("PM: Calling %pS\n", ops->shutdown); - ops->shutdown(); + pr_info("PM: Calling %pS\n", + syscore->ops->shutdown); + syscore->ops->shutdown(syscore->data); } - mutex_unlock(&syscore_ops_lock); + mutex_unlock(&syscore_lock); } diff --git a/drivers/bus/mvebu-mbus.c b/drivers/bus/mvebu-mbus.c index 00cb792bda18..dd94145c9b22 100644 --- a/drivers/bus/mvebu-mbus.c +++ b/drivers/bus/mvebu-mbus.c @@ -1006,7 +1006,7 @@ static __init int mvebu_mbus_debugfs_init(void) } fs_initcall(mvebu_mbus_debugfs_init); -static int mvebu_mbus_suspend(void) +static int mvebu_mbus_suspend(void *data) { struct mvebu_mbus_state *s = &mbus_state; int win; @@ -1040,7 +1040,7 @@ static int mvebu_mbus_suspend(void) return 0; } -static void mvebu_mbus_resume(void) +static void mvebu_mbus_resume(void *data) { struct mvebu_mbus_state *s = &mbus_state; int win; @@ -1069,9 +1069,13 @@ static void mvebu_mbus_resume(void) } } -static struct syscore_ops mvebu_mbus_syscore_ops = { - .suspend = mvebu_mbus_suspend, - .resume = mvebu_mbus_resume, +static const struct syscore_ops mvebu_mbus_syscore_ops = { + .suspend = mvebu_mbus_suspend, + .resume = mvebu_mbus_resume, +}; + +static struct syscore mvebu_mbus_syscore = { + .ops = &mvebu_mbus_syscore_ops, }; static int __init mvebu_mbus_common_init(struct mvebu_mbus_state *mbus, @@ -1118,7 +1122,7 @@ static int __init mvebu_mbus_common_init(struct mvebu_mbus_state *mbus, writel(UNIT_SYNC_BARRIER_ALL, mbus->mbuswins_base + UNIT_SYNC_BARRIER_OFF); - register_syscore_ops(&mvebu_mbus_syscore_ops); + register_syscore(&mvebu_mbus_syscore); return 0; } diff --git a/drivers/clk/at91/pmc.c b/drivers/clk/at91/pmc.c index acf780a81589..2310f6f73162 100644 --- a/drivers/clk/at91/pmc.c +++ b/drivers/clk/at91/pmc.c @@ -115,7 +115,7 @@ struct pmc_data *pmc_data_allocate(unsigned int ncore, unsigned int nsystem, /* Address in SECURAM that say if we suspend to backup mode. */ static void __iomem *at91_pmc_backup_suspend; -static int at91_pmc_suspend(void) +static int at91_pmc_suspend(void *data) { unsigned int backup; @@ -129,7 +129,7 @@ static int at91_pmc_suspend(void) return clk_save_context(); } -static void at91_pmc_resume(void) +static void at91_pmc_resume(void *data) { unsigned int backup; @@ -143,11 +143,15 @@ static void at91_pmc_resume(void) clk_restore_context(); } -static struct syscore_ops pmc_syscore_ops = { +static const struct syscore_ops pmc_syscore_ops = { .suspend = at91_pmc_suspend, .resume = at91_pmc_resume, }; +static struct syscore pmc_syscore = { + .ops = &pmc_syscore_ops, +}; + static const struct of_device_id pmc_dt_ids[] = { { .compatible = "atmel,sama5d2-pmc" }, { .compatible = "microchip,sama7g5-pmc", }, @@ -185,7 +189,7 @@ static int __init pmc_register_ops(void) return -ENOMEM; } - register_syscore_ops(&pmc_syscore_ops); + register_syscore(&pmc_syscore); return 0; } diff --git a/drivers/clk/imx/clk-vf610.c b/drivers/clk/imx/clk-vf610.c index 9e11f1c7c397..41eb38552a9c 100644 --- a/drivers/clk/imx/clk-vf610.c +++ b/drivers/clk/imx/clk-vf610.c @@ -139,7 +139,7 @@ static struct clk * __init vf610_get_fixed_clock( return clk; }; -static int vf610_clk_suspend(void) +static int vf610_clk_suspend(void *data) { int i; @@ -156,7 +156,7 @@ static int vf610_clk_suspend(void) return 0; } -static void vf610_clk_resume(void) +static void vf610_clk_resume(void *data) { int i; @@ -171,11 +171,15 @@ static void vf610_clk_resume(void) writel_relaxed(ccgr[i], CCM_CCGRx(i)); } -static struct syscore_ops vf610_clk_syscore_ops = { +static const struct syscore_ops vf610_clk_syscore_ops = { .suspend = vf610_clk_suspend, .resume = vf610_clk_resume, }; +static struct syscore vf610_clk_syscore = { + .ops = &vf610_clk_syscore_ops, +}; + static void __init vf610_clocks_init(struct device_node *ccm_node) { struct device_node *np; @@ -462,7 +466,7 @@ static void __init vf610_clocks_init(struct device_node *ccm_node) for (i = 0; i < ARRAY_SIZE(clks_init_on); i++) clk_prepare_enable(clk[clks_init_on[i]]); - register_syscore_ops(&vf610_clk_syscore_ops); + register_syscore(&vf610_clk_syscore); /* Add the clocks to provider list */ clk_data.clks = clk; diff --git a/drivers/clk/ingenic/jz4725b-cgu.c b/drivers/clk/ingenic/jz4725b-cgu.c index 590e9c85cb25..94cee44c854f 100644 --- a/drivers/clk/ingenic/jz4725b-cgu.c +++ b/drivers/clk/ingenic/jz4725b-cgu.c @@ -268,6 +268,6 @@ static void __init jz4725b_cgu_init(struct device_node *np) if (retval) pr_err("%s: failed to register CGU Clocks\n", __func__); - ingenic_cgu_register_syscore_ops(cgu); + ingenic_cgu_register_syscore(cgu); } CLK_OF_DECLARE_DRIVER(jz4725b_cgu, "ingenic,jz4725b-cgu", jz4725b_cgu_init); diff --git a/drivers/clk/ingenic/jz4740-cgu.c b/drivers/clk/ingenic/jz4740-cgu.c index 3e0a30574ebb..2def3aedc8dd 100644 --- a/drivers/clk/ingenic/jz4740-cgu.c +++ b/drivers/clk/ingenic/jz4740-cgu.c @@ -266,6 +266,6 @@ static void __init jz4740_cgu_init(struct device_node *np) if (retval) pr_err("%s: failed to register CGU Clocks\n", __func__); - ingenic_cgu_register_syscore_ops(cgu); + ingenic_cgu_register_syscore(cgu); } CLK_OF_DECLARE_DRIVER(jz4740_cgu, "ingenic,jz4740-cgu", jz4740_cgu_init); diff --git a/drivers/clk/ingenic/jz4755-cgu.c b/drivers/clk/ingenic/jz4755-cgu.c index f2c2d848dab7..17cf5dcaece9 100644 --- a/drivers/clk/ingenic/jz4755-cgu.c +++ b/drivers/clk/ingenic/jz4755-cgu.c @@ -337,7 +337,7 @@ static void __init jz4755_cgu_init(struct device_node *np) if (retval) pr_err("%s: failed to register CGU Clocks\n", __func__); - ingenic_cgu_register_syscore_ops(cgu); + ingenic_cgu_register_syscore(cgu); } /* * CGU has some children devices, this is useful for probing children devices diff --git a/drivers/clk/ingenic/jz4760-cgu.c b/drivers/clk/ingenic/jz4760-cgu.c index e407f00bd594..372fe4b07992 100644 --- a/drivers/clk/ingenic/jz4760-cgu.c +++ b/drivers/clk/ingenic/jz4760-cgu.c @@ -436,7 +436,7 @@ static void __init jz4760_cgu_init(struct device_node *np) if (retval) pr_err("%s: failed to register CGU Clocks\n", __func__); - ingenic_cgu_register_syscore_ops(cgu); + ingenic_cgu_register_syscore(cgu); } /* We only probe via devicetree, no need for a platform driver */ diff --git a/drivers/clk/ingenic/jz4770-cgu.c b/drivers/clk/ingenic/jz4770-cgu.c index 6ae1740367f9..58f1d3bad677 100644 --- a/drivers/clk/ingenic/jz4770-cgu.c +++ b/drivers/clk/ingenic/jz4770-cgu.c @@ -456,7 +456,7 @@ static void __init jz4770_cgu_init(struct device_node *np) if (retval) pr_err("%s: failed to register CGU Clocks\n", __func__); - ingenic_cgu_register_syscore_ops(cgu); + ingenic_cgu_register_syscore(cgu); } /* We only probe via devicetree, no need for a platform driver */ diff --git a/drivers/clk/ingenic/jz4780-cgu.c b/drivers/clk/ingenic/jz4780-cgu.c index 07e2f3c5c454..1e88aef7ac0f 100644 --- a/drivers/clk/ingenic/jz4780-cgu.c +++ b/drivers/clk/ingenic/jz4780-cgu.c @@ -803,6 +803,6 @@ static void __init jz4780_cgu_init(struct device_node *np) return; } - ingenic_cgu_register_syscore_ops(cgu); + ingenic_cgu_register_syscore(cgu); } CLK_OF_DECLARE_DRIVER(jz4780_cgu, "ingenic,jz4780-cgu", jz4780_cgu_init); diff --git a/drivers/clk/ingenic/pm.c b/drivers/clk/ingenic/pm.c index 341752b640d2..206d5cf2872f 100644 --- a/drivers/clk/ingenic/pm.c +++ b/drivers/clk/ingenic/pm.c @@ -15,7 +15,7 @@ static void __iomem * __maybe_unused ingenic_cgu_base; -static int __maybe_unused ingenic_cgu_pm_suspend(void) +static int __maybe_unused ingenic_cgu_pm_suspend(void *data) { u32 val = readl(ingenic_cgu_base + CGU_REG_LCR); @@ -24,22 +24,26 @@ static int __maybe_unused ingenic_cgu_pm_suspend(void) return 0; } -static void __maybe_unused ingenic_cgu_pm_resume(void) +static void __maybe_unused ingenic_cgu_pm_resume(void *data) { u32 val = readl(ingenic_cgu_base + CGU_REG_LCR); writel(val & ~LCR_LOW_POWER_MODE, ingenic_cgu_base + CGU_REG_LCR); } -static struct syscore_ops __maybe_unused ingenic_cgu_pm_ops = { +static const struct syscore_ops __maybe_unused ingenic_cgu_pm_ops = { .suspend = ingenic_cgu_pm_suspend, .resume = ingenic_cgu_pm_resume, }; -void ingenic_cgu_register_syscore_ops(struct ingenic_cgu *cgu) +static struct syscore __maybe_unused ingenic_cgu_pm = { + .ops = &ingenic_cgu_pm_ops, +}; + +void ingenic_cgu_register_syscore(struct ingenic_cgu *cgu) { if (IS_ENABLED(CONFIG_PM_SLEEP)) { ingenic_cgu_base = cgu->base; - register_syscore_ops(&ingenic_cgu_pm_ops); + register_syscore(&ingenic_cgu_pm); } } diff --git a/drivers/clk/ingenic/pm.h b/drivers/clk/ingenic/pm.h index fa7540407b6b..0dcb57dc64cb 100644 --- a/drivers/clk/ingenic/pm.h +++ b/drivers/clk/ingenic/pm.h @@ -7,6 +7,6 @@ struct ingenic_cgu; -void ingenic_cgu_register_syscore_ops(struct ingenic_cgu *cgu); +void ingenic_cgu_register_syscore(struct ingenic_cgu *cgu); #endif /* DRIVERS_CLK_INGENIC_PM_H */ diff --git a/drivers/clk/ingenic/tcu.c b/drivers/clk/ingenic/tcu.c index 7d04ef40b7cf..bc6a51da2072 100644 --- a/drivers/clk/ingenic/tcu.c +++ b/drivers/clk/ingenic/tcu.c @@ -455,7 +455,7 @@ static int __init ingenic_tcu_probe(struct device_node *np) return ret; } -static int __maybe_unused tcu_pm_suspend(void) +static int __maybe_unused tcu_pm_suspend(void *data) { struct ingenic_tcu *tcu = ingenic_tcu; @@ -465,7 +465,7 @@ static int __maybe_unused tcu_pm_suspend(void) return 0; } -static void __maybe_unused tcu_pm_resume(void) +static void __maybe_unused tcu_pm_resume(void *data) { struct ingenic_tcu *tcu = ingenic_tcu; @@ -473,11 +473,15 @@ static void __maybe_unused tcu_pm_resume(void) clk_enable(tcu->clk); } -static struct syscore_ops __maybe_unused tcu_pm_ops = { +static const struct syscore_ops __maybe_unused tcu_pm_ops = { .suspend = tcu_pm_suspend, .resume = tcu_pm_resume, }; +static struct syscore __maybe_unused tcu_pm = { + .ops = &tcu_pm_ops, +}; + static void __init ingenic_tcu_init(struct device_node *np) { int ret = ingenic_tcu_probe(np); @@ -486,7 +490,7 @@ static void __init ingenic_tcu_init(struct device_node *np) pr_crit("Failed to initialize TCU clocks: %d\n", ret); if (IS_ENABLED(CONFIG_PM_SLEEP)) - register_syscore_ops(&tcu_pm_ops); + register_syscore(&tcu_pm); } CLK_OF_DECLARE_DRIVER(jz4740_cgu, "ingenic,jz4740-tcu", ingenic_tcu_init); diff --git a/drivers/clk/ingenic/x1000-cgu.c b/drivers/clk/ingenic/x1000-cgu.c index d80886caf393..d89bdfb7c219 100644 --- a/drivers/clk/ingenic/x1000-cgu.c +++ b/drivers/clk/ingenic/x1000-cgu.c @@ -556,7 +556,7 @@ static void __init x1000_cgu_init(struct device_node *np) return; } - ingenic_cgu_register_syscore_ops(cgu); + ingenic_cgu_register_syscore(cgu); } /* * CGU has some children devices, this is useful for probing children devices diff --git a/drivers/clk/ingenic/x1830-cgu.c b/drivers/clk/ingenic/x1830-cgu.c index 0fd46e50a513..acf856e5009e 100644 --- a/drivers/clk/ingenic/x1830-cgu.c +++ b/drivers/clk/ingenic/x1830-cgu.c @@ -463,7 +463,7 @@ static void __init x1830_cgu_init(struct device_node *np) return; } - ingenic_cgu_register_syscore_ops(cgu); + ingenic_cgu_register_syscore(cgu); } /* * CGU has some children devices, this is useful for probing children devices diff --git a/drivers/clk/mvebu/common.c b/drivers/clk/mvebu/common.c index 785dbede4835..5adbbd91a6db 100644 --- a/drivers/clk/mvebu/common.c +++ b/drivers/clk/mvebu/common.c @@ -215,22 +215,26 @@ static struct clk *clk_gating_get_src( return ERR_PTR(-ENODEV); } -static int mvebu_clk_gating_suspend(void) +static int mvebu_clk_gating_suspend(void *data) { ctrl->saved_reg = readl(ctrl->base); return 0; } -static void mvebu_clk_gating_resume(void) +static void mvebu_clk_gating_resume(void *data) { writel(ctrl->saved_reg, ctrl->base); } -static struct syscore_ops clk_gate_syscore_ops = { +static const struct syscore_ops clk_gate_syscore_ops = { .suspend = mvebu_clk_gating_suspend, .resume = mvebu_clk_gating_resume, }; +static struct syscore clk_gate_syscore = { + .ops = &clk_gate_syscore_ops, +}; + void __init mvebu_clk_gating_setup(struct device_node *np, const struct clk_gating_soc_desc *desc) { @@ -284,7 +288,7 @@ void __init mvebu_clk_gating_setup(struct device_node *np, of_clk_add_provider(np, clk_gating_get_src, ctrl); - register_syscore_ops(&clk_gate_syscore_ops); + register_syscore(&clk_gate_syscore); return; gates_out: diff --git a/drivers/clk/rockchip/clk-rk3288.c b/drivers/clk/rockchip/clk-rk3288.c index 0a1e017df7c6..9cf3e1e43b78 100644 --- a/drivers/clk/rockchip/clk-rk3288.c +++ b/drivers/clk/rockchip/clk-rk3288.c @@ -871,7 +871,7 @@ static const int rk3288_saved_cru_reg_ids[] = { static u32 rk3288_saved_cru_regs[ARRAY_SIZE(rk3288_saved_cru_reg_ids)]; -static int rk3288_clk_suspend(void) +static int rk3288_clk_suspend(void *data) { int i, reg_id; @@ -906,7 +906,7 @@ static int rk3288_clk_suspend(void) return 0; } -static void rk3288_clk_resume(void) +static void rk3288_clk_resume(void *data) { int i, reg_id; @@ -923,11 +923,15 @@ static void rk3288_clk_shutdown(void) writel_relaxed(0xf3030000, rk3288_cru_base + RK3288_MODE_CON); } -static struct syscore_ops rk3288_clk_syscore_ops = { +static const struct syscore_ops rk3288_clk_syscore_ops = { .suspend = rk3288_clk_suspend, .resume = rk3288_clk_resume, }; +static struct syscore rk3288_clk_syscore = { + .ops = &rk3288_clk_syscore_ops, +}; + static void __init rk3288_common_init(struct device_node *np, enum rk3288_variant soc) { @@ -976,7 +980,7 @@ static void __init rk3288_common_init(struct device_node *np, rockchip_register_restart_notifier(ctx, RK3288_GLB_SRST_FST, rk3288_clk_shutdown); - register_syscore_ops(&rk3288_clk_syscore_ops); + register_syscore(&rk3288_clk_syscore); rockchip_clk_of_add_provider(np, ctx); } diff --git a/drivers/clk/samsung/clk-s5pv210-audss.c b/drivers/clk/samsung/clk-s5pv210-audss.c index b1fd8fac3a4c..c9fcb23de183 100644 --- a/drivers/clk/samsung/clk-s5pv210-audss.c +++ b/drivers/clk/samsung/clk-s5pv210-audss.c @@ -36,7 +36,7 @@ static unsigned long reg_save[][2] = { {ASS_CLK_GATE, 0}, }; -static int s5pv210_audss_clk_suspend(void) +static int s5pv210_audss_clk_suspend(void *data) { int i; @@ -46,7 +46,7 @@ static int s5pv210_audss_clk_suspend(void) return 0; } -static void s5pv210_audss_clk_resume(void) +static void s5pv210_audss_clk_resume(void *data) { int i; @@ -54,10 +54,14 @@ static void s5pv210_audss_clk_resume(void) writel(reg_save[i][1], reg_base + reg_save[i][0]); } -static struct syscore_ops s5pv210_audss_clk_syscore_ops = { +static const struct syscore_ops s5pv210_audss_clk_syscore_ops = { .suspend = s5pv210_audss_clk_suspend, .resume = s5pv210_audss_clk_resume, }; + +static struct syscore s5pv210_audss_clk_syscore = { + .ops = &s5pv210_audss_clk_syscore_ops, +}; #endif /* CONFIG_PM_SLEEP */ /* register s5pv210_audss clocks */ @@ -175,7 +179,7 @@ static int s5pv210_audss_clk_probe(struct platform_device *pdev) } #ifdef CONFIG_PM_SLEEP - register_syscore_ops(&s5pv210_audss_clk_syscore_ops); + register_syscore(&s5pv210_audss_clk_syscore); #endif return 0; diff --git a/drivers/clk/samsung/clk.c b/drivers/clk/samsung/clk.c index dbc9925ca8f4..c149ca6c2217 100644 --- a/drivers/clk/samsung/clk.c +++ b/drivers/clk/samsung/clk.c @@ -271,7 +271,7 @@ void __init samsung_clk_of_register_fixed_ext(struct samsung_clk_provider *ctx, } #ifdef CONFIG_PM_SLEEP -static int samsung_clk_suspend(void) +static int samsung_clk_suspend(void *data) { struct samsung_clock_reg_cache *reg_cache; @@ -284,7 +284,7 @@ static int samsung_clk_suspend(void) return 0; } -static void samsung_clk_resume(void) +static void samsung_clk_resume(void *data) { struct samsung_clock_reg_cache *reg_cache; @@ -293,11 +293,15 @@ static void samsung_clk_resume(void) reg_cache->rd_num); } -static struct syscore_ops samsung_clk_syscore_ops = { +static const struct syscore_ops samsung_clk_syscore_ops = { .suspend = samsung_clk_suspend, .resume = samsung_clk_resume, }; +static struct syscore samsung_clk_syscore = { + .ops = &samsung_clk_syscore_ops, +}; + void samsung_clk_extended_sleep_init(void __iomem *reg_base, const unsigned long *rdump, unsigned long nr_rdump, @@ -316,7 +320,7 @@ void samsung_clk_extended_sleep_init(void __iomem *reg_base, panic("could not allocate register dump storage.\n"); if (list_empty(&clock_reg_cache_list)) - register_syscore_ops(&samsung_clk_syscore_ops); + register_syscore(&samsung_clk_syscore); reg_cache->reg_base = reg_base; reg_cache->rd_num = nr_rdump; diff --git a/drivers/clk/tegra/clk-tegra210.c b/drivers/clk/tegra/clk-tegra210.c index 412902f573b5..504d0ea997a5 100644 --- a/drivers/clk/tegra/clk-tegra210.c +++ b/drivers/clk/tegra/clk-tegra210.c @@ -3444,7 +3444,7 @@ static void tegra210_disable_cpu_clock(u32 cpu) static u32 spare_reg_ctx, misc_clk_enb_ctx, clk_msk_arm_ctx; static u32 cpu_softrst_ctx[3]; -static int tegra210_clk_suspend(void) +static int tegra210_clk_suspend(void *data) { unsigned int i; @@ -3465,7 +3465,7 @@ static int tegra210_clk_suspend(void) return 0; } -static void tegra210_clk_resume(void) +static void tegra210_clk_resume(void *data) { unsigned int i; @@ -3523,13 +3523,17 @@ static void tegra210_cpu_clock_resume(void) } #endif -static struct syscore_ops tegra_clk_syscore_ops = { +static const struct syscore_ops tegra_clk_syscore_ops = { #ifdef CONFIG_PM_SLEEP .suspend = tegra210_clk_suspend, .resume = tegra210_clk_resume, #endif }; +static struct syscore tegra_clk_syscore = { + .ops = &tegra_clk_syscore_ops, +}; + static struct tegra_cpu_car_ops tegra210_cpu_car_ops = { .wait_for_reset = tegra210_wait_cpu_in_reset, .disable_clock = tegra210_disable_cpu_clock, @@ -3813,6 +3817,6 @@ static void __init tegra210_clock_init(struct device_node *np) tegra_cpu_car_ops = &tegra210_cpu_car_ops; - register_syscore_ops(&tegra_clk_syscore_ops); + register_syscore(&tegra_clk_syscore); } CLK_OF_DECLARE(tegra210, "nvidia,tegra210-car", tegra210_clock_init); diff --git a/drivers/clocksource/timer-armada-370-xp.c b/drivers/clocksource/timer-armada-370-xp.c index 54284c1c0651..f2b4cc40db93 100644 --- a/drivers/clocksource/timer-armada-370-xp.c +++ b/drivers/clocksource/timer-armada-370-xp.c @@ -207,14 +207,14 @@ static int armada_370_xp_timer_dying_cpu(unsigned int cpu) static u32 timer0_ctrl_reg, timer0_local_ctrl_reg; -static int armada_370_xp_timer_suspend(void) +static int armada_370_xp_timer_suspend(void *data) { timer0_ctrl_reg = readl(timer_base + TIMER_CTRL_OFF); timer0_local_ctrl_reg = readl(local_base + TIMER_CTRL_OFF); return 0; } -static void armada_370_xp_timer_resume(void) +static void armada_370_xp_timer_resume(void *data) { writel(0xffffffff, timer_base + TIMER0_VAL_OFF); writel(0xffffffff, timer_base + TIMER0_RELOAD_OFF); @@ -222,11 +222,15 @@ static void armada_370_xp_timer_resume(void) writel(timer0_local_ctrl_reg, local_base + TIMER_CTRL_OFF); } -static struct syscore_ops armada_370_xp_timer_syscore_ops = { +static const struct syscore_ops armada_370_xp_timer_syscore_ops = { .suspend = armada_370_xp_timer_suspend, .resume = armada_370_xp_timer_resume, }; +static struct syscore armada_370_xp_timer_syscore = { + .ops = &armada_370_xp_timer_syscore_ops, +}; + static unsigned long armada_370_delay_timer_read(void) { return ~readl(timer_base + TIMER0_VAL_OFF); @@ -324,7 +328,7 @@ static int __init armada_370_xp_timer_common_init(struct device_node *np) return res; } - register_syscore_ops(&armada_370_xp_timer_syscore_ops); + register_syscore(&armada_370_xp_timer_syscore); return 0; } diff --git a/drivers/cpuidle/cpuidle-psci.c b/drivers/cpuidle/cpuidle-psci.c index b19bc60cc627..3372e1f90561 100644 --- a/drivers/cpuidle/cpuidle-psci.c +++ b/drivers/cpuidle/cpuidle-psci.c @@ -177,26 +177,30 @@ static void psci_idle_syscore_switch(bool suspend) } } -static int psci_idle_syscore_suspend(void) +static int psci_idle_syscore_suspend(void *data) { psci_idle_syscore_switch(true); return 0; } -static void psci_idle_syscore_resume(void) +static void psci_idle_syscore_resume(void *data) { psci_idle_syscore_switch(false); } -static struct syscore_ops psci_idle_syscore_ops = { +static const struct syscore_ops psci_idle_syscore_ops = { .suspend = psci_idle_syscore_suspend, .resume = psci_idle_syscore_resume, }; +static struct syscore psci_idle_syscore = { + .ops = &psci_idle_syscore_ops, +}; + static void psci_idle_init_syscore(void) { if (psci_cpuidle_use_syscore) - register_syscore_ops(&psci_idle_syscore_ops); + register_syscore(&psci_idle_syscore); } static void psci_idle_init_cpuhp(void) diff --git a/drivers/gpio/gpio-mxc.c b/drivers/gpio/gpio-mxc.c index 52060b3ec745..d7666fe9dbf8 100644 --- a/drivers/gpio/gpio-mxc.c +++ b/drivers/gpio/gpio-mxc.c @@ -667,7 +667,7 @@ static const struct dev_pm_ops mxc_gpio_dev_pm_ops = { RUNTIME_PM_OPS(mxc_gpio_runtime_suspend, mxc_gpio_runtime_resume, NULL) }; -static int mxc_gpio_syscore_suspend(void) +static int mxc_gpio_syscore_suspend(void *data) { struct mxc_gpio_port *port; int ret; @@ -684,7 +684,7 @@ static int mxc_gpio_syscore_suspend(void) return 0; } -static void mxc_gpio_syscore_resume(void) +static void mxc_gpio_syscore_resume(void *data) { struct mxc_gpio_port *port; int ret; @@ -701,11 +701,15 @@ static void mxc_gpio_syscore_resume(void) } } -static struct syscore_ops mxc_gpio_syscore_ops = { +static const struct syscore_ops mxc_gpio_syscore_ops = { .suspend = mxc_gpio_syscore_suspend, .resume = mxc_gpio_syscore_resume, }; +static struct syscore mxc_gpio_syscore = { + .ops = &mxc_gpio_syscore_ops, +}; + static struct platform_driver mxc_gpio_driver = { .driver = { .name = "gpio-mxc", @@ -718,7 +722,7 @@ static struct platform_driver mxc_gpio_driver = { static int __init gpio_mxc_init(void) { - register_syscore_ops(&mxc_gpio_syscore_ops); + register_syscore(&mxc_gpio_syscore); return platform_driver_register(&mxc_gpio_driver); } diff --git a/drivers/gpio/gpio-pxa.c b/drivers/gpio/gpio-pxa.c index fa22f3faa163..664cf1eef494 100644 --- a/drivers/gpio/gpio-pxa.c +++ b/drivers/gpio/gpio-pxa.c @@ -747,7 +747,7 @@ static int __init pxa_gpio_dt_init(void) device_initcall(pxa_gpio_dt_init); #ifdef CONFIG_PM -static int pxa_gpio_suspend(void) +static int pxa_gpio_suspend(void *data) { struct pxa_gpio_chip *pchip = pxa_gpio_chip; struct pxa_gpio_bank *c; @@ -768,7 +768,7 @@ static int pxa_gpio_suspend(void) return 0; } -static void pxa_gpio_resume(void) +static void pxa_gpio_resume(void *data) { struct pxa_gpio_chip *pchip = pxa_gpio_chip; struct pxa_gpio_bank *c; @@ -792,14 +792,18 @@ static void pxa_gpio_resume(void) #define pxa_gpio_resume NULL #endif -static struct syscore_ops pxa_gpio_syscore_ops = { +static const struct syscore_ops pxa_gpio_syscore_ops = { .suspend = pxa_gpio_suspend, .resume = pxa_gpio_resume, }; +static struct syscore pxa_gpio_syscore = { + .ops = &pxa_gpio_syscore_ops, +}; + static int __init pxa_gpio_sysinit(void) { - register_syscore_ops(&pxa_gpio_syscore_ops); + register_syscore(&pxa_gpio_syscore); return 0; } postcore_initcall(pxa_gpio_sysinit); diff --git a/drivers/gpio/gpio-sa1100.c b/drivers/gpio/gpio-sa1100.c index 7f6a62f5d1ee..1938ffa2f4f3 100644 --- a/drivers/gpio/gpio-sa1100.c +++ b/drivers/gpio/gpio-sa1100.c @@ -256,7 +256,7 @@ static void sa1100_gpio_handler(struct irq_desc *desc) } while (mask); } -static int sa1100_gpio_suspend(void) +static int sa1100_gpio_suspend(void *data) { struct sa1100_gpio_chip *sgc = &sa1100_gpio_chip; @@ -275,19 +275,23 @@ static int sa1100_gpio_suspend(void) return 0; } -static void sa1100_gpio_resume(void) +static void sa1100_gpio_resume(void *data) { sa1100_update_edge_regs(&sa1100_gpio_chip); } -static struct syscore_ops sa1100_gpio_syscore_ops = { +static const struct syscore_ops sa1100_gpio_syscore_ops = { .suspend = sa1100_gpio_suspend, .resume = sa1100_gpio_resume, }; +static struct syscore sa1100_gpio_syscore = { + .ops = &sa1100_gpio_syscore_ops, +}; + static int __init sa1100_gpio_init_devicefs(void) { - register_syscore_ops(&sa1100_gpio_syscore_ops); + register_syscore(&sa1100_gpio_syscore); return 0; } diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c index 69591dc7bad2..67734dc73e16 100644 --- a/drivers/hv/vmbus_drv.c +++ b/drivers/hv/vmbus_drv.c @@ -2801,7 +2801,7 @@ static void hv_crash_handler(struct pt_regs *regs) hv_synic_disable_regs(cpu); }; -static int hv_synic_suspend(void) +static int hv_synic_suspend(void *data) { /* * When we reach here, all the non-boot CPUs have been offlined. @@ -2828,7 +2828,7 @@ static int hv_synic_suspend(void) return 0; } -static void hv_synic_resume(void) +static void hv_synic_resume(void *data) { hv_synic_enable_regs(0); @@ -2840,11 +2840,15 @@ static void hv_synic_resume(void) } /* The callbacks run only on CPU0, with irqs_disabled. */ -static struct syscore_ops hv_synic_syscore_ops = { +static const struct syscore_ops hv_synic_syscore_ops = { .suspend = hv_synic_suspend, .resume = hv_synic_resume, }; +static struct syscore hv_synic_syscore = { + .ops = &hv_synic_syscore_ops, +}; + static int __init hv_acpi_init(void) { int ret; @@ -2887,7 +2891,7 @@ static int __init hv_acpi_init(void) hv_setup_kexec_handler(hv_kexec_handler); hv_setup_crash_handler(hv_crash_handler); - register_syscore_ops(&hv_synic_syscore_ops); + register_syscore(&hv_synic_syscore); return 0; @@ -2901,7 +2905,7 @@ static void __exit vmbus_exit(void) { int cpu; - unregister_syscore_ops(&hv_synic_syscore_ops); + unregister_syscore(&hv_synic_syscore); hv_remove_kexec_handler(); hv_remove_crash_handler(); diff --git a/drivers/iommu/amd/init.c b/drivers/iommu/amd/init.c index f2991c11867c..b763f4c9c5a7 100644 --- a/drivers/iommu/amd/init.c +++ b/drivers/iommu/amd/init.c @@ -3024,7 +3024,7 @@ static void disable_iommus(void) * disable suspend until real resume implemented */ -static void amd_iommu_resume(void) +static void amd_iommu_resume(void *data) { struct amd_iommu *iommu; @@ -3038,7 +3038,7 @@ static void amd_iommu_resume(void) amd_iommu_enable_interrupts(); } -static int amd_iommu_suspend(void) +static int amd_iommu_suspend(void *data) { /* disable IOMMUs to go out of the way for BIOS */ disable_iommus(); @@ -3046,11 +3046,15 @@ static int amd_iommu_suspend(void) return 0; } -static struct syscore_ops amd_iommu_syscore_ops = { +static const struct syscore_ops amd_iommu_syscore_ops = { .suspend = amd_iommu_suspend, .resume = amd_iommu_resume, }; +static struct syscore amd_iommu_syscore = { + .ops = &amd_iommu_syscore_ops, +}; + static void __init free_iommu_resources(void) { free_iommu_all(); @@ -3395,7 +3399,7 @@ static int __init state_next(void) init_state = IOMMU_ENABLED; break; case IOMMU_ENABLED: - register_syscore_ops(&amd_iommu_syscore_ops); + register_syscore(&amd_iommu_syscore); iommu_snp_enable(); ret = amd_iommu_init_pci(); init_state = ret ? IOMMU_INIT_ERROR : IOMMU_PCI_INIT; @@ -3498,12 +3502,12 @@ int __init amd_iommu_enable(void) void amd_iommu_disable(void) { - amd_iommu_suspend(); + amd_iommu_suspend(NULL); } int amd_iommu_reenable(int mode) { - amd_iommu_resume(); + amd_iommu_resume(NULL); return 0; } diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c index e236c7ec221f..fdaf7f64dd33 100644 --- a/drivers/iommu/intel/iommu.c +++ b/drivers/iommu/intel/iommu.c @@ -2303,7 +2303,7 @@ static void iommu_flush_all(void) } } -static int iommu_suspend(void) +static int iommu_suspend(void *data) { struct dmar_drhd_unit *drhd; struct intel_iommu *iommu = NULL; @@ -2330,7 +2330,7 @@ static int iommu_suspend(void) return 0; } -static void iommu_resume(void) +static void iommu_resume(void *data) { struct dmar_drhd_unit *drhd; struct intel_iommu *iommu = NULL; @@ -2361,14 +2361,18 @@ static void iommu_resume(void) } } -static struct syscore_ops iommu_syscore_ops = { +static const struct syscore_ops iommu_syscore_ops = { .resume = iommu_resume, .suspend = iommu_suspend, }; +static struct syscore iommu_syscore = { + .ops = &iommu_syscore_ops, +}; + static void __init init_iommu_pm_ops(void) { - register_syscore_ops(&iommu_syscore_ops); + register_syscore(&iommu_syscore); } #else diff --git a/drivers/irqchip/exynos-combiner.c b/drivers/irqchip/exynos-combiner.c index e7dfcf0cda43..495848442b35 100644 --- a/drivers/irqchip/exynos-combiner.c +++ b/drivers/irqchip/exynos-combiner.c @@ -200,12 +200,13 @@ static void __init combiner_init(void __iomem *combiner_base, /** * combiner_suspend - save interrupt combiner state before suspend + * @data: syscore context * * Save the interrupt enable set register for all combiner groups since * the state is lost when the system enters into a sleep state. * */ -static int combiner_suspend(void) +static int combiner_suspend(void *data) { int i; @@ -218,12 +219,13 @@ static int combiner_suspend(void) /** * combiner_resume - restore interrupt combiner state after resume + * @data: syscore context * * Restore the interrupt enable set register for all combiner groups since * the state is lost when the system enters into a sleep state on suspend. * */ -static void combiner_resume(void) +static void combiner_resume(void *data) { int i; @@ -240,11 +242,15 @@ static void combiner_resume(void) #define combiner_resume NULL #endif -static struct syscore_ops combiner_syscore_ops = { +static const struct syscore_ops combiner_syscore_ops = { .suspend = combiner_suspend, .resume = combiner_resume, }; +static struct syscore combiner_syscore = { + .ops = &combiner_syscore_ops, +}; + static int __init combiner_of_init(struct device_node *np, struct device_node *parent) { @@ -264,7 +270,7 @@ static int __init combiner_of_init(struct device_node *np, combiner_init(combiner_base, np); - register_syscore_ops(&combiner_syscore_ops); + register_syscore(&combiner_syscore); return 0; } diff --git a/drivers/irqchip/irq-armada-370-xp.c b/drivers/irqchip/irq-armada-370-xp.c index a44c49e985b7..a4d03a2d1569 100644 --- a/drivers/irqchip/irq-armada-370-xp.c +++ b/drivers/irqchip/irq-armada-370-xp.c @@ -726,7 +726,7 @@ static void __exception_irq_entry mpic_handle_irq(struct pt_regs *regs) } while (1); } -static int mpic_suspend(void) +static int mpic_suspend(void *data) { struct mpic *mpic = mpic_data; @@ -735,7 +735,7 @@ static int mpic_suspend(void) return 0; } -static void mpic_resume(void) +static void mpic_resume(void *data) { struct mpic *mpic = mpic_data; bool src0, src1; @@ -788,11 +788,15 @@ static void mpic_resume(void) mpic_ipi_resume(mpic); } -static struct syscore_ops mpic_syscore_ops = { +static const struct syscore_ops mpic_syscore_ops = { .suspend = mpic_suspend, .resume = mpic_resume, }; +static struct syscore mpic_syscore = { + .ops = &mpic_syscore_ops, +}; + static int __init mpic_map_region(struct device_node *np, int index, void __iomem **base, phys_addr_t *phys_base) { @@ -905,7 +909,7 @@ static int __init mpic_of_init(struct device_node *node, struct device_node *par mpic_handle_cascade_irq, mpic); } - register_syscore_ops(&mpic_syscore_ops); + register_syscore(&mpic_syscore); return 0; } diff --git a/drivers/irqchip/irq-bcm7038-l1.c b/drivers/irqchip/irq-bcm7038-l1.c index 04fac0cc857f..cd9a56459f99 100644 --- a/drivers/irqchip/irq-bcm7038-l1.c +++ b/drivers/irqchip/irq-bcm7038-l1.c @@ -292,7 +292,7 @@ static int __init bcm7038_l1_init_one(struct device_node *dn, static LIST_HEAD(bcm7038_l1_intcs_list); static DEFINE_RAW_SPINLOCK(bcm7038_l1_intcs_lock); -static int bcm7038_l1_suspend(void) +static int bcm7038_l1_suspend(void *data) { struct bcm7038_l1_chip *intc; int boot_cpu, word; @@ -318,7 +318,7 @@ static int bcm7038_l1_suspend(void) return 0; } -static void bcm7038_l1_resume(void) +static void bcm7038_l1_resume(void *data) { struct bcm7038_l1_chip *intc; int boot_cpu, word; @@ -339,11 +339,15 @@ static void bcm7038_l1_resume(void) } } -static struct syscore_ops bcm7038_l1_syscore_ops = { +static const struct syscore_ops bcm7038_l1_syscore_ops = { .suspend = bcm7038_l1_suspend, .resume = bcm7038_l1_resume, }; +static struct syscore bcm7038_l1_syscore = { + .ops = &bcm7038_l1_syscore_ops, +}; + static int bcm7038_l1_set_wake(struct irq_data *d, unsigned int on) { struct bcm7038_l1_chip *intc = irq_data_get_irq_chip_data(d); @@ -431,7 +435,7 @@ static int __init bcm7038_l1_of_init(struct device_node *dn, raw_spin_unlock(&bcm7038_l1_intcs_lock); if (list_is_singular(&bcm7038_l1_intcs_list)) - register_syscore_ops(&bcm7038_l1_syscore_ops); + register_syscore(&bcm7038_l1_syscore); #endif pr_info("registered BCM7038 L1 intc (%pOF, IRQs: %d)\n", diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c index 467cb78435a9..ada585bfa451 100644 --- a/drivers/irqchip/irq-gic-v3-its.c +++ b/drivers/irqchip/irq-gic-v3-its.c @@ -4992,7 +4992,7 @@ static void its_enable_quirks(struct its_node *its) its_quirks, its); } -static int its_save_disable(void) +static int its_save_disable(void *data) { struct its_node *its; int err = 0; @@ -5028,7 +5028,7 @@ static int its_save_disable(void) return err; } -static void its_restore_enable(void) +static void its_restore_enable(void *data) { struct its_node *its; int ret; @@ -5088,11 +5088,15 @@ static void its_restore_enable(void) raw_spin_unlock(&its_lock); } -static struct syscore_ops its_syscore_ops = { +static const struct syscore_ops its_syscore_ops = { .suspend = its_save_disable, .resume = its_restore_enable, }; +static struct syscore its_syscore = { + .ops = &its_syscore_ops, +}; + static void __init __iomem *its_map_one(struct resource *res, int *err) { void __iomem *its_base; @@ -5864,7 +5868,7 @@ int __init its_init(struct fwnode_handle *handle, struct rdists *rdists, } } - register_syscore_ops(&its_syscore_ops); + register_syscore(&its_syscore); return 0; } diff --git a/drivers/irqchip/irq-i8259.c b/drivers/irqchip/irq-i8259.c index 91b2f587119c..cca77f9948a3 100644 --- a/drivers/irqchip/irq-i8259.c +++ b/drivers/irqchip/irq-i8259.c @@ -202,13 +202,13 @@ static void mask_and_ack_8259A(struct irq_data *d) } } -static void i8259A_resume(void) +static void i8259A_resume(void *data) { if (i8259A_auto_eoi >= 0) init_8259A(i8259A_auto_eoi); } -static void i8259A_shutdown(void) +static void i8259A_shutdown(void *data) { /* Put the i8259A into a quiescent state that * the kernel initialization code can get it @@ -220,11 +220,15 @@ static void i8259A_shutdown(void) } } -static struct syscore_ops i8259_syscore_ops = { +static const struct syscore_ops i8259_syscore_ops = { .resume = i8259A_resume, .shutdown = i8259A_shutdown, }; +static struct syscore i8259_syscore = { + .ops = &i8259_syscore_ops, +}; + static void init_8259A(int auto_eoi) { unsigned long flags; @@ -320,7 +324,7 @@ struct irq_domain * __init __init_i8259_irqs(struct device_node *node) if (request_irq(irq, no_action, IRQF_NO_THREAD, "cascade", NULL)) pr_err("Failed to register cascade interrupt\n"); - register_syscore_ops(&i8259_syscore_ops); + register_syscore(&i8259_syscore); return domain; } diff --git a/drivers/irqchip/irq-imx-gpcv2.c b/drivers/irqchip/irq-imx-gpcv2.c index b91f5c14b405..04f7ba0657be 100644 --- a/drivers/irqchip/irq-imx-gpcv2.c +++ b/drivers/irqchip/irq-imx-gpcv2.c @@ -33,7 +33,7 @@ static void __iomem *gpcv2_idx_to_reg(struct gpcv2_irqchip_data *cd, int i) return cd->gpc_base + cd->cpu2wakeup + i * 4; } -static int gpcv2_wakeup_source_save(void) +static int gpcv2_wakeup_source_save(void *data) { struct gpcv2_irqchip_data *cd; void __iomem *reg; @@ -52,7 +52,7 @@ static int gpcv2_wakeup_source_save(void) return 0; } -static void gpcv2_wakeup_source_restore(void) +static void gpcv2_wakeup_source_restore(void *data) { struct gpcv2_irqchip_data *cd; int i; @@ -65,9 +65,13 @@ static void gpcv2_wakeup_source_restore(void) writel_relaxed(cd->saved_irq_mask[i], gpcv2_idx_to_reg(cd, i)); } -static struct syscore_ops imx_gpcv2_syscore_ops = { - .suspend = gpcv2_wakeup_source_save, - .resume = gpcv2_wakeup_source_restore, +static const struct syscore_ops gpcv2_syscore_ops = { + .suspend = gpcv2_wakeup_source_save, + .resume = gpcv2_wakeup_source_restore, +}; + +static struct syscore gpcv2_syscore = { + .ops = &gpcv2_syscore_ops, }; static int imx_gpcv2_irq_set_wake(struct irq_data *d, unsigned int on) @@ -276,7 +280,7 @@ static int __init imx_gpcv2_irqchip_init(struct device_node *node, writel_relaxed(~0x1, cd->gpc_base + cd->cpu2wakeup); imx_gpcv2_instance = cd; - register_syscore_ops(&imx_gpcv2_syscore_ops); + register_syscore(&gpcv2_syscore); /* * Clear the OF_POPULATED flag set in of_irq_init so that diff --git a/drivers/irqchip/irq-loongson-eiointc.c b/drivers/irqchip/irq-loongson-eiointc.c index 39e5a72ccd3c..ad2105685b48 100644 --- a/drivers/irqchip/irq-loongson-eiointc.c +++ b/drivers/irqchip/irq-loongson-eiointc.c @@ -407,21 +407,25 @@ static struct irq_domain *acpi_get_vec_parent(int node, struct acpi_vector_group return NULL; } -static int eiointc_suspend(void) +static int eiointc_suspend(void *data) { return 0; } -static void eiointc_resume(void) +static void eiointc_resume(void *data) { eiointc_router_init(0); } -static struct syscore_ops eiointc_syscore_ops = { +static const struct syscore_ops eiointc_syscore_ops = { .suspend = eiointc_suspend, .resume = eiointc_resume, }; +static struct syscore eiointc_syscore = { + .ops = &eiointc_syscore_ops, +}; + static int __init pch_pic_parse_madt(union acpi_subtable_headers *header, const unsigned long end) { @@ -540,7 +544,7 @@ static int __init eiointc_init(struct eiointc_priv *priv, int parent_irq, eiointc_router_init(0); if (nr_pics == 1) { - register_syscore_ops(&eiointc_syscore_ops); + register_syscore(&eiointc_syscore); cpuhp_setup_state_nocalls(CPUHP_AP_IRQ_EIOINTC_STARTING, "irqchip/loongarch/eiointc:starting", eiointc_router_init, NULL); diff --git a/drivers/irqchip/irq-loongson-htpic.c b/drivers/irqchip/irq-loongson-htpic.c index f4abdf156de7..1c691c4be989 100644 --- a/drivers/irqchip/irq-loongson-htpic.c +++ b/drivers/irqchip/irq-loongson-htpic.c @@ -71,15 +71,19 @@ static void htpic_reg_init(void) writel(0xffff, htpic->base + HTINT_EN_OFF); } -static void htpic_resume(void) +static void htpic_resume(void *data) { htpic_reg_init(); } -struct syscore_ops htpic_syscore_ops = { +static const struct syscore_ops htpic_syscore_ops = { .resume = htpic_resume, }; +static struct syscore htpic_syscore = { + .ops = &htpic_syscore_ops, +}; + static int __init htpic_of_init(struct device_node *node, struct device_node *parent) { unsigned int parent_irq[4]; @@ -130,7 +134,7 @@ static int __init htpic_of_init(struct device_node *node, struct device_node *pa htpic_irq_dispatch, htpic); } - register_syscore_ops(&htpic_syscore_ops); + register_syscore(&htpic_syscore); return 0; diff --git a/drivers/irqchip/irq-loongson-htvec.c b/drivers/irqchip/irq-loongson-htvec.c index d8558eb35044..d2be8e954e92 100644 --- a/drivers/irqchip/irq-loongson-htvec.c +++ b/drivers/irqchip/irq-loongson-htvec.c @@ -159,7 +159,7 @@ static void htvec_reset(struct htvec *priv) } } -static int htvec_suspend(void) +static int htvec_suspend(void *data) { int i; @@ -169,7 +169,7 @@ static int htvec_suspend(void) return 0; } -static void htvec_resume(void) +static void htvec_resume(void *data) { int i; @@ -177,11 +177,15 @@ static void htvec_resume(void) writel(htvec_priv->saved_vec_en[i], htvec_priv->base + HTVEC_EN_OFF + 4 * i); } -static struct syscore_ops htvec_syscore_ops = { +static const struct syscore_ops htvec_syscore_ops = { .suspend = htvec_suspend, .resume = htvec_resume, }; +static struct syscore htvec_syscore = { + .ops = &htvec_syscore_ops, +}; + static int htvec_init(phys_addr_t addr, unsigned long size, int num_parents, int parent_irq[], struct fwnode_handle *domain_handle) { @@ -214,7 +218,7 @@ static int htvec_init(phys_addr_t addr, unsigned long size, htvec_priv = priv; - register_syscore_ops(&htvec_syscore_ops); + register_syscore(&htvec_syscore); return 0; diff --git a/drivers/irqchip/irq-loongson-pch-lpc.c b/drivers/irqchip/irq-loongson-pch-lpc.c index 912bf50a5c7c..3a125f3e4287 100644 --- a/drivers/irqchip/irq-loongson-pch-lpc.c +++ b/drivers/irqchip/irq-loongson-pch-lpc.c @@ -151,7 +151,7 @@ static int pch_lpc_disabled(struct pch_lpc *priv) (readl(priv->base + LPC_INT_STS) == 0xffffffff); } -static int pch_lpc_suspend(void) +static int pch_lpc_suspend(void *data) { pch_lpc_priv->saved_reg_ctl = readl(pch_lpc_priv->base + LPC_INT_CTL); pch_lpc_priv->saved_reg_ena = readl(pch_lpc_priv->base + LPC_INT_ENA); @@ -159,18 +159,22 @@ static int pch_lpc_suspend(void) return 0; } -static void pch_lpc_resume(void) +static void pch_lpc_resume(void *data) { writel(pch_lpc_priv->saved_reg_ctl, pch_lpc_priv->base + LPC_INT_CTL); writel(pch_lpc_priv->saved_reg_ena, pch_lpc_priv->base + LPC_INT_ENA); writel(pch_lpc_priv->saved_reg_pol, pch_lpc_priv->base + LPC_INT_POL); } -static struct syscore_ops pch_lpc_syscore_ops = { +static const struct syscore_ops pch_lpc_syscore_ops = { .suspend = pch_lpc_suspend, .resume = pch_lpc_resume, }; +static struct syscore pch_lpc_syscore = { + .ops = &pch_lpc_syscore_ops, +}; + int __init pch_lpc_acpi_init(struct irq_domain *parent, struct acpi_madt_lpc_pic *acpi_pchlpc) { @@ -222,7 +226,7 @@ int __init pch_lpc_acpi_init(struct irq_domain *parent, pch_lpc_priv = priv; pch_lpc_handle = irq_handle; - register_syscore_ops(&pch_lpc_syscore_ops); + register_syscore(&pch_lpc_syscore); return 0; diff --git a/drivers/irqchip/irq-loongson-pch-pic.c b/drivers/irqchip/irq-loongson-pch-pic.c index 62e6bf3a0611..c6b369a974a7 100644 --- a/drivers/irqchip/irq-loongson-pch-pic.c +++ b/drivers/irqchip/irq-loongson-pch-pic.c @@ -278,7 +278,7 @@ static void pch_pic_reset(struct pch_pic *priv) } } -static int pch_pic_suspend(void) +static int pch_pic_suspend(void *data) { int i, j; @@ -296,7 +296,7 @@ static int pch_pic_suspend(void) return 0; } -static void pch_pic_resume(void) +static void pch_pic_resume(void *data) { int i, j; @@ -313,11 +313,15 @@ static void pch_pic_resume(void) } } -static struct syscore_ops pch_pic_syscore_ops = { +static const struct syscore_ops pch_pic_syscore_ops = { .suspend = pch_pic_suspend, .resume = pch_pic_resume, }; +static struct syscore pch_pic_syscore = { + .ops = &pch_pic_syscore_ops, +}; + static int pch_pic_init(phys_addr_t addr, unsigned long size, int vec_base, struct irq_domain *parent_domain, struct fwnode_handle *domain_handle, u32 gsi_base) @@ -356,7 +360,7 @@ static int pch_pic_init(phys_addr_t addr, unsigned long size, int vec_base, pch_pic_priv[nr_pics++] = priv; if (nr_pics == 1) - register_syscore_ops(&pch_pic_syscore_ops); + register_syscore(&pch_pic_syscore); return 0; diff --git a/drivers/irqchip/irq-mchp-eic.c b/drivers/irqchip/irq-mchp-eic.c index 516a3a0e359c..be83e6e422c3 100644 --- a/drivers/irqchip/irq-mchp-eic.c +++ b/drivers/irqchip/irq-mchp-eic.c @@ -109,7 +109,7 @@ static int mchp_eic_irq_set_wake(struct irq_data *d, unsigned int on) return 0; } -static int mchp_eic_irq_suspend(void) +static int mchp_eic_irq_suspend(void *data) { unsigned int hwirq; @@ -123,7 +123,7 @@ static int mchp_eic_irq_suspend(void) return 0; } -static void mchp_eic_irq_resume(void) +static void mchp_eic_irq_resume(void *data) { unsigned int hwirq; @@ -135,11 +135,15 @@ static void mchp_eic_irq_resume(void) MCHP_EIC_SCFG(hwirq)); } -static struct syscore_ops mchp_eic_syscore_ops = { +static const struct syscore_ops mchp_eic_syscore_ops = { .suspend = mchp_eic_irq_suspend, .resume = mchp_eic_irq_resume, }; +static struct syscore mchp_eic_syscore = { + .ops = &mchp_eic_syscore_ops, +}; + static struct irq_chip mchp_eic_chip = { .name = "eic", .flags = IRQCHIP_MASK_ON_SUSPEND | IRQCHIP_SET_TYPE_MASKED, @@ -257,7 +261,7 @@ static int mchp_eic_init(struct device_node *node, struct device_node *parent) goto clk_unprepare; } - register_syscore_ops(&mchp_eic_syscore_ops); + register_syscore(&mchp_eic_syscore); pr_info("%pOF: EIC registered, nr_irqs %u\n", node, MCHP_EIC_NIRQ); diff --git a/drivers/irqchip/irq-mst-intc.c b/drivers/irqchip/irq-mst-intc.c index 9643cc3a77d7..7f760f555a76 100644 --- a/drivers/irqchip/irq-mst-intc.c +++ b/drivers/irqchip/irq-mst-intc.c @@ -143,7 +143,7 @@ static void mst_intc_polarity_restore(struct mst_intc_chip_data *cd) writew_relaxed(cd->saved_polarity_conf[i], addr + i * 4); } -static void mst_irq_resume(void) +static void mst_irq_resume(void *data) { struct mst_intc_chip_data *cd; @@ -151,7 +151,7 @@ static void mst_irq_resume(void) mst_intc_polarity_restore(cd); } -static int mst_irq_suspend(void) +static int mst_irq_suspend(void *data) { struct mst_intc_chip_data *cd; @@ -160,14 +160,18 @@ static int mst_irq_suspend(void) return 0; } -static struct syscore_ops mst_irq_syscore_ops = { +static const struct syscore_ops mst_irq_syscore_ops = { .suspend = mst_irq_suspend, .resume = mst_irq_resume, }; +static struct syscore mst_irq_syscore = { + .ops = &mst_irq_syscore_ops, +}; + static int __init mst_irq_pm_init(void) { - register_syscore_ops(&mst_irq_syscore_ops); + register_syscore(&mst_irq_syscore); return 0; } late_initcall(mst_irq_pm_init); diff --git a/drivers/irqchip/irq-mtk-cirq.c b/drivers/irqchip/irq-mtk-cirq.c index de481ba340f8..9571f622774e 100644 --- a/drivers/irqchip/irq-mtk-cirq.c +++ b/drivers/irqchip/irq-mtk-cirq.c @@ -199,7 +199,7 @@ static const struct irq_domain_ops cirq_domain_ops = { }; #ifdef CONFIG_PM_SLEEP -static int mtk_cirq_suspend(void) +static int mtk_cirq_suspend(void *data) { void __iomem *reg; u32 value, mask; @@ -257,7 +257,7 @@ static int mtk_cirq_suspend(void) return 0; } -static void mtk_cirq_resume(void) +static void mtk_cirq_resume(void *data) { void __iomem *reg = mtk_cirq_reg(cirq_data, CIRQ_CONTROL); u32 value; @@ -272,14 +272,18 @@ static void mtk_cirq_resume(void) writel_relaxed(value, reg); } -static struct syscore_ops mtk_cirq_syscore_ops = { +static const struct syscore_ops mtk_cirq_syscore_ops = { .suspend = mtk_cirq_suspend, .resume = mtk_cirq_resume, }; +static struct syscore mtk_cirq_syscore = { + .ops = &mtk_cirq_syscore_ops, +}; + static void mtk_cirq_syscore_init(void) { - register_syscore_ops(&mtk_cirq_syscore_ops); + register_syscore(&mtk_cirq_syscore); } #else static inline void mtk_cirq_syscore_init(void) {} diff --git a/drivers/irqchip/irq-renesas-rzg2l.c b/drivers/irqchip/irq-renesas-rzg2l.c index 2a54adeb4cc7..de88e80eac0c 100644 --- a/drivers/irqchip/irq-renesas-rzg2l.c +++ b/drivers/irqchip/irq-renesas-rzg2l.c @@ -399,7 +399,7 @@ static int rzg2l_irqc_set_type(struct irq_data *d, unsigned int type) return irq_chip_set_type_parent(d, IRQ_TYPE_LEVEL_HIGH); } -static int rzg2l_irqc_irq_suspend(void) +static int rzg2l_irqc_irq_suspend(void *data) { struct rzg2l_irqc_reg_cache *cache = &rzg2l_irqc_data->cache; void __iomem *base = rzg2l_irqc_data->base; @@ -411,7 +411,7 @@ static int rzg2l_irqc_irq_suspend(void) return 0; } -static void rzg2l_irqc_irq_resume(void) +static void rzg2l_irqc_irq_resume(void *data) { struct rzg2l_irqc_reg_cache *cache = &rzg2l_irqc_data->cache; void __iomem *base = rzg2l_irqc_data->base; @@ -426,11 +426,15 @@ static void rzg2l_irqc_irq_resume(void) writel_relaxed(cache->iitsr, base + IITSR); } -static struct syscore_ops rzg2l_irqc_syscore_ops = { +static const struct syscore_ops rzg2l_irqc_syscore_ops = { .suspend = rzg2l_irqc_irq_suspend, .resume = rzg2l_irqc_irq_resume, }; +static struct syscore rzg2l_irqc_syscore = { + .ops = &rzg2l_irqc_syscore_ops, +}; + static const struct irq_chip rzg2l_irqc_chip = { .name = "rzg2l-irqc", .irq_eoi = rzg2l_irqc_eoi, @@ -581,7 +585,7 @@ static int rzg2l_irqc_common_init(struct device_node *node, struct device_node * return -ENOMEM; } - register_syscore_ops(&rzg2l_irqc_syscore_ops); + register_syscore(&rzg2l_irqc_syscore); /* * Prevent the cleanup function from invoking put_device by assigning diff --git a/drivers/irqchip/irq-sa11x0.c b/drivers/irqchip/irq-sa11x0.c index d8d4dff16276..e5f24c5f3f41 100644 --- a/drivers/irqchip/irq-sa11x0.c +++ b/drivers/irqchip/irq-sa11x0.c @@ -85,7 +85,7 @@ static struct sa1100irq_state { unsigned int iccr; } sa1100irq_state; -static int sa1100irq_suspend(void) +static int sa1100irq_suspend(void *data) { struct sa1100irq_state *st = &sa1100irq_state; @@ -102,7 +102,7 @@ static int sa1100irq_suspend(void) return 0; } -static void sa1100irq_resume(void) +static void sa1100irq_resume(void *data) { struct sa1100irq_state *st = &sa1100irq_state; @@ -114,14 +114,18 @@ static void sa1100irq_resume(void) } } -static struct syscore_ops sa1100irq_syscore_ops = { +static const struct syscore_ops sa1100irq_syscore_ops = { .suspend = sa1100irq_suspend, .resume = sa1100irq_resume, }; +static struct syscore sa1100irq_syscore = { + .ops = &sa1100irq_syscore_ops, +}; + static int __init sa1100irq_init_devicefs(void) { - register_syscore_ops(&sa1100irq_syscore_ops); + register_syscore(&sa1100irq_syscore); return 0; } diff --git a/drivers/irqchip/irq-sifive-plic.c b/drivers/irqchip/irq-sifive-plic.c index cbd7697bc148..4f59c0ca1537 100644 --- a/drivers/irqchip/irq-sifive-plic.c +++ b/drivers/irqchip/irq-sifive-plic.c @@ -245,7 +245,7 @@ static int plic_irq_set_type(struct irq_data *d, unsigned int type) return IRQ_SET_MASK_OK; } -static int plic_irq_suspend(void) +static int plic_irq_suspend(void *data) { unsigned int i, cpu; unsigned long flags; @@ -277,7 +277,7 @@ static int plic_irq_suspend(void) return 0; } -static void plic_irq_resume(void) +static void plic_irq_resume(void *data) { unsigned int i, index, cpu; unsigned long flags; @@ -308,11 +308,15 @@ static void plic_irq_resume(void) } } -static struct syscore_ops plic_irq_syscore_ops = { +static const struct syscore_ops plic_irq_syscore_ops = { .suspend = plic_irq_suspend, .resume = plic_irq_resume, }; +static struct syscore plic_irq_syscore = { + .ops = &plic_irq_syscore_ops, +}; + static int plic_irqdomain_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hwirq) { @@ -678,7 +682,7 @@ static int plic_probe(struct fwnode_handle *fwnode) cpuhp_setup_state(CPUHP_AP_IRQ_SIFIVE_PLIC_STARTING, "irqchip/sifive/plic:starting", plic_starting_cpu, plic_dying_cpu); - register_syscore_ops(&plic_irq_syscore_ops); + register_syscore(&plic_irq_syscore); plic_global_setup_done = true; } } diff --git a/drivers/irqchip/irq-sun6i-r.c b/drivers/irqchip/irq-sun6i-r.c index 37d4b29763bc..23251831c06e 100644 --- a/drivers/irqchip/irq-sun6i-r.c +++ b/drivers/irqchip/irq-sun6i-r.c @@ -268,7 +268,7 @@ static const struct irq_domain_ops sun6i_r_intc_domain_ops = { .free = irq_domain_free_irqs_common, }; -static int sun6i_r_intc_suspend(void) +static int sun6i_r_intc_suspend(void *data) { u32 buf[BITS_TO_U32(MAX(SUN6I_NR_TOP_LEVEL_IRQS, SUN6I_NR_MUX_BITS))]; int i; @@ -284,7 +284,7 @@ static int sun6i_r_intc_suspend(void) return 0; } -static void sun6i_r_intc_resume(void) +static void sun6i_r_intc_resume(void *data) { int i; @@ -294,17 +294,21 @@ static void sun6i_r_intc_resume(void) writel_relaxed(0, base + SUN6I_IRQ_ENABLE(i)); } -static void sun6i_r_intc_shutdown(void) +static void sun6i_r_intc_shutdown(void *data) { - sun6i_r_intc_suspend(); + sun6i_r_intc_suspend(data); } -static struct syscore_ops sun6i_r_intc_syscore_ops = { +static const struct syscore_ops sun6i_r_intc_syscore_ops = { .suspend = sun6i_r_intc_suspend, .resume = sun6i_r_intc_resume, .shutdown = sun6i_r_intc_shutdown, }; +static struct syscore sun6i_r_intc_syscore = { + .ops = &sun6i_r_intc_syscore_ops, +}; + static int __init sun6i_r_intc_init(struct device_node *node, struct device_node *parent, const struct sun6i_r_intc_variant *v) @@ -346,10 +350,10 @@ static int __init sun6i_r_intc_init(struct device_node *node, return -ENOMEM; } - register_syscore_ops(&sun6i_r_intc_syscore_ops); + register_syscore(&sun6i_r_intc_syscore); sun6i_r_intc_ack_nmi(); - sun6i_r_intc_resume(); + sun6i_r_intc_resume(NULL); return 0; } diff --git a/drivers/irqchip/irq-tegra.c b/drivers/irqchip/irq-tegra.c index 66cbb9f77ff3..b6382cf6359a 100644 --- a/drivers/irqchip/irq-tegra.c +++ b/drivers/irqchip/irq-tegra.c @@ -132,7 +132,7 @@ static int tegra_set_wake(struct irq_data *d, unsigned int enable) return 0; } -static int tegra_ictlr_suspend(void) +static int tegra_ictlr_suspend(void *data) { unsigned long flags; unsigned int i; @@ -161,7 +161,7 @@ static int tegra_ictlr_suspend(void) return 0; } -static void tegra_ictlr_resume(void) +static void tegra_ictlr_resume(void *data) { unsigned long flags; unsigned int i; @@ -184,14 +184,18 @@ static void tegra_ictlr_resume(void) local_irq_restore(flags); } -static struct syscore_ops tegra_ictlr_syscore_ops = { +static const struct syscore_ops tegra_ictlr_syscore_ops = { .suspend = tegra_ictlr_suspend, .resume = tegra_ictlr_resume, }; +static struct syscore tegra_ictlr_syscore = { + .ops = &tegra_ictlr_syscore_ops, +}; + static void tegra_ictlr_syscore_init(void) { - register_syscore_ops(&tegra_ictlr_syscore_ops); + register_syscore(&tegra_ictlr_syscore); } #else #define tegra_set_wake NULL diff --git a/drivers/irqchip/irq-vic.c b/drivers/irqchip/irq-vic.c index 2bcdf216a000..e38104c5064e 100644 --- a/drivers/irqchip/irq-vic.c +++ b/drivers/irqchip/irq-vic.c @@ -120,7 +120,7 @@ static void resume_one_vic(struct vic_device *vic) writel(~vic->soft_int, base + VIC_INT_SOFT_CLEAR); } -static void vic_resume(void) +static void vic_resume(void *data) { int id; @@ -146,7 +146,7 @@ static void suspend_one_vic(struct vic_device *vic) writel(~vic->resume_irqs, base + VIC_INT_ENABLE_CLEAR); } -static int vic_suspend(void) +static int vic_suspend(void *data) { int id; @@ -156,11 +156,15 @@ static int vic_suspend(void) return 0; } -static struct syscore_ops vic_syscore_ops = { +static const struct syscore_ops vic_syscore_ops = { .suspend = vic_suspend, .resume = vic_resume, }; +static struct syscore vic_syscore = { + .ops = &vic_syscore_ops, +}; + /** * vic_pm_init - initcall to register VIC pm * @@ -171,7 +175,7 @@ static struct syscore_ops vic_syscore_ops = { static int __init vic_pm_init(void) { if (vic_id > 0) - register_syscore_ops(&vic_syscore_ops); + register_syscore(&vic_syscore); return 0; } diff --git a/drivers/leds/trigger/ledtrig-cpu.c b/drivers/leds/trigger/ledtrig-cpu.c index 05848a2fecff..679323c2ccda 100644 --- a/drivers/leds/trigger/ledtrig-cpu.c +++ b/drivers/leds/trigger/ledtrig-cpu.c @@ -94,28 +94,32 @@ void ledtrig_cpu(enum cpu_led_event ledevt) } EXPORT_SYMBOL(ledtrig_cpu); -static int ledtrig_cpu_syscore_suspend(void) +static int ledtrig_cpu_syscore_suspend(void *data) { ledtrig_cpu(CPU_LED_STOP); return 0; } -static void ledtrig_cpu_syscore_resume(void) +static void ledtrig_cpu_syscore_resume(void *data) { ledtrig_cpu(CPU_LED_START); } -static void ledtrig_cpu_syscore_shutdown(void) +static void ledtrig_cpu_syscore_shutdown(void *data) { ledtrig_cpu(CPU_LED_HALTED); } -static struct syscore_ops ledtrig_cpu_syscore_ops = { +static const struct syscore_ops ledtrig_cpu_syscore_ops = { .shutdown = ledtrig_cpu_syscore_shutdown, .suspend = ledtrig_cpu_syscore_suspend, .resume = ledtrig_cpu_syscore_resume, }; +static struct syscore ledtrig_cpu_syscore = { + .ops = &ledtrig_cpu_syscore_ops, +}; + static int ledtrig_online_cpu(unsigned int cpu) { ledtrig_cpu(CPU_LED_START); @@ -157,7 +161,7 @@ static int __init ledtrig_cpu_init(void) led_trigger_register_simple(trig->name, &trig->_trig); } - register_syscore_ops(&ledtrig_cpu_syscore_ops); + register_syscore(&ledtrig_cpu_syscore); ret = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "leds/trigger:starting", ledtrig_online_cpu, ledtrig_prepare_down_cpu); diff --git a/drivers/macintosh/via-pmu.c b/drivers/macintosh/via-pmu.c index b0f09c70f1ff..5fe47e784d43 100644 --- a/drivers/macintosh/via-pmu.c +++ b/drivers/macintosh/via-pmu.c @@ -2600,7 +2600,7 @@ void pmu_blink(int n) #if defined(CONFIG_SUSPEND) && defined(CONFIG_PPC32) int pmu_sys_suspended; -static int pmu_syscore_suspend(void) +static int pmu_syscore_suspend(void *data) { /* Suspend PMU event interrupts */ pmu_suspend(); @@ -2614,7 +2614,7 @@ static int pmu_syscore_suspend(void) return 0; } -static void pmu_syscore_resume(void) +static void pmu_syscore_resume(void *data) { struct adb_request req; @@ -2634,14 +2634,18 @@ static void pmu_syscore_resume(void) pmu_sys_suspended = 0; } -static struct syscore_ops pmu_syscore_ops = { +static const struct syscore_ops pmu_syscore_ops = { .suspend = pmu_syscore_suspend, .resume = pmu_syscore_resume, }; +static struct syscore pmu_syscore = { + .ops = &pmu_syscore_ops, +}; + static int pmu_syscore_register(void) { - register_syscore_ops(&pmu_syscore_ops); + register_syscore(&pmu_syscore); return 0; } diff --git a/drivers/power/reset/sc27xx-poweroff.c b/drivers/power/reset/sc27xx-poweroff.c index 90287c31992c..393bd1c33b73 100644 --- a/drivers/power/reset/sc27xx-poweroff.c +++ b/drivers/power/reset/sc27xx-poweroff.c @@ -28,7 +28,7 @@ static struct regmap *regmap; * taking cpus down to avoid racing regmap or spi mutex lock when poweroff * system through PMIC. */ -static void sc27xx_poweroff_shutdown(void) +static void sc27xx_poweroff_shutdown(void *data) { #ifdef CONFIG_HOTPLUG_CPU int cpu; @@ -40,10 +40,14 @@ static void sc27xx_poweroff_shutdown(void) #endif } -static struct syscore_ops poweroff_syscore_ops = { +static const struct syscore_ops poweroff_syscore_ops = { .shutdown = sc27xx_poweroff_shutdown, }; +static struct syscore poweroff_syscore = { + .ops = &poweroff_syscore_ops, +}; + static void sc27xx_poweroff_do_poweroff(void) { /* Disable the external subsys connection's power firstly */ @@ -62,7 +66,7 @@ static int sc27xx_poweroff_probe(struct platform_device *pdev) return -ENODEV; pm_power_off = sc27xx_poweroff_do_poweroff; - register_syscore_ops(&poweroff_syscore_ops); + register_syscore(&poweroff_syscore); return 0; } diff --git a/drivers/sh/clk/core.c b/drivers/sh/clk/core.c index 7a73f5e4a1fc..f02e12dfa5f6 100644 --- a/drivers/sh/clk/core.c +++ b/drivers/sh/clk/core.c @@ -569,7 +569,7 @@ long clk_round_rate(struct clk *clk, unsigned long rate) EXPORT_SYMBOL_GPL(clk_round_rate); #ifdef CONFIG_PM -static void clks_core_resume(void) +static void clks_core_resume(void *data) { struct clk *clkp; @@ -588,13 +588,17 @@ static void clks_core_resume(void) } } -static struct syscore_ops clks_syscore_ops = { +static const struct syscore_ops clks_syscore_ops = { .resume = clks_core_resume, }; +static struct syscore clks_syscore = { + .ops = &clks_syscore_ops, +}; + static int __init clk_syscore_init(void) { - register_syscore_ops(&clks_syscore_ops); + register_syscore(&clks_syscore); return 0; } diff --git a/drivers/sh/intc/core.c b/drivers/sh/intc/core.c index ea571eeb3078..3dde703b7766 100644 --- a/drivers/sh/intc/core.c +++ b/drivers/sh/intc/core.c @@ -394,7 +394,7 @@ int __init register_intc_controller(struct intc_desc *desc) return -ENOMEM; } -static int intc_suspend(void) +static int intc_suspend(void *data) { struct intc_desc_int *d; @@ -420,7 +420,7 @@ static int intc_suspend(void) return 0; } -static void intc_resume(void) +static void intc_resume(void *data) { struct intc_desc_int *d; @@ -450,11 +450,15 @@ static void intc_resume(void) } } -struct syscore_ops intc_syscore_ops = { +static const struct syscore_ops intc_syscore_ops = { .suspend = intc_suspend, .resume = intc_resume, }; +static struct syscore intc_syscore = { + .ops = &intc_syscore_ops, +}; + const struct bus_type intc_subsys = { .name = "intc", .dev_name = "intc", @@ -477,7 +481,7 @@ static int __init register_intc_devs(void) struct intc_desc_int *d; int error; - register_syscore_ops(&intc_syscore_ops); + register_syscore(&intc_syscore); error = subsys_system_register(&intc_subsys, NULL); if (!error) { diff --git a/drivers/soc/bcm/brcmstb/biuctrl.c b/drivers/soc/bcm/brcmstb/biuctrl.c index 364ddbe365c2..bd830649b60d 100644 --- a/drivers/soc/bcm/brcmstb/biuctrl.c +++ b/drivers/soc/bcm/brcmstb/biuctrl.c @@ -298,7 +298,7 @@ static int __init setup_hifcpubiuctrl_regs(struct device_node *np) #ifdef CONFIG_PM_SLEEP static u32 cpubiuctrl_reg_save[NUM_CPU_BIUCTRL_REGS]; -static int brcmstb_cpu_credit_reg_suspend(void) +static int brcmstb_cpu_credit_reg_suspend(void *data) { unsigned int i; @@ -311,7 +311,7 @@ static int brcmstb_cpu_credit_reg_suspend(void) return 0; } -static void brcmstb_cpu_credit_reg_resume(void) +static void brcmstb_cpu_credit_reg_resume(void *data) { unsigned int i; @@ -322,10 +322,14 @@ static void brcmstb_cpu_credit_reg_resume(void) cbc_writel(cpubiuctrl_reg_save[i], i); } -static struct syscore_ops brcmstb_cpu_credit_syscore_ops = { +static const struct syscore_ops brcmstb_cpu_credit_syscore_ops = { .suspend = brcmstb_cpu_credit_reg_suspend, .resume = brcmstb_cpu_credit_reg_resume, }; + +static struct syscore brcmstb_cpu_credit_syscore = { + .ops = &brcmstb_cpu_credit_syscore_ops, +}; #endif @@ -354,7 +358,7 @@ static int __init brcmstb_biuctrl_init(void) a72_b53_rac_enable_all(np); mcp_a72_b53_set(); #ifdef CONFIG_PM_SLEEP - register_syscore_ops(&brcmstb_cpu_credit_syscore_ops); + register_syscore(&brcmstb_cpu_credit_syscore); #endif ret = 0; out_put: diff --git a/drivers/soc/tegra/pmc.c b/drivers/soc/tegra/pmc.c index 034a2a535a1e..93bbebd68001 100644 --- a/drivers/soc/tegra/pmc.c +++ b/drivers/soc/tegra/pmc.c @@ -466,7 +466,7 @@ struct tegra_pmc { unsigned long *wake_type_dual_edge_map; unsigned long *wake_sw_status_map; unsigned long *wake_cntrl_level_map; - struct syscore_ops syscore; + struct syscore syscore; }; static struct tegra_pmc *pmc = &(struct tegra_pmc) { @@ -3147,7 +3147,7 @@ static void tegra186_pmc_process_wake_events(struct tegra_pmc *pmc, unsigned int } } -static void tegra186_pmc_wake_syscore_resume(void) +static void tegra186_pmc_wake_syscore_resume(void *data) { u32 status, mask; unsigned int i; @@ -3160,7 +3160,7 @@ static void tegra186_pmc_wake_syscore_resume(void) } } -static int tegra186_pmc_wake_syscore_suspend(void) +static int tegra186_pmc_wake_syscore_suspend(void *data) { wke_read_sw_wake_status(pmc); @@ -3179,6 +3179,11 @@ static int tegra186_pmc_wake_syscore_suspend(void) return 0; } +static const struct syscore_ops tegra186_pmc_wake_syscore_ops = { + .suspend = tegra186_pmc_wake_syscore_suspend, + .resume = tegra186_pmc_wake_syscore_resume, +}; + #if defined(CONFIG_PM_SLEEP) && defined(CONFIG_ARM) static int tegra_pmc_suspend(struct device *dev) { @@ -3829,10 +3834,8 @@ static const struct tegra_pmc_regs tegra186_pmc_regs = { static void tegra186_pmc_init(struct tegra_pmc *pmc) { - pmc->syscore.suspend = tegra186_pmc_wake_syscore_suspend; - pmc->syscore.resume = tegra186_pmc_wake_syscore_resume; - - register_syscore_ops(&pmc->syscore); + pmc->syscore.ops = &tegra186_pmc_wake_syscore_ops; + register_syscore(&pmc->syscore); } static void tegra186_pmc_setup_irq_polarity(struct tegra_pmc *pmc, diff --git a/drivers/thermal/intel/intel_hfi.c b/drivers/thermal/intel/intel_hfi.c index bd2fca7dc017..8a2f441cd2ec 100644 --- a/drivers/thermal/intel/intel_hfi.c +++ b/drivers/thermal/intel/intel_hfi.c @@ -592,7 +592,7 @@ static void hfi_disable_instance(void *ptr) hfi_disable(); } -static void hfi_syscore_resume(void) +static void hfi_syscore_resume(void *data) { /* This code runs only on the boot CPU. */ struct hfi_cpu_info *info = &per_cpu(hfi_cpu_info, 0); @@ -603,7 +603,7 @@ static void hfi_syscore_resume(void) hfi_enable_instance(hfi_instance); } -static int hfi_syscore_suspend(void) +static int hfi_syscore_suspend(void *data) { /* No locking needed. There is no concurrency with CPU offline. */ hfi_disable(); @@ -611,11 +611,15 @@ static int hfi_syscore_suspend(void) return 0; } -static struct syscore_ops hfi_pm_ops = { +static const struct syscore_ops hfi_pm_ops = { .resume = hfi_syscore_resume, .suspend = hfi_syscore_suspend, }; +static struct syscore hfi_pm = { + .ops = &hfi_pm_ops, +}; + static int hfi_thermal_notify(struct notifier_block *nb, unsigned long state, void *_notify) { @@ -710,7 +714,7 @@ void __init intel_hfi_init(void) if (thermal_genl_register_notifier(&hfi_thermal_nb)) goto err_nl_notif; - register_syscore_ops(&hfi_pm_ops); + register_syscore(&hfi_pm); return; diff --git a/drivers/xen/xen-acpi-processor.c b/drivers/xen/xen-acpi-processor.c index 296703939846..f2e8eaf684ba 100644 --- a/drivers/xen/xen-acpi-processor.c +++ b/drivers/xen/xen-acpi-processor.c @@ -495,7 +495,7 @@ static void xen_acpi_processor_resume_worker(struct work_struct *dummy) pr_info("ACPI data upload failed, error = %d\n", rc); } -static void xen_acpi_processor_resume(void) +static void xen_acpi_processor_resume(void *data) { static DECLARE_WORK(wq, xen_acpi_processor_resume_worker); @@ -509,10 +509,14 @@ static void xen_acpi_processor_resume(void) schedule_work(&wq); } -static struct syscore_ops xap_syscore_ops = { +static const struct syscore_ops xap_syscore_ops = { .resume = xen_acpi_processor_resume, }; +static struct syscore xap_syscore = { + .ops = &xap_syscore_ops, +}; + static int __init xen_acpi_processor_init(void) { int i; @@ -563,7 +567,7 @@ static int __init xen_acpi_processor_init(void) if (rc) goto err_unregister; - register_syscore_ops(&xap_syscore_ops); + register_syscore(&xap_syscore); return 0; err_unregister: @@ -580,7 +584,7 @@ static void __exit xen_acpi_processor_exit(void) { int i; - unregister_syscore_ops(&xap_syscore_ops); + unregister_syscore(&xap_syscore); bitmap_free(acpi_ids_done); bitmap_free(acpi_id_present); bitmap_free(acpi_id_cst_present); diff --git a/include/linux/syscore_ops.h b/include/linux/syscore_ops.h index ae4d48e4c970..ac6d71be5c38 100644 --- a/include/linux/syscore_ops.h +++ b/include/linux/syscore_ops.h @@ -11,14 +11,19 @@ #include struct syscore_ops { - struct list_head node; - int (*suspend)(void); - void (*resume)(void); - void (*shutdown)(void); + int (*suspend)(void *data); + void (*resume)(void *data); + void (*shutdown)(void *data); }; -extern void register_syscore_ops(struct syscore_ops *ops); -extern void unregister_syscore_ops(struct syscore_ops *ops); +struct syscore { + struct list_head node; + const struct syscore_ops *ops; + void *data; +}; + +extern void register_syscore(struct syscore *syscore); +extern void unregister_syscore(struct syscore *syscore); #ifdef CONFIG_PM_SLEEP extern int syscore_suspend(void); extern void syscore_resume(void); diff --git a/kernel/cpu_pm.c b/kernel/cpu_pm.c index b0f0d15085db..7481fbb947d3 100644 --- a/kernel/cpu_pm.c +++ b/kernel/cpu_pm.c @@ -173,7 +173,7 @@ int cpu_cluster_pm_exit(void) EXPORT_SYMBOL_GPL(cpu_cluster_pm_exit); #ifdef CONFIG_PM -static int cpu_pm_suspend(void) +static int cpu_pm_suspend(void *data) { int ret; @@ -185,20 +185,24 @@ static int cpu_pm_suspend(void) return ret; } -static void cpu_pm_resume(void) +static void cpu_pm_resume(void *data) { cpu_cluster_pm_exit(); cpu_pm_exit(); } -static struct syscore_ops cpu_pm_syscore_ops = { +static const struct syscore_ops cpu_pm_syscore_ops = { .suspend = cpu_pm_suspend, .resume = cpu_pm_resume, }; +static struct syscore cpu_pm_syscore = { + .ops = &cpu_pm_syscore_ops, +}; + static int cpu_pm_init(void) { - register_syscore_ops(&cpu_pm_syscore_ops); + register_syscore(&cpu_pm_syscore); return 0; } core_initcall(cpu_pm_init); diff --git a/kernel/irq/generic-chip.c b/kernel/irq/generic-chip.c index bf59e37d650a..3cd0c40282c0 100644 --- a/kernel/irq/generic-chip.c +++ b/kernel/irq/generic-chip.c @@ -650,7 +650,7 @@ static struct irq_data *irq_gc_get_irq_data(struct irq_chip_generic *gc) } #ifdef CONFIG_PM -static int irq_gc_suspend(void) +static int irq_gc_suspend(void *data) { struct irq_chip_generic *gc; @@ -670,7 +670,7 @@ static int irq_gc_suspend(void) return 0; } -static void irq_gc_resume(void) +static void irq_gc_resume(void *data) { struct irq_chip_generic *gc; @@ -693,7 +693,7 @@ static void irq_gc_resume(void) #define irq_gc_resume NULL #endif -static void irq_gc_shutdown(void) +static void irq_gc_shutdown(void *data) { struct irq_chip_generic *gc; @@ -709,15 +709,19 @@ static void irq_gc_shutdown(void) } } -static struct syscore_ops irq_gc_syscore_ops = { +static const struct syscore_ops irq_gc_syscore_ops = { .suspend = irq_gc_suspend, .resume = irq_gc_resume, .shutdown = irq_gc_shutdown, }; +static struct syscore irq_gc_syscore = { + .ops = &irq_gc_syscore_ops, +}; + static int __init irq_gc_init_ops(void) { - register_syscore_ops(&irq_gc_syscore_ops); + register_syscore(&irq_gc_syscore); return 0; } device_initcall(irq_gc_init_ops); diff --git a/kernel/irq/pm.c b/kernel/irq/pm.c index f7394729cedc..99ff65466d87 100644 --- a/kernel/irq/pm.c +++ b/kernel/irq/pm.c @@ -211,21 +211,26 @@ void rearm_wake_irq(unsigned int irq) /** * irq_pm_syscore_resume - enable interrupt lines early + * @data: syscore context * * Enable all interrupt lines with %IRQF_EARLY_RESUME set. */ -static void irq_pm_syscore_resume(void) +static void irq_pm_syscore_resume(void *data) { resume_irqs(true); } -static struct syscore_ops irq_pm_syscore_ops = { +static const struct syscore_ops irq_pm_syscore_ops = { .resume = irq_pm_syscore_resume, }; +static struct syscore irq_pm_syscore = { + .ops = &irq_pm_syscore_ops, +}; + static int __init irq_pm_init_ops(void) { - register_syscore_ops(&irq_pm_syscore_ops); + register_syscore(&irq_pm_syscore); return 0; } diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c index 5aee9ffb16b9..f852dce94015 100644 --- a/kernel/printk/printk.c +++ b/kernel/printk/printk.c @@ -3639,12 +3639,13 @@ static bool legacy_kthread_create(void) /** * printk_kthreads_shutdown - shutdown all threaded printers + * @data: syscore context * * On system shutdown all threaded printers are stopped. This allows printk * to transition back to atomic printing, thus providing a robust mechanism * for the final shutdown/reboot messages to be output. */ -static void printk_kthreads_shutdown(void) +static void printk_kthreads_shutdown(void *data) { struct console *con; @@ -3666,10 +3667,14 @@ static void printk_kthreads_shutdown(void) console_list_unlock(); } -static struct syscore_ops printk_syscore_ops = { +static const struct syscore_ops printk_syscore_ops = { .shutdown = printk_kthreads_shutdown, }; +static struct syscore printk_syscore = { + .ops = &printk_syscore_ops, +}; + /* * If appropriate, start nbcon kthreads and set @printk_kthreads_running. * If any kthreads fail to start, those consoles are unregistered. @@ -3737,7 +3742,7 @@ static void printk_kthreads_check_locked(void) static int __init printk_set_kthreads_ready(void) { - register_syscore_ops(&printk_syscore_ops); + register_syscore(&printk_syscore); console_list_lock(); printk_kthreads_ready = true; diff --git a/kernel/time/sched_clock.c b/kernel/time/sched_clock.c index cc1afec306b3..f39111830ca3 100644 --- a/kernel/time/sched_clock.c +++ b/kernel/time/sched_clock.c @@ -296,6 +296,11 @@ int sched_clock_suspend(void) return 0; } +static int sched_clock_syscore_suspend(void *data) +{ + return sched_clock_suspend(); +} + void sched_clock_resume(void) { struct clock_read_data *rd = &cd.read_data[0]; @@ -305,14 +310,23 @@ void sched_clock_resume(void) rd->read_sched_clock = cd.actual_read_sched_clock; } -static struct syscore_ops sched_clock_ops = { - .suspend = sched_clock_suspend, - .resume = sched_clock_resume, +static void sched_clock_syscore_resume(void *data) +{ + sched_clock_resume(); +} + +static const struct syscore_ops sched_clock_syscore_ops = { + .suspend = sched_clock_syscore_suspend, + .resume = sched_clock_syscore_resume, +}; + +static struct syscore sched_clock_syscore = { + .ops = &sched_clock_syscore_ops, }; static int __init sched_clock_syscore_init(void) { - register_syscore_ops(&sched_clock_ops); + register_syscore(&sched_clock_syscore); return 0; } diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c index b6974fce800c..f3513679ee09 100644 --- a/kernel/time/timekeeping.c +++ b/kernel/time/timekeeping.c @@ -1994,6 +1994,11 @@ void timekeeping_resume(void) timerfd_resume(); } +static void timekeeping_syscore_resume(void *data) +{ + timekeeping_resume(); +} + int timekeeping_suspend(void) { struct timekeeper *tks = &tk_core.shadow_timekeeper; @@ -2061,15 +2066,24 @@ int timekeeping_suspend(void) return 0; } +static int timekeeping_syscore_suspend(void *data) +{ + return timekeeping_suspend(); +} + /* sysfs resume/suspend bits for timekeeping */ -static struct syscore_ops timekeeping_syscore_ops = { - .resume = timekeeping_resume, - .suspend = timekeeping_suspend, +static const struct syscore_ops timekeeping_syscore_ops = { + .resume = timekeeping_syscore_resume, + .suspend = timekeeping_syscore_suspend, +}; + +static struct syscore timekeeping_syscore = { + .ops = &timekeeping_syscore_ops, }; static int __init timekeeping_init_ops(void) { - register_syscore_ops(&timekeeping_syscore_ops); + register_syscore(&timekeeping_syscore); return 0; } device_initcall(timekeeping_init_ops); diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index 226faeaa8e56..b7675a58d663 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -5629,7 +5629,7 @@ static int kvm_offline_cpu(unsigned int cpu) return 0; } -static void kvm_shutdown(void) +static void kvm_shutdown(void *data) { /* * Disable hardware virtualization and set kvm_rebooting to indicate @@ -5647,7 +5647,7 @@ static void kvm_shutdown(void) on_each_cpu(kvm_disable_virtualization_cpu, NULL, 1); } -static int kvm_suspend(void) +static int kvm_suspend(void *data) { /* * Secondary CPUs and CPU hotplug are disabled across the suspend/resume @@ -5664,7 +5664,7 @@ static int kvm_suspend(void) return 0; } -static void kvm_resume(void) +static void kvm_resume(void *data) { lockdep_assert_not_held(&kvm_usage_lock); lockdep_assert_irqs_disabled(); @@ -5672,12 +5672,16 @@ static void kvm_resume(void) WARN_ON_ONCE(kvm_enable_virtualization_cpu()); } -static struct syscore_ops kvm_syscore_ops = { +static const struct syscore_ops kvm_syscore_ops = { .suspend = kvm_suspend, .resume = kvm_resume, .shutdown = kvm_shutdown, }; +static struct syscore kvm_syscore = { + .ops = &kvm_syscore_ops, +}; + int kvm_enable_virtualization(void) { int r; @@ -5694,7 +5698,7 @@ int kvm_enable_virtualization(void) if (r) goto err_cpuhp; - register_syscore_ops(&kvm_syscore_ops); + register_syscore(&kvm_syscore); /* * Undo virtualization enabling and bail if the system is going down. @@ -5716,7 +5720,7 @@ int kvm_enable_virtualization(void) return 0; err_rebooting: - unregister_syscore_ops(&kvm_syscore_ops); + unregister_syscore(&kvm_syscore); cpuhp_remove_state(CPUHP_AP_KVM_ONLINE); err_cpuhp: kvm_arch_disable_virtualization(); @@ -5732,7 +5736,7 @@ void kvm_disable_virtualization(void) if (--kvm_usage_count) return; - unregister_syscore_ops(&kvm_syscore_ops); + unregister_syscore(&kvm_syscore); cpuhp_remove_state(CPUHP_AP_KVM_ONLINE); kvm_arch_disable_virtualization(); } From c87f820bc4748fdd4d50969e8930cd88d1b61582 Mon Sep 17 00:00:00 2001 From: Kartik Rajput Date: Wed, 8 Oct 2025 16:46:18 +0530 Subject: [PATCH 089/114] soc/tegra: fuse: Do not register SoC device on ACPI boot On Tegra platforms using ACPI, the SMCCC driver already registers the SoC device. This makes the registration performed by the Tegra fuse driver redundant. When booted via ACPI, skip registering the SoC device and suppress printing SKU information from the Tegra fuse driver, as this information is already provided by the SMCCC driver. Fixes: 972167c69080 ("soc/tegra: fuse: Add ACPI support for Tegra194 and Tegra234") Cc: stable@vger.kernel.org Signed-off-by: Kartik Rajput Signed-off-by: Thierry Reding --- drivers/soc/tegra/fuse/fuse-tegra.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/soc/tegra/fuse/fuse-tegra.c b/drivers/soc/tegra/fuse/fuse-tegra.c index d27667283846..74d2fedea71c 100644 --- a/drivers/soc/tegra/fuse/fuse-tegra.c +++ b/drivers/soc/tegra/fuse/fuse-tegra.c @@ -182,8 +182,6 @@ static int tegra_fuse_probe(struct platform_device *pdev) } fuse->soc->init(fuse); - tegra_fuse_print_sku_info(&tegra_sku_info); - tegra_soc_device_register(); err = tegra_fuse_add_lookups(fuse); if (err) From e13c1f34aa8675363f45593e85c125e15b9a4410 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bruno=20Sobreira=20Fran=C3=A7a?= Date: Fri, 24 Oct 2025 01:35:14 +0000 Subject: [PATCH 090/114] soc/tegra: Resolve a spelling error in the tegra194-cbb.c MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix a typo spotted during code reading. Signed-off-by: Bruno Sobreira França Reviewed-by: Jon Hunter Acked-by: Uwe Kleine-König Reviewed-by: Herve Codina Signed-off-by: Thierry Reding --- drivers/soc/tegra/cbb/tegra194-cbb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/soc/tegra/cbb/tegra194-cbb.c b/drivers/soc/tegra/cbb/tegra194-cbb.c index c1bdea8c853f..ab75d50cc85c 100644 --- a/drivers/soc/tegra/cbb/tegra194-cbb.c +++ b/drivers/soc/tegra/cbb/tegra194-cbb.c @@ -1836,7 +1836,7 @@ print_errlog1_2(struct seq_file *file, struct tegra194_cbb *cbb, } /* - * Print transcation type, error code and description from ErrLog0 for all + * Print transaction type, error code and description from ErrLog0 for all * errors. For NOC target errors, all relevant error info is printed using * ErrLog0 only. But additional information is printed for errors from * APB targets because for them: From ce27c9c2129679551c4e5fe71c1c5d42fff399c2 Mon Sep 17 00:00:00 2001 From: Aaron Kling Date: Tue, 23 Sep 2025 11:58:05 -0500 Subject: [PATCH 091/114] soc/tegra: fuse: speedo-tegra210: Update speedo IDs Existing code only sets CPU and GPU speedo IDs 0 and 1. The CPU DVFS code supports 11 IDs and nouveau supports 5. This aligns with what the downstream vendor kernel supports. Align SKUs with the downstream list. The Tegra210 CVB tables were added in the first referenced fixes commit. Since then, all Tegra210 SoCs have tried to scale to 1.9 GHz, when the supported devkits are only supposed to scale to 1.5 or 1.7 GHZ. Overclocking should not be the default state. Fixes: 2b2dbc2f94e5 ("clk: tegra: dfll: add CVB tables for Tegra210") Fixes: 579db6e5d9b8 ("arm64: tegra: Enable DFLL support on Jetson Nano") Signed-off-by: Aaron Kling Signed-off-by: Thierry Reding --- drivers/soc/tegra/fuse/speedo-tegra210.c | 58 +++++++++++++++++------- 1 file changed, 41 insertions(+), 17 deletions(-) diff --git a/drivers/soc/tegra/fuse/speedo-tegra210.c b/drivers/soc/tegra/fuse/speedo-tegra210.c index 695d0b7f9a8a..a8cc36329772 100644 --- a/drivers/soc/tegra/fuse/speedo-tegra210.c +++ b/drivers/soc/tegra/fuse/speedo-tegra210.c @@ -65,27 +65,51 @@ static void __init rev_sku_to_speedo_ids(struct tegra_sku_info *sku_info, sku_info->gpu_speedo_id = 0; *threshold = THRESHOLD_INDEX_0; - switch (sku) { - case 0x00: /* Engineering SKU */ - case 0x01: /* Engineering SKU */ - case 0x07: - case 0x17: - case 0x27: - if (speedo_rev >= 2) + if (sku_info->revision >= TEGRA_REVISION_A02) { + switch (sku) { + case 0x00: /* Engineering SKU */ + case 0x01: /* Engineering SKU */ + case 0x13: + sku_info->cpu_speedo_id = 5; + sku_info->gpu_speedo_id = 2; + break; + + case 0x07: + case 0x17: + case 0x1F: + sku_info->cpu_speedo_id = 7; + sku_info->gpu_speedo_id = 2; + break; + + case 0x27: + sku_info->cpu_speedo_id = 1; + sku_info->gpu_speedo_id = 2; + break; + + case 0x83: + sku_info->cpu_speedo_id = 3; + sku_info->gpu_speedo_id = 3; + break; + + case 0x87: + sku_info->cpu_speedo_id = 2; sku_info->gpu_speedo_id = 1; - break; + break; - case 0x13: - if (speedo_rev >= 2) - sku_info->gpu_speedo_id = 1; + case 0x8F: + sku_info->cpu_speedo_id = 9; + sku_info->gpu_speedo_id = 2; + break; - sku_info->cpu_speedo_id = 1; - break; - - default: + default: + pr_err("Tegra210: unknown revision 2 or newer SKU %#04x\n", sku); + /* Using the default for the error case */ + break; + } + } else if (sku == 0x00 || sku == 0x01 || sku == 0x07 || sku == 0x13 || sku == 0x17) { + sku_info->gpu_speedo_id = 1; + } else { pr_err("Tegra210: unknown SKU %#04x\n", sku); - /* Using the default for the error case */ - break; } } From 688dfe40b4d7b33047cfa009f4f88a9526265126 Mon Sep 17 00:00:00 2001 From: Aaron Kling Date: Tue, 21 Oct 2025 22:11:15 -0500 Subject: [PATCH 092/114] soc/tegra: fuse: speedo-tegra210: Add SoC speedo 2 The Jetson Nano series of modules only have 2 EMC table entries, different from other SoC SKUs. As the EMC driver uses the SoC speedo ID to populate the EMC OPP tables, add a new speedo ID to uniquely identify this. Signed-off-by: Aaron Kling Reviewed-by: Mikko Perttunen Signed-off-by: Thierry Reding --- drivers/soc/tegra/fuse/speedo-tegra210.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/soc/tegra/fuse/speedo-tegra210.c b/drivers/soc/tegra/fuse/speedo-tegra210.c index a8cc36329772..06c2bcbee573 100644 --- a/drivers/soc/tegra/fuse/speedo-tegra210.c +++ b/drivers/soc/tegra/fuse/speedo-tegra210.c @@ -97,6 +97,7 @@ static void __init rev_sku_to_speedo_ids(struct tegra_sku_info *sku_info, break; case 0x8F: + sku_info->soc_speedo_id = 2; sku_info->cpu_speedo_id = 9; sku_info->gpu_speedo_id = 2; break; From 1c458bbe4b335d1675c47d64df0c8cd34961d2bf Mon Sep 17 00:00:00 2001 From: Prathamesh Shete Date: Fri, 14 Nov 2025 16:17:11 +0000 Subject: [PATCH 093/114] soc/tegra: pmc: Don't fail if "aotag" is not present The "aotog" is an optional aperture, so if that aperture is not defined for a given device, then initialise the 'aotag' pointer to NULL instead of returning an error. Note that the PMC driver will not use 'aotag' pointer if initialised to NULL. Co-developed-by: Shardar Mohammed Signed-off-by: Shardar Mohammed Signed-off-by: Prathamesh Shete Signed-off-by: Jon Hunter Signed-off-by: Thierry Reding --- drivers/soc/tegra/pmc.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/drivers/soc/tegra/pmc.c b/drivers/soc/tegra/pmc.c index 034a2a535a1e..d8c8894a8f38 100644 --- a/drivers/soc/tegra/pmc.c +++ b/drivers/soc/tegra/pmc.c @@ -2897,9 +2897,16 @@ static int tegra_pmc_probe(struct platform_device *pdev) if (IS_ERR(pmc->wake)) return PTR_ERR(pmc->wake); - pmc->aotag = devm_platform_ioremap_resource_byname(pdev, "aotag"); - if (IS_ERR(pmc->aotag)) - return PTR_ERR(pmc->aotag); + /* "aotag" is an optional aperture */ + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, + "aotag"); + if (res) { + pmc->aotag = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(pmc->aotag)) + return PTR_ERR(pmc->aotag); + } else { + pmc->aotag = NULL; + } /* "scratch" is an optional aperture */ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, From aaca2e9933a362bcd89ec563b3e89de18460335f Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Wed, 29 Oct 2025 16:10:33 +0100 Subject: [PATCH 094/114] soc/tegra: pmc: Document tegra_pmc.syscore field This eliminates a warning from the documentation build targets. Signed-off-by: Thierry Reding --- drivers/soc/tegra/pmc.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/soc/tegra/pmc.c b/drivers/soc/tegra/pmc.c index d8c8894a8f38..3f2ae5fe3135 100644 --- a/drivers/soc/tegra/pmc.c +++ b/drivers/soc/tegra/pmc.c @@ -423,6 +423,7 @@ struct tegra_pmc_soc { * @wake_sw_status_map: Bitmap to hold raw status of wakes without mask * @wake_cntrl_level_map: Bitmap to hold wake levels to be programmed in * cntrl register associated with each wake during system suspend. + * @syscore: syscore suspend/resume callbacks */ struct tegra_pmc { struct device *dev; From 500e1368e46928f4b2259612dcabb6999afae2a6 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Thu, 25 Sep 2025 17:00:07 +0200 Subject: [PATCH 095/114] amba: tegra-ahb: Fix device leak on SMMU enable Make sure to drop the reference taken to the AHB platform device when looking up its driver data while enabling the SMMU. Note that holding a reference to a device does not prevent its driver data from going away. Fixes: 89c788bab1f0 ("ARM: tegra: Add SMMU enabler in AHB") Cc: stable@vger.kernel.org # 3.5 Signed-off-by: Johan Hovold Signed-off-by: Thierry Reding --- drivers/amba/tegra-ahb.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/amba/tegra-ahb.c b/drivers/amba/tegra-ahb.c index c0e8b765522d..f23c3ed01810 100644 --- a/drivers/amba/tegra-ahb.c +++ b/drivers/amba/tegra-ahb.c @@ -144,6 +144,7 @@ int tegra_ahb_enable_smmu(struct device_node *dn) if (!dev) return -EPROBE_DEFER; ahb = dev_get_drvdata(dev); + put_device(dev); val = gizmo_readl(ahb, AHB_ARBITRATION_XBAR_CTRL); val |= AHB_ARBITRATION_XBAR_CTRL_SMMU_INIT_DONE; gizmo_writel(ahb, val, AHB_ARBITRATION_XBAR_CTRL); From dd03d34d6d8e7a3f62450fb7a1408d86fb35487c Mon Sep 17 00:00:00 2001 From: Haotien Hsu Date: Mon, 11 Aug 2025 15:45:57 +0800 Subject: [PATCH 096/114] soc/tegra: pmc: Add USB wake events for Tegra234 Add USB wake events for Tegra234 so that system can be woken up from suspend when USB devices hot-plug/unplug event is detected. Signed-off-by: Haotien Hsu Signed-off-by: Thierry Reding --- drivers/soc/tegra/pmc.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/soc/tegra/pmc.c b/drivers/soc/tegra/pmc.c index 3f2ae5fe3135..ad19efade196 100644 --- a/drivers/soc/tegra/pmc.c +++ b/drivers/soc/tegra/pmc.c @@ -4222,6 +4222,13 @@ static const struct tegra_wake_event tegra234_wake_events[] = { TEGRA_WAKE_GPIO("power", 29, 1, TEGRA234_AON_GPIO(EE, 4)), TEGRA_WAKE_GPIO("mgbe", 56, 0, TEGRA234_MAIN_GPIO(Y, 3)), TEGRA_WAKE_IRQ("rtc", 73, 10), + TEGRA_WAKE_IRQ("usb3-port-0", 76, 167), + TEGRA_WAKE_IRQ("usb3-port-1", 77, 167), + TEGRA_WAKE_IRQ("usb3-port-2-3", 78, 167), + TEGRA_WAKE_IRQ("usb2-port-0", 79, 167), + TEGRA_WAKE_IRQ("usb2-port-1", 80, 167), + TEGRA_WAKE_IRQ("usb2-port-2", 81, 167), + TEGRA_WAKE_IRQ("usb2-port-3", 82, 167), TEGRA_WAKE_IRQ("sw-wake", SW_WAKE_ID, 179), }; From 048213a38e7ac1591f725e370c152cc80dd84105 Mon Sep 17 00:00:00 2001 From: Heiko Stuebner Date: Tue, 21 Oct 2025 09:42:48 +0200 Subject: [PATCH 097/114] soc: rockchip: grf: Add select correct PWM implementation on RK3368 Similar to the RK3288, the RK3368 has two different implementations of the PWM block inside the SoC - the newer ones that we have a driver for and that is used on every SoC and a previous variant that was likely left as a fallback if the new one creates problems. The devicetree is already set up for the new variant, so make sure we actually use it - similar to the RK3288. Signed-off-by: Heiko Stuebner Link: https://patch.msgid.link/20251021074254.87065-4-heiko@sntech.de Signed-off-by: Heiko Stuebner --- drivers/soc/rockchip/grf.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/soc/rockchip/grf.c b/drivers/soc/rockchip/grf.c index c0c2ec1296f5..27bfa09ff251 100644 --- a/drivers/soc/rockchip/grf.c +++ b/drivers/soc/rockchip/grf.c @@ -91,6 +91,7 @@ static const struct rockchip_grf_info rk3328_grf __initconst = { static const struct rockchip_grf_value rk3368_defaults[] __initconst = { { "jtag switching", RK3368_GRF_SOC_CON15, FIELD_PREP_WM16_CONST(BIT(13), 0) }, + { "pwm select", RK3368_GRF_SOC_CON15, FIELD_PREP_WM16_CONST(BIT(12), 1) }, }; static const struct rockchip_grf_info rk3368_grf __initconst = { From fc80e57c51a2825ed7c995c1e7e95c9d7cb6fada Mon Sep 17 00:00:00 2001 From: Robert Marko Date: Mon, 22 Sep 2025 16:27:28 +0200 Subject: [PATCH 098/114] dt-bindings: reset: microchip: Add LAN969x support LAN969x also uses the Microchip reset driver, it reuses the LAN966x support so use a fallback compatible. Signed-off-by: Robert Marko Acked-by: Conor Dooley Signed-off-by: Philipp Zabel --- .../devicetree/bindings/reset/microchip,rst.yaml | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/Documentation/devicetree/bindings/reset/microchip,rst.yaml b/Documentation/devicetree/bindings/reset/microchip,rst.yaml index f2da0693b05a..e190e526f3e9 100644 --- a/Documentation/devicetree/bindings/reset/microchip,rst.yaml +++ b/Documentation/devicetree/bindings/reset/microchip,rst.yaml @@ -20,9 +20,14 @@ properties: pattern: "^reset-controller@[0-9a-f]+$" compatible: - enum: - - microchip,sparx5-switch-reset - - microchip,lan966x-switch-reset + oneOf: + - enum: + - microchip,sparx5-switch-reset + - microchip,lan966x-switch-reset + - items: + - enum: + - microchip,lan9691-switch-reset + - const: microchip,lan966x-switch-reset reg: items: From bf919ccfced7d47d14ec2d20ae465e8ae410aee6 Mon Sep 17 00:00:00 2001 From: Robert Marko Date: Mon, 22 Sep 2025 16:27:29 +0200 Subject: [PATCH 099/114] reset: sparx5: add LAN969x support LAN969x uses the same reset configuration as LAN966x, but we need to allow compiling it when ARCH_LAN969X is selected. A fallback compatible to LAN966x will be used. Signed-off-by: Robert Marko Signed-off-by: Philipp Zabel --- drivers/reset/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig index 78b7078478d4..59245cd0c393 100644 --- a/drivers/reset/Kconfig +++ b/drivers/reset/Kconfig @@ -170,7 +170,7 @@ config RESET_LPC18XX config RESET_MCHP_SPARX5 tristate "Microchip Sparx5 reset driver" - depends on ARCH_SPARX5 || SOC_LAN966 || MCHP_LAN966X_PCI || COMPILE_TEST + depends on ARCH_SPARX5 || ARCH_LAN969X || SOC_LAN966 || MCHP_LAN966X_PCI || COMPILE_TEST default y if SPARX5_SWITCH select MFD_SYSCON help From 23818ebb9c76bac8dfedec252cf33157230efc23 Mon Sep 17 00:00:00 2001 From: Xuyang Dong Date: Tue, 30 Sep 2025 17:32:18 +0800 Subject: [PATCH 100/114] dt-bindings: reset: eswin: Documentation for eic7700 SoC Add device tree binding documentation and header file for the ESWIN eic7700 reset controller module. Signed-off-by: Yifeng Huang Signed-off-by: Xuyang Dong Reviewed-by: Krzysztof Kozlowski Signed-off-by: Philipp Zabel --- .../bindings/reset/eswin,eic7700-reset.yaml | 42 +++ .../dt-bindings/reset/eswin,eic7700-reset.h | 298 ++++++++++++++++++ 2 files changed, 340 insertions(+) create mode 100644 Documentation/devicetree/bindings/reset/eswin,eic7700-reset.yaml create mode 100644 include/dt-bindings/reset/eswin,eic7700-reset.h diff --git a/Documentation/devicetree/bindings/reset/eswin,eic7700-reset.yaml b/Documentation/devicetree/bindings/reset/eswin,eic7700-reset.yaml new file mode 100644 index 000000000000..cf2fdb907571 --- /dev/null +++ b/Documentation/devicetree/bindings/reset/eswin,eic7700-reset.yaml @@ -0,0 +1,42 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/reset/eswin,eic7700-reset.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: ESWIN EIC7700 SoC reset controller + +maintainers: + - Yifeng Huang + - Xuyang Dong + +description: + The system reset controller can be used to reset various peripheral + controllers in ESWIN eic7700 SoC. + +properties: + compatible: + const: eswin,eic7700-reset + + reg: + maxItems: 1 + + '#reset-cells': + const: 1 + +required: + - compatible + - reg + - '#reset-cells' + +additionalProperties: false + +examples: + - | + #include + + reset-controller@51828300 { + compatible = "eswin,eic7700-reset"; + reg = <0x51828300 0x200>; + #reset-cells = <1>; + }; diff --git a/include/dt-bindings/reset/eswin,eic7700-reset.h b/include/dt-bindings/reset/eswin,eic7700-reset.h new file mode 100644 index 000000000000..a370c9f74307 --- /dev/null +++ b/include/dt-bindings/reset/eswin,eic7700-reset.h @@ -0,0 +1,298 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ +/* + * Copyright 2025, Beijing ESWIN Computing Technology Co., Ltd.. + * All rights reserved. + * + * Device Tree binding constants for EIC7700 reset controller. + * + * Authors: + * Yifeng Huang + * Xuyang Dong + */ + +#ifndef __DT_ESWIN_EIC7700_RESET_H__ +#define __DT_ESWIN_EIC7700_RESET_H__ + +#define EIC7700_RESET_NOC_NSP 0 +#define EIC7700_RESET_NOC_CFG 1 +#define EIC7700_RESET_RNOC_NSP 2 +#define EIC7700_RESET_SNOC_TCU 3 +#define EIC7700_RESET_SNOC_U84 4 +#define EIC7700_RESET_SNOC_PCIE_XSR 5 +#define EIC7700_RESET_SNOC_PCIE_XMR 6 +#define EIC7700_RESET_SNOC_PCIE_PR 7 +#define EIC7700_RESET_SNOC_NPU 8 +#define EIC7700_RESET_SNOC_JTAG 9 +#define EIC7700_RESET_SNOC_DSP 10 +#define EIC7700_RESET_SNOC_DDRC1_P2 11 +#define EIC7700_RESET_SNOC_DDRC1_P1 12 +#define EIC7700_RESET_SNOC_DDRC0_P2 13 +#define EIC7700_RESET_SNOC_DDRC0_P1 14 +#define EIC7700_RESET_SNOC_D2D 15 +#define EIC7700_RESET_SNOC_AON 16 +#define EIC7700_RESET_GPU_AXI 17 +#define EIC7700_RESET_GPU_CFG 18 +#define EIC7700_RESET_GPU_GRAY 19 +#define EIC7700_RESET_GPU_JONES 20 +#define EIC7700_RESET_GPU_SPU 21 +#define EIC7700_RESET_DSP_AXI 22 +#define EIC7700_RESET_DSP_CFG 23 +#define EIC7700_RESET_DSP_DIV4 24 +#define EIC7700_RESET_DSP_DIV0 25 +#define EIC7700_RESET_DSP_DIV1 26 +#define EIC7700_RESET_DSP_DIV2 27 +#define EIC7700_RESET_DSP_DIV3 28 +#define EIC7700_RESET_D2D_AXI 29 +#define EIC7700_RESET_D2D_CFG 30 +#define EIC7700_RESET_D2D_PRST 31 +#define EIC7700_RESET_D2D_RAW_PCS 32 +#define EIC7700_RESET_D2D_RX 33 +#define EIC7700_RESET_D2D_TX 34 +#define EIC7700_RESET_D2D_CORE 35 +#define EIC7700_RESET_DDR1_ARST 36 +#define EIC7700_RESET_DDR1_TRACE 37 +#define EIC7700_RESET_DDR0_ARST 38 +#define EIC7700_RESET_DDR_CFG 39 +#define EIC7700_RESET_DDR0_TRACE 40 +#define EIC7700_RESET_DDR_CORE 41 +#define EIC7700_RESET_DDR_PRST 42 +#define EIC7700_RESET_TCU_AXI 43 +#define EIC7700_RESET_TCU_CFG 44 +#define EIC7700_RESET_TCU_TBU0 45 +#define EIC7700_RESET_TCU_TBU1 46 +#define EIC7700_RESET_TCU_TBU2 47 +#define EIC7700_RESET_TCU_TBU3 48 +#define EIC7700_RESET_TCU_TBU4 49 +#define EIC7700_RESET_TCU_TBU5 50 +#define EIC7700_RESET_TCU_TBU6 51 +#define EIC7700_RESET_TCU_TBU7 52 +#define EIC7700_RESET_TCU_TBU8 53 +#define EIC7700_RESET_TCU_TBU9 54 +#define EIC7700_RESET_TCU_TBU10 55 +#define EIC7700_RESET_TCU_TBU11 56 +#define EIC7700_RESET_TCU_TBU12 57 +#define EIC7700_RESET_TCU_TBU13 58 +#define EIC7700_RESET_TCU_TBU14 59 +#define EIC7700_RESET_TCU_TBU15 60 +#define EIC7700_RESET_TCU_TBU16 61 +#define EIC7700_RESET_NPU_AXI 62 +#define EIC7700_RESET_NPU_CFG 63 +#define EIC7700_RESET_NPU_CORE 64 +#define EIC7700_RESET_NPU_E31CORE 65 +#define EIC7700_RESET_NPU_E31BUS 66 +#define EIC7700_RESET_NPU_E31DBG 67 +#define EIC7700_RESET_NPU_LLC 68 +#define EIC7700_RESET_HSP_AXI 69 +#define EIC7700_RESET_HSP_CFG 70 +#define EIC7700_RESET_HSP_POR 71 +#define EIC7700_RESET_MSHC0_PHY 72 +#define EIC7700_RESET_MSHC1_PHY 73 +#define EIC7700_RESET_MSHC2_PHY 74 +#define EIC7700_RESET_MSHC0_TXRX 75 +#define EIC7700_RESET_MSHC1_TXRX 76 +#define EIC7700_RESET_MSHC2_TXRX 77 +#define EIC7700_RESET_SATA_ASIC0 78 +#define EIC7700_RESET_SATA_OOB 79 +#define EIC7700_RESET_SATA_PMALIVE 80 +#define EIC7700_RESET_SATA_RBC 81 +#define EIC7700_RESET_DMA0 82 +#define EIC7700_RESET_HSP_DMA 83 +#define EIC7700_RESET_USB0_VAUX 84 +#define EIC7700_RESET_USB1_VAUX 85 +#define EIC7700_RESET_HSP_SD1_PRST 86 +#define EIC7700_RESET_HSP_SD0_PRST 87 +#define EIC7700_RESET_HSP_EMMC_PRST 88 +#define EIC7700_RESET_HSP_DMA_PRST 89 +#define EIC7700_RESET_HSP_SD1_ARST 90 +#define EIC7700_RESET_HSP_SD0_ARST 91 +#define EIC7700_RESET_HSP_EMMC_ARST 92 +#define EIC7700_RESET_HSP_DMA_ARST 93 +#define EIC7700_RESET_HSP_ETH1_ARST 94 +#define EIC7700_RESET_HSP_ETH0_ARST 95 +#define EIC7700_RESET_SATA_ARST 96 +#define EIC7700_RESET_PCIE_CFG 97 +#define EIC7700_RESET_PCIE_POWEUP 98 +#define EIC7700_RESET_PCIE_PERST 99 +#define EIC7700_RESET_I2C0 100 +#define EIC7700_RESET_I2C1 101 +#define EIC7700_RESET_I2C2 102 +#define EIC7700_RESET_I2C3 103 +#define EIC7700_RESET_I2C4 104 +#define EIC7700_RESET_I2C5 105 +#define EIC7700_RESET_I2C6 106 +#define EIC7700_RESET_I2C7 107 +#define EIC7700_RESET_I2C8 108 +#define EIC7700_RESET_I2C9 109 +#define EIC7700_RESET_FAN 110 +#define EIC7700_RESET_PVT0 111 +#define EIC7700_RESET_PVT1 112 +#define EIC7700_RESET_MBOX0 113 +#define EIC7700_RESET_MBOX1 114 +#define EIC7700_RESET_MBOX2 115 +#define EIC7700_RESET_MBOX3 116 +#define EIC7700_RESET_MBOX4 117 +#define EIC7700_RESET_MBOX5 118 +#define EIC7700_RESET_MBOX6 119 +#define EIC7700_RESET_MBOX7 120 +#define EIC7700_RESET_MBOX8 121 +#define EIC7700_RESET_MBOX9 122 +#define EIC7700_RESET_MBOX10 123 +#define EIC7700_RESET_MBOX11 124 +#define EIC7700_RESET_MBOX12 125 +#define EIC7700_RESET_MBOX13 126 +#define EIC7700_RESET_MBOX14 127 +#define EIC7700_RESET_MBOX15 128 +#define EIC7700_RESET_UART0 129 +#define EIC7700_RESET_UART1 130 +#define EIC7700_RESET_UART2 131 +#define EIC7700_RESET_UART3 132 +#define EIC7700_RESET_UART4 133 +#define EIC7700_RESET_GPIO0 134 +#define EIC7700_RESET_GPIO1 135 +#define EIC7700_RESET_TIMER 136 +#define EIC7700_RESET_SSI0 137 +#define EIC7700_RESET_SSI1 138 +#define EIC7700_RESET_WDT0 139 +#define EIC7700_RESET_WDT1 140 +#define EIC7700_RESET_WDT2 141 +#define EIC7700_RESET_WDT3 142 +#define EIC7700_RESET_LSP_CFG 143 +#define EIC7700_RESET_U84_CORE0 144 +#define EIC7700_RESET_U84_CORE1 145 +#define EIC7700_RESET_U84_CORE2 146 +#define EIC7700_RESET_U84_CORE3 147 +#define EIC7700_RESET_U84_BUS 148 +#define EIC7700_RESET_U84_DBG 149 +#define EIC7700_RESET_U84_TRACECOM 150 +#define EIC7700_RESET_U84_TRACE0 151 +#define EIC7700_RESET_U84_TRACE1 152 +#define EIC7700_RESET_U84_TRACE2 153 +#define EIC7700_RESET_U84_TRACE3 154 +#define EIC7700_RESET_SCPU_CORE 155 +#define EIC7700_RESET_SCPU_BUS 156 +#define EIC7700_RESET_SCPU_DBG 157 +#define EIC7700_RESET_LPCPU_CORE 158 +#define EIC7700_RESET_LPCPU_BUS 159 +#define EIC7700_RESET_LPCPU_DBG 160 +#define EIC7700_RESET_VC_CFG 161 +#define EIC7700_RESET_VC_AXI 162 +#define EIC7700_RESET_VC_MONCFG 163 +#define EIC7700_RESET_JD_CFG 164 +#define EIC7700_RESET_JD_AXI 165 +#define EIC7700_RESET_JE_CFG 166 +#define EIC7700_RESET_JE_AXI 167 +#define EIC7700_RESET_VD_CFG 168 +#define EIC7700_RESET_VD_AXI 169 +#define EIC7700_RESET_VE_AXI 170 +#define EIC7700_RESET_VE_CFG 171 +#define EIC7700_RESET_G2D_CORE 172 +#define EIC7700_RESET_G2D_CFG 173 +#define EIC7700_RESET_G2D_AXI 174 +#define EIC7700_RESET_VI_AXI 175 +#define EIC7700_RESET_VI_CFG 176 +#define EIC7700_RESET_VI_DWE 177 +#define EIC7700_RESET_DVP 178 +#define EIC7700_RESET_ISP0 179 +#define EIC7700_RESET_ISP1 180 +#define EIC7700_RESET_SHUTTR0 181 +#define EIC7700_RESET_SHUTTR1 182 +#define EIC7700_RESET_SHUTTR2 183 +#define EIC7700_RESET_SHUTTR3 184 +#define EIC7700_RESET_SHUTTR4 185 +#define EIC7700_RESET_SHUTTR5 186 +#define EIC7700_RESET_VO_MIPI 187 +#define EIC7700_RESET_VO_PRST 188 +#define EIC7700_RESET_VO_HDMI_PRST 189 +#define EIC7700_RESET_VO_HDMI_PHY 190 +#define EIC7700_RESET_VO_HDMI 191 +#define EIC7700_RESET_VO_I2S 192 +#define EIC7700_RESET_VO_I2S_PRST 193 +#define EIC7700_RESET_VO_AXI 194 +#define EIC7700_RESET_VO_CFG 195 +#define EIC7700_RESET_VO_DC 196 +#define EIC7700_RESET_VO_DC_PRST 197 +#define EIC7700_RESET_BOOTSPI_HRST 198 +#define EIC7700_RESET_BOOTSPI 199 +#define EIC7700_RESET_ANO1 200 +#define EIC7700_RESET_ANO0 201 +#define EIC7700_RESET_DMA1_ARST 202 +#define EIC7700_RESET_DMA1_HRST 203 +#define EIC7700_RESET_FPRT 204 +#define EIC7700_RESET_HBLOCK 205 +#define EIC7700_RESET_SECSR 206 +#define EIC7700_RESET_OTP 207 +#define EIC7700_RESET_PKA 208 +#define EIC7700_RESET_SPACC 209 +#define EIC7700_RESET_TRNG 210 +#define EIC7700_RESET_TIMER0_0 211 +#define EIC7700_RESET_TIMER0_1 212 +#define EIC7700_RESET_TIMER0_2 213 +#define EIC7700_RESET_TIMER0_3 214 +#define EIC7700_RESET_TIMER0_4 215 +#define EIC7700_RESET_TIMER0_5 216 +#define EIC7700_RESET_TIMER0_6 217 +#define EIC7700_RESET_TIMER0_7 218 +#define EIC7700_RESET_TIMER0_N 219 +#define EIC7700_RESET_TIMER1_0 220 +#define EIC7700_RESET_TIMER1_1 221 +#define EIC7700_RESET_TIMER1_2 222 +#define EIC7700_RESET_TIMER1_3 223 +#define EIC7700_RESET_TIMER1_4 224 +#define EIC7700_RESET_TIMER1_5 225 +#define EIC7700_RESET_TIMER1_6 226 +#define EIC7700_RESET_TIMER1_7 227 +#define EIC7700_RESET_TIMER1_N 228 +#define EIC7700_RESET_TIMER2_0 229 +#define EIC7700_RESET_TIMER2_1 230 +#define EIC7700_RESET_TIMER2_2 231 +#define EIC7700_RESET_TIMER2_3 232 +#define EIC7700_RESET_TIMER2_4 233 +#define EIC7700_RESET_TIMER2_5 234 +#define EIC7700_RESET_TIMER2_6 235 +#define EIC7700_RESET_TIMER2_7 236 +#define EIC7700_RESET_TIMER2_N 237 +#define EIC7700_RESET_TIMER3_0 238 +#define EIC7700_RESET_TIMER3_1 239 +#define EIC7700_RESET_TIMER3_2 240 +#define EIC7700_RESET_TIMER3_3 241 +#define EIC7700_RESET_TIMER3_4 242 +#define EIC7700_RESET_TIMER3_5 243 +#define EIC7700_RESET_TIMER3_6 244 +#define EIC7700_RESET_TIMER3_7 245 +#define EIC7700_RESET_TIMER3_N 246 +#define EIC7700_RESET_RTC 247 +#define EIC7700_RESET_MNOC_SNOC_NSP 248 +#define EIC7700_RESET_MNOC_VC 249 +#define EIC7700_RESET_MNOC_CFG 250 +#define EIC7700_RESET_MNOC_HSP 251 +#define EIC7700_RESET_MNOC_GPU 252 +#define EIC7700_RESET_MNOC_DDRC1_P3 253 +#define EIC7700_RESET_MNOC_DDRC0_P3 254 +#define EIC7700_RESET_RNOC_VO 255 +#define EIC7700_RESET_RNOC_VI 256 +#define EIC7700_RESET_RNOC_SNOC_NSP 257 +#define EIC7700_RESET_RNOC_CFG 258 +#define EIC7700_RESET_MNOC_DDRC1_P4 259 +#define EIC7700_RESET_MNOC_DDRC0_P4 260 +#define EIC7700_RESET_CNOC_VO_CFG 261 +#define EIC7700_RESET_CNOC_VI_CFG 262 +#define EIC7700_RESET_CNOC_VC_CFG 263 +#define EIC7700_RESET_CNOC_TCU_CFG 264 +#define EIC7700_RESET_CNOC_PCIE_CFG 265 +#define EIC7700_RESET_CNOC_NPU_CFG 266 +#define EIC7700_RESET_CNOC_LSP_CFG 267 +#define EIC7700_RESET_CNOC_HSP_CFG 268 +#define EIC7700_RESET_CNOC_GPU_CFG 269 +#define EIC7700_RESET_CNOC_DSPT_CFG 270 +#define EIC7700_RESET_CNOC_DDRT1_CFG 271 +#define EIC7700_RESET_CNOC_DDRT0_CFG 272 +#define EIC7700_RESET_CNOC_D2D_CFG 273 +#define EIC7700_RESET_CNOC_CFG 274 +#define EIC7700_RESET_CNOC_CLMM_CFG 275 +#define EIC7700_RESET_CNOC_AON_CFG 276 +#define EIC7700_RESET_LNOC_CFG 277 +#define EIC7700_RESET_LNOC_NPU_LLC 278 +#define EIC7700_RESET_LNOC_DDRC1_P0 279 +#define EIC7700_RESET_LNOC_DDRC0_P0 280 + +#endif /* __DT_ESWIN_EIC7700_RESET_H__ */ From 0884bd97c08cfad9c23166ddee953498cf535284 Mon Sep 17 00:00:00 2001 From: Xuyang Dong Date: Tue, 30 Sep 2025 17:32:38 +0800 Subject: [PATCH 101/114] reset: eswin: Add eic7700 reset driver Add support for reset controller in eic7700 series chips. Provide functionality for asserting and deasserting resets on the chip. Signed-off-by: Yifeng Huang Signed-off-by: Xuyang Dong Reviewed-by: Philipp Zabel Signed-off-by: Philipp Zabel --- drivers/reset/Kconfig | 10 + drivers/reset/Makefile | 1 + drivers/reset/reset-eic7700.c | 429 ++++++++++++++++++++++++++++++++++ 3 files changed, 440 insertions(+) create mode 100644 drivers/reset/reset-eic7700.c diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig index 59245cd0c393..3fec827056fe 100644 --- a/drivers/reset/Kconfig +++ b/drivers/reset/Kconfig @@ -73,6 +73,16 @@ config RESET_BRCMSTB_RESCAL This enables the RESCAL reset controller for SATA, PCIe0, or PCIe1 on BCM7216 or the BCM2712. +config RESET_EIC7700 + bool "Reset controller driver for ESWIN SoCs" + depends on ARCH_ESWIN || COMPILE_TEST + default ARCH_ESWIN + help + This enables the reset controller driver for ESWIN SoCs. This driver is + specific to ESWIN SoCs and should only be enabled if using such hardware. + The driver supports eic7700 series chips and provides functionality for + asserting and deasserting resets on the chip. + config RESET_EYEQ bool "Mobileye EyeQ reset controller" depends on MACH_EYEQ5 || MACH_EYEQ6H || COMPILE_TEST diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile index f7934f9fb90b..9c3e484dfd81 100644 --- a/drivers/reset/Makefile +++ b/drivers/reset/Makefile @@ -13,6 +13,7 @@ obj-$(CONFIG_RESET_BCM6345) += reset-bcm6345.o obj-$(CONFIG_RESET_BERLIN) += reset-berlin.o obj-$(CONFIG_RESET_BRCMSTB) += reset-brcmstb.o obj-$(CONFIG_RESET_BRCMSTB_RESCAL) += reset-brcmstb-rescal.o +obj-$(CONFIG_RESET_EIC7700) += reset-eic7700.o obj-$(CONFIG_RESET_EYEQ) += reset-eyeq.o obj-$(CONFIG_RESET_GPIO) += reset-gpio.o obj-$(CONFIG_RESET_HSDK) += reset-hsdk.o diff --git a/drivers/reset/reset-eic7700.c b/drivers/reset/reset-eic7700.c new file mode 100644 index 000000000000..b72283b18b08 --- /dev/null +++ b/drivers/reset/reset-eic7700.c @@ -0,0 +1,429 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright 2025, Beijing ESWIN Computing Technology Co., Ltd.. + * All rights reserved. + * + * ESWIN Reset Driver + * + * Authors: + * Yifeng Huang + * Xuyang Dong + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#define SYSCRG_CLEAR_BOOT_INFO_OFFSET 0xC +#define CLEAR_BOOT_FLAG_BIT BIT(0) +#define SYSCRG_RESET_OFFSET 0x100 + +/** + * struct eic7700_reset_data - reset controller information structure + * @rcdev: reset controller entity + * @regmap: regmap handle containing the memory-mapped reset registers + */ +struct eic7700_reset_data { + struct reset_controller_dev rcdev; + struct regmap *regmap; +}; + +static const struct regmap_config eic7700_regmap_config = { + .reg_bits = 32, + .val_bits = 32, + .reg_stride = 4, + .max_register = 0x1fc, +}; + +struct eic7700_reg { + u32 reg; + u32 bit; +}; + +static inline struct eic7700_reset_data * +to_eic7700_reset_data(struct reset_controller_dev *rcdev) +{ + return container_of(rcdev, struct eic7700_reset_data, rcdev); +} + +#define EIC7700_RESET(id, reg, bit)[id] = \ + { SYSCRG_RESET_OFFSET + (reg) * sizeof(u32), BIT(bit) } + +/* mapping table for reset ID to register offset and reset bit */ +static const struct eic7700_reg eic7700_reset[] = { + EIC7700_RESET(EIC7700_RESET_NOC_NSP, 0, 0), + EIC7700_RESET(EIC7700_RESET_NOC_CFG, 0, 1), + EIC7700_RESET(EIC7700_RESET_RNOC_NSP, 0, 2), + EIC7700_RESET(EIC7700_RESET_SNOC_TCU, 0, 3), + EIC7700_RESET(EIC7700_RESET_SNOC_U84, 0, 4), + EIC7700_RESET(EIC7700_RESET_SNOC_PCIE_XSR, 0, 5), + EIC7700_RESET(EIC7700_RESET_SNOC_PCIE_XMR, 0, 6), + EIC7700_RESET(EIC7700_RESET_SNOC_PCIE_PR, 0, 7), + EIC7700_RESET(EIC7700_RESET_SNOC_NPU, 0, 8), + EIC7700_RESET(EIC7700_RESET_SNOC_JTAG, 0, 9), + EIC7700_RESET(EIC7700_RESET_SNOC_DSP, 0, 10), + EIC7700_RESET(EIC7700_RESET_SNOC_DDRC1_P2, 0, 11), + EIC7700_RESET(EIC7700_RESET_SNOC_DDRC1_P1, 0, 12), + EIC7700_RESET(EIC7700_RESET_SNOC_DDRC0_P2, 0, 13), + EIC7700_RESET(EIC7700_RESET_SNOC_DDRC0_P1, 0, 14), + EIC7700_RESET(EIC7700_RESET_SNOC_D2D, 0, 15), + EIC7700_RESET(EIC7700_RESET_SNOC_AON, 0, 16), + EIC7700_RESET(EIC7700_RESET_GPU_AXI, 1, 0), + EIC7700_RESET(EIC7700_RESET_GPU_CFG, 1, 1), + EIC7700_RESET(EIC7700_RESET_GPU_GRAY, 1, 2), + EIC7700_RESET(EIC7700_RESET_GPU_JONES, 1, 3), + EIC7700_RESET(EIC7700_RESET_GPU_SPU, 1, 4), + EIC7700_RESET(EIC7700_RESET_DSP_AXI, 2, 0), + EIC7700_RESET(EIC7700_RESET_DSP_CFG, 2, 1), + EIC7700_RESET(EIC7700_RESET_DSP_DIV4, 2, 2), + EIC7700_RESET(EIC7700_RESET_DSP_DIV0, 2, 4), + EIC7700_RESET(EIC7700_RESET_DSP_DIV1, 2, 5), + EIC7700_RESET(EIC7700_RESET_DSP_DIV2, 2, 6), + EIC7700_RESET(EIC7700_RESET_DSP_DIV3, 2, 7), + EIC7700_RESET(EIC7700_RESET_D2D_AXI, 3, 0), + EIC7700_RESET(EIC7700_RESET_D2D_CFG, 3, 1), + EIC7700_RESET(EIC7700_RESET_D2D_PRST, 3, 2), + EIC7700_RESET(EIC7700_RESET_D2D_RAW_PCS, 3, 4), + EIC7700_RESET(EIC7700_RESET_D2D_RX, 3, 5), + EIC7700_RESET(EIC7700_RESET_D2D_TX, 3, 6), + EIC7700_RESET(EIC7700_RESET_D2D_CORE, 3, 7), + EIC7700_RESET(EIC7700_RESET_DDR1_ARST, 4, 0), + EIC7700_RESET(EIC7700_RESET_DDR1_TRACE, 4, 6), + EIC7700_RESET(EIC7700_RESET_DDR0_ARST, 4, 16), + EIC7700_RESET(EIC7700_RESET_DDR_CFG, 4, 21), + EIC7700_RESET(EIC7700_RESET_DDR0_TRACE, 4, 22), + EIC7700_RESET(EIC7700_RESET_DDR_CORE, 4, 23), + EIC7700_RESET(EIC7700_RESET_DDR_PRST, 4, 26), + EIC7700_RESET(EIC7700_RESET_TCU_AXI, 5, 0), + EIC7700_RESET(EIC7700_RESET_TCU_CFG, 5, 1), + EIC7700_RESET(EIC7700_RESET_TCU_TBU0, 5, 4), + EIC7700_RESET(EIC7700_RESET_TCU_TBU1, 5, 5), + EIC7700_RESET(EIC7700_RESET_TCU_TBU2, 5, 6), + EIC7700_RESET(EIC7700_RESET_TCU_TBU3, 5, 7), + EIC7700_RESET(EIC7700_RESET_TCU_TBU4, 5, 8), + EIC7700_RESET(EIC7700_RESET_TCU_TBU5, 5, 9), + EIC7700_RESET(EIC7700_RESET_TCU_TBU6, 5, 10), + EIC7700_RESET(EIC7700_RESET_TCU_TBU7, 5, 11), + EIC7700_RESET(EIC7700_RESET_TCU_TBU8, 5, 12), + EIC7700_RESET(EIC7700_RESET_TCU_TBU9, 5, 13), + EIC7700_RESET(EIC7700_RESET_TCU_TBU10, 5, 14), + EIC7700_RESET(EIC7700_RESET_TCU_TBU11, 5, 15), + EIC7700_RESET(EIC7700_RESET_TCU_TBU12, 5, 16), + EIC7700_RESET(EIC7700_RESET_TCU_TBU13, 5, 17), + EIC7700_RESET(EIC7700_RESET_TCU_TBU14, 5, 18), + EIC7700_RESET(EIC7700_RESET_TCU_TBU15, 5, 19), + EIC7700_RESET(EIC7700_RESET_TCU_TBU16, 5, 20), + EIC7700_RESET(EIC7700_RESET_NPU_AXI, 6, 0), + EIC7700_RESET(EIC7700_RESET_NPU_CFG, 6, 1), + EIC7700_RESET(EIC7700_RESET_NPU_CORE, 6, 2), + EIC7700_RESET(EIC7700_RESET_NPU_E31CORE, 6, 3), + EIC7700_RESET(EIC7700_RESET_NPU_E31BUS, 6, 4), + EIC7700_RESET(EIC7700_RESET_NPU_E31DBG, 6, 5), + EIC7700_RESET(EIC7700_RESET_NPU_LLC, 6, 6), + EIC7700_RESET(EIC7700_RESET_HSP_AXI, 7, 0), + EIC7700_RESET(EIC7700_RESET_HSP_CFG, 7, 1), + EIC7700_RESET(EIC7700_RESET_HSP_POR, 7, 2), + EIC7700_RESET(EIC7700_RESET_MSHC0_PHY, 7, 3), + EIC7700_RESET(EIC7700_RESET_MSHC1_PHY, 7, 4), + EIC7700_RESET(EIC7700_RESET_MSHC2_PHY, 7, 5), + EIC7700_RESET(EIC7700_RESET_MSHC0_TXRX, 7, 6), + EIC7700_RESET(EIC7700_RESET_MSHC1_TXRX, 7, 7), + EIC7700_RESET(EIC7700_RESET_MSHC2_TXRX, 7, 8), + EIC7700_RESET(EIC7700_RESET_SATA_ASIC0, 7, 9), + EIC7700_RESET(EIC7700_RESET_SATA_OOB, 7, 10), + EIC7700_RESET(EIC7700_RESET_SATA_PMALIVE, 7, 11), + EIC7700_RESET(EIC7700_RESET_SATA_RBC, 7, 12), + EIC7700_RESET(EIC7700_RESET_DMA0, 7, 13), + EIC7700_RESET(EIC7700_RESET_HSP_DMA, 7, 14), + EIC7700_RESET(EIC7700_RESET_USB0_VAUX, 7, 15), + EIC7700_RESET(EIC7700_RESET_USB1_VAUX, 7, 16), + EIC7700_RESET(EIC7700_RESET_HSP_SD1_PRST, 7, 17), + EIC7700_RESET(EIC7700_RESET_HSP_SD0_PRST, 7, 18), + EIC7700_RESET(EIC7700_RESET_HSP_EMMC_PRST, 7, 19), + EIC7700_RESET(EIC7700_RESET_HSP_DMA_PRST, 7, 20), + EIC7700_RESET(EIC7700_RESET_HSP_SD1_ARST, 7, 21), + EIC7700_RESET(EIC7700_RESET_HSP_SD0_ARST, 7, 22), + EIC7700_RESET(EIC7700_RESET_HSP_EMMC_ARST, 7, 23), + EIC7700_RESET(EIC7700_RESET_HSP_DMA_ARST, 7, 24), + EIC7700_RESET(EIC7700_RESET_HSP_ETH1_ARST, 7, 25), + EIC7700_RESET(EIC7700_RESET_HSP_ETH0_ARST, 7, 26), + EIC7700_RESET(EIC7700_RESET_SATA_ARST, 7, 27), + EIC7700_RESET(EIC7700_RESET_PCIE_CFG, 8, 0), + EIC7700_RESET(EIC7700_RESET_PCIE_POWEUP, 8, 1), + EIC7700_RESET(EIC7700_RESET_PCIE_PERST, 8, 2), + EIC7700_RESET(EIC7700_RESET_I2C0, 9, 0), + EIC7700_RESET(EIC7700_RESET_I2C1, 9, 1), + EIC7700_RESET(EIC7700_RESET_I2C2, 9, 2), + EIC7700_RESET(EIC7700_RESET_I2C3, 9, 3), + EIC7700_RESET(EIC7700_RESET_I2C4, 9, 4), + EIC7700_RESET(EIC7700_RESET_I2C5, 9, 5), + EIC7700_RESET(EIC7700_RESET_I2C6, 9, 6), + EIC7700_RESET(EIC7700_RESET_I2C7, 9, 7), + EIC7700_RESET(EIC7700_RESET_I2C8, 9, 8), + EIC7700_RESET(EIC7700_RESET_I2C9, 9, 9), + EIC7700_RESET(EIC7700_RESET_FAN, 10, 0), + EIC7700_RESET(EIC7700_RESET_PVT0, 11, 0), + EIC7700_RESET(EIC7700_RESET_PVT1, 11, 1), + EIC7700_RESET(EIC7700_RESET_MBOX0, 12, 0), + EIC7700_RESET(EIC7700_RESET_MBOX1, 12, 1), + EIC7700_RESET(EIC7700_RESET_MBOX2, 12, 2), + EIC7700_RESET(EIC7700_RESET_MBOX3, 12, 3), + EIC7700_RESET(EIC7700_RESET_MBOX4, 12, 4), + EIC7700_RESET(EIC7700_RESET_MBOX5, 12, 5), + EIC7700_RESET(EIC7700_RESET_MBOX6, 12, 6), + EIC7700_RESET(EIC7700_RESET_MBOX7, 12, 7), + EIC7700_RESET(EIC7700_RESET_MBOX8, 12, 8), + EIC7700_RESET(EIC7700_RESET_MBOX9, 12, 9), + EIC7700_RESET(EIC7700_RESET_MBOX10, 12, 10), + EIC7700_RESET(EIC7700_RESET_MBOX11, 12, 11), + EIC7700_RESET(EIC7700_RESET_MBOX12, 12, 12), + EIC7700_RESET(EIC7700_RESET_MBOX13, 12, 13), + EIC7700_RESET(EIC7700_RESET_MBOX14, 12, 14), + EIC7700_RESET(EIC7700_RESET_MBOX15, 12, 15), + EIC7700_RESET(EIC7700_RESET_UART0, 13, 0), + EIC7700_RESET(EIC7700_RESET_UART1, 13, 1), + EIC7700_RESET(EIC7700_RESET_UART2, 13, 2), + EIC7700_RESET(EIC7700_RESET_UART3, 13, 3), + EIC7700_RESET(EIC7700_RESET_UART4, 13, 4), + EIC7700_RESET(EIC7700_RESET_GPIO0, 14, 0), + EIC7700_RESET(EIC7700_RESET_GPIO1, 14, 1), + EIC7700_RESET(EIC7700_RESET_TIMER, 15, 0), + EIC7700_RESET(EIC7700_RESET_SSI0, 16, 0), + EIC7700_RESET(EIC7700_RESET_SSI1, 16, 1), + EIC7700_RESET(EIC7700_RESET_WDT0, 17, 0), + EIC7700_RESET(EIC7700_RESET_WDT1, 17, 1), + EIC7700_RESET(EIC7700_RESET_WDT2, 17, 2), + EIC7700_RESET(EIC7700_RESET_WDT3, 17, 3), + EIC7700_RESET(EIC7700_RESET_LSP_CFG, 18, 0), + EIC7700_RESET(EIC7700_RESET_U84_CORE0, 19, 0), + EIC7700_RESET(EIC7700_RESET_U84_CORE1, 19, 1), + EIC7700_RESET(EIC7700_RESET_U84_CORE2, 19, 2), + EIC7700_RESET(EIC7700_RESET_U84_CORE3, 19, 3), + EIC7700_RESET(EIC7700_RESET_U84_BUS, 19, 4), + EIC7700_RESET(EIC7700_RESET_U84_DBG, 19, 5), + EIC7700_RESET(EIC7700_RESET_U84_TRACECOM, 19, 6), + EIC7700_RESET(EIC7700_RESET_U84_TRACE0, 19, 8), + EIC7700_RESET(EIC7700_RESET_U84_TRACE1, 19, 9), + EIC7700_RESET(EIC7700_RESET_U84_TRACE2, 19, 10), + EIC7700_RESET(EIC7700_RESET_U84_TRACE3, 19, 11), + EIC7700_RESET(EIC7700_RESET_SCPU_CORE, 20, 0), + EIC7700_RESET(EIC7700_RESET_SCPU_BUS, 20, 1), + EIC7700_RESET(EIC7700_RESET_SCPU_DBG, 20, 2), + EIC7700_RESET(EIC7700_RESET_LPCPU_CORE, 21, 0), + EIC7700_RESET(EIC7700_RESET_LPCPU_BUS, 21, 1), + EIC7700_RESET(EIC7700_RESET_LPCPU_DBG, 21, 2), + EIC7700_RESET(EIC7700_RESET_VC_CFG, 22, 0), + EIC7700_RESET(EIC7700_RESET_VC_AXI, 22, 1), + EIC7700_RESET(EIC7700_RESET_VC_MONCFG, 22, 2), + EIC7700_RESET(EIC7700_RESET_JD_CFG, 23, 0), + EIC7700_RESET(EIC7700_RESET_JD_AXI, 23, 1), + EIC7700_RESET(EIC7700_RESET_JE_CFG, 24, 0), + EIC7700_RESET(EIC7700_RESET_JE_AXI, 24, 1), + EIC7700_RESET(EIC7700_RESET_VD_CFG, 25, 0), + EIC7700_RESET(EIC7700_RESET_VD_AXI, 25, 1), + EIC7700_RESET(EIC7700_RESET_VE_AXI, 26, 0), + EIC7700_RESET(EIC7700_RESET_VE_CFG, 26, 1), + EIC7700_RESET(EIC7700_RESET_G2D_CORE, 27, 0), + EIC7700_RESET(EIC7700_RESET_G2D_CFG, 27, 1), + EIC7700_RESET(EIC7700_RESET_G2D_AXI, 27, 2), + EIC7700_RESET(EIC7700_RESET_VI_AXI, 28, 0), + EIC7700_RESET(EIC7700_RESET_VI_CFG, 28, 1), + EIC7700_RESET(EIC7700_RESET_VI_DWE, 28, 2), + EIC7700_RESET(EIC7700_RESET_DVP, 29, 0), + EIC7700_RESET(EIC7700_RESET_ISP0, 30, 0), + EIC7700_RESET(EIC7700_RESET_ISP1, 31, 0), + EIC7700_RESET(EIC7700_RESET_SHUTTR0, 32, 0), + EIC7700_RESET(EIC7700_RESET_SHUTTR1, 32, 1), + EIC7700_RESET(EIC7700_RESET_SHUTTR2, 32, 2), + EIC7700_RESET(EIC7700_RESET_SHUTTR3, 32, 3), + EIC7700_RESET(EIC7700_RESET_SHUTTR4, 32, 4), + EIC7700_RESET(EIC7700_RESET_SHUTTR5, 32, 5), + EIC7700_RESET(EIC7700_RESET_VO_MIPI, 33, 0), + EIC7700_RESET(EIC7700_RESET_VO_PRST, 33, 1), + EIC7700_RESET(EIC7700_RESET_VO_HDMI_PRST, 33, 3), + EIC7700_RESET(EIC7700_RESET_VO_HDMI_PHY, 33, 4), + EIC7700_RESET(EIC7700_RESET_VO_HDMI, 33, 5), + EIC7700_RESET(EIC7700_RESET_VO_I2S, 34, 0), + EIC7700_RESET(EIC7700_RESET_VO_I2S_PRST, 34, 1), + EIC7700_RESET(EIC7700_RESET_VO_AXI, 35, 0), + EIC7700_RESET(EIC7700_RESET_VO_CFG, 35, 1), + EIC7700_RESET(EIC7700_RESET_VO_DC, 35, 2), + EIC7700_RESET(EIC7700_RESET_VO_DC_PRST, 35, 3), + EIC7700_RESET(EIC7700_RESET_BOOTSPI_HRST, 36, 0), + EIC7700_RESET(EIC7700_RESET_BOOTSPI, 36, 1), + EIC7700_RESET(EIC7700_RESET_ANO1, 37, 0), + EIC7700_RESET(EIC7700_RESET_ANO0, 38, 0), + EIC7700_RESET(EIC7700_RESET_DMA1_ARST, 39, 0), + EIC7700_RESET(EIC7700_RESET_DMA1_HRST, 39, 1), + EIC7700_RESET(EIC7700_RESET_FPRT, 40, 0), + EIC7700_RESET(EIC7700_RESET_HBLOCK, 41, 0), + EIC7700_RESET(EIC7700_RESET_SECSR, 42, 0), + EIC7700_RESET(EIC7700_RESET_OTP, 43, 0), + EIC7700_RESET(EIC7700_RESET_PKA, 44, 0), + EIC7700_RESET(EIC7700_RESET_SPACC, 45, 0), + EIC7700_RESET(EIC7700_RESET_TRNG, 46, 0), + EIC7700_RESET(EIC7700_RESET_TIMER0_0, 48, 0), + EIC7700_RESET(EIC7700_RESET_TIMER0_1, 48, 1), + EIC7700_RESET(EIC7700_RESET_TIMER0_2, 48, 2), + EIC7700_RESET(EIC7700_RESET_TIMER0_3, 48, 3), + EIC7700_RESET(EIC7700_RESET_TIMER0_4, 48, 4), + EIC7700_RESET(EIC7700_RESET_TIMER0_5, 48, 5), + EIC7700_RESET(EIC7700_RESET_TIMER0_6, 48, 6), + EIC7700_RESET(EIC7700_RESET_TIMER0_7, 48, 7), + EIC7700_RESET(EIC7700_RESET_TIMER0_N, 48, 8), + EIC7700_RESET(EIC7700_RESET_TIMER1_0, 49, 0), + EIC7700_RESET(EIC7700_RESET_TIMER1_1, 49, 1), + EIC7700_RESET(EIC7700_RESET_TIMER1_2, 49, 2), + EIC7700_RESET(EIC7700_RESET_TIMER1_3, 49, 3), + EIC7700_RESET(EIC7700_RESET_TIMER1_4, 49, 4), + EIC7700_RESET(EIC7700_RESET_TIMER1_5, 49, 5), + EIC7700_RESET(EIC7700_RESET_TIMER1_6, 49, 6), + EIC7700_RESET(EIC7700_RESET_TIMER1_7, 49, 7), + EIC7700_RESET(EIC7700_RESET_TIMER1_N, 49, 8), + EIC7700_RESET(EIC7700_RESET_TIMER2_0, 50, 0), + EIC7700_RESET(EIC7700_RESET_TIMER2_1, 50, 1), + EIC7700_RESET(EIC7700_RESET_TIMER2_2, 50, 2), + EIC7700_RESET(EIC7700_RESET_TIMER2_3, 50, 3), + EIC7700_RESET(EIC7700_RESET_TIMER2_4, 50, 4), + EIC7700_RESET(EIC7700_RESET_TIMER2_5, 50, 5), + EIC7700_RESET(EIC7700_RESET_TIMER2_6, 50, 6), + EIC7700_RESET(EIC7700_RESET_TIMER2_7, 50, 7), + EIC7700_RESET(EIC7700_RESET_TIMER2_N, 50, 8), + EIC7700_RESET(EIC7700_RESET_TIMER3_0, 51, 0), + EIC7700_RESET(EIC7700_RESET_TIMER3_1, 51, 1), + EIC7700_RESET(EIC7700_RESET_TIMER3_2, 51, 2), + EIC7700_RESET(EIC7700_RESET_TIMER3_3, 51, 3), + EIC7700_RESET(EIC7700_RESET_TIMER3_4, 51, 4), + EIC7700_RESET(EIC7700_RESET_TIMER3_5, 51, 5), + EIC7700_RESET(EIC7700_RESET_TIMER3_6, 51, 6), + EIC7700_RESET(EIC7700_RESET_TIMER3_7, 51, 7), + EIC7700_RESET(EIC7700_RESET_TIMER3_N, 51, 8), + EIC7700_RESET(EIC7700_RESET_RTC, 52, 0), + EIC7700_RESET(EIC7700_RESET_MNOC_SNOC_NSP, 53, 0), + EIC7700_RESET(EIC7700_RESET_MNOC_VC, 53, 1), + EIC7700_RESET(EIC7700_RESET_MNOC_CFG, 53, 2), + EIC7700_RESET(EIC7700_RESET_MNOC_HSP, 53, 3), + EIC7700_RESET(EIC7700_RESET_MNOC_GPU, 53, 4), + EIC7700_RESET(EIC7700_RESET_MNOC_DDRC1_P3, 53, 5), + EIC7700_RESET(EIC7700_RESET_MNOC_DDRC0_P3, 53, 6), + EIC7700_RESET(EIC7700_RESET_RNOC_VO, 54, 0), + EIC7700_RESET(EIC7700_RESET_RNOC_VI, 54, 1), + EIC7700_RESET(EIC7700_RESET_RNOC_SNOC_NSP, 54, 2), + EIC7700_RESET(EIC7700_RESET_RNOC_CFG, 54, 3), + EIC7700_RESET(EIC7700_RESET_MNOC_DDRC1_P4, 54, 4), + EIC7700_RESET(EIC7700_RESET_MNOC_DDRC0_P4, 54, 5), + EIC7700_RESET(EIC7700_RESET_CNOC_VO_CFG, 55, 0), + EIC7700_RESET(EIC7700_RESET_CNOC_VI_CFG, 55, 1), + EIC7700_RESET(EIC7700_RESET_CNOC_VC_CFG, 55, 2), + EIC7700_RESET(EIC7700_RESET_CNOC_TCU_CFG, 55, 3), + EIC7700_RESET(EIC7700_RESET_CNOC_PCIE_CFG, 55, 4), + EIC7700_RESET(EIC7700_RESET_CNOC_NPU_CFG, 55, 5), + EIC7700_RESET(EIC7700_RESET_CNOC_LSP_CFG, 55, 6), + EIC7700_RESET(EIC7700_RESET_CNOC_HSP_CFG, 55, 7), + EIC7700_RESET(EIC7700_RESET_CNOC_GPU_CFG, 55, 8), + EIC7700_RESET(EIC7700_RESET_CNOC_DSPT_CFG, 55, 9), + EIC7700_RESET(EIC7700_RESET_CNOC_DDRT1_CFG, 55, 10), + EIC7700_RESET(EIC7700_RESET_CNOC_DDRT0_CFG, 55, 11), + EIC7700_RESET(EIC7700_RESET_CNOC_D2D_CFG, 55, 12), + EIC7700_RESET(EIC7700_RESET_CNOC_CFG, 55, 13), + EIC7700_RESET(EIC7700_RESET_CNOC_CLMM_CFG, 55, 14), + EIC7700_RESET(EIC7700_RESET_CNOC_AON_CFG, 55, 15), + EIC7700_RESET(EIC7700_RESET_LNOC_CFG, 56, 0), + EIC7700_RESET(EIC7700_RESET_LNOC_NPU_LLC, 56, 1), + EIC7700_RESET(EIC7700_RESET_LNOC_DDRC1_P0, 56, 2), + EIC7700_RESET(EIC7700_RESET_LNOC_DDRC0_P0, 56, 3), +}; + +static int eic7700_reset_assert(struct reset_controller_dev *rcdev, + unsigned long id) +{ + struct eic7700_reset_data *data = to_eic7700_reset_data(rcdev); + + return regmap_clear_bits(data->regmap, eic7700_reset[id].reg, + eic7700_reset[id].bit); +} + +static int eic7700_reset_deassert(struct reset_controller_dev *rcdev, + unsigned long id) +{ + struct eic7700_reset_data *data = to_eic7700_reset_data(rcdev); + + return regmap_set_bits(data->regmap, eic7700_reset[id].reg, + eic7700_reset[id].bit); +} + +static int eic7700_reset_reset(struct reset_controller_dev *rcdev, + unsigned long id) +{ + int ret; + + ret = eic7700_reset_assert(rcdev, id); + if (ret) + return ret; + + usleep_range(10, 15); + + return eic7700_reset_deassert(rcdev, id); +} + +static const struct reset_control_ops eic7700_reset_ops = { + .reset = eic7700_reset_reset, + .assert = eic7700_reset_assert, + .deassert = eic7700_reset_deassert, +}; + +static const struct of_device_id eic7700_reset_dt_ids[] = { + { .compatible = "eswin,eic7700-reset", }, + { /* sentinel */ } +}; + +static int eic7700_reset_probe(struct platform_device *pdev) +{ + struct eic7700_reset_data *data; + struct device *dev = &pdev->dev; + void __iomem *base; + + data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); + if (!data) + return -ENOMEM; + + base = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(base)) + return PTR_ERR(base); + + data->regmap = devm_regmap_init_mmio(dev, base, &eic7700_regmap_config); + if (IS_ERR(data->regmap)) + return dev_err_probe(dev, PTR_ERR(data->regmap), + "failed to get regmap!\n"); + + data->rcdev.owner = THIS_MODULE; + data->rcdev.ops = &eic7700_reset_ops; + data->rcdev.of_node = dev->of_node; + data->rcdev.of_reset_n_cells = 1; + data->rcdev.dev = dev; + data->rcdev.nr_resets = ARRAY_SIZE(eic7700_reset); + + /* clear boot flag so u84 and scpu could be reseted by software */ + regmap_set_bits(data->regmap, SYSCRG_CLEAR_BOOT_INFO_OFFSET, + CLEAR_BOOT_FLAG_BIT); + msleep(50); + + return devm_reset_controller_register(dev, &data->rcdev); +} + +static struct platform_driver eic7700_reset_driver = { + .probe = eic7700_reset_probe, + .driver = { + .name = "eic7700-reset", + .of_match_table = eic7700_reset_dt_ids, + }, +}; + +builtin_platform_driver(eic7700_reset_driver); From 20eee0f69c9034a0f613528f829dcaca192740d5 Mon Sep 17 00:00:00 2001 From: Claudiu Beznea Date: Thu, 23 Oct 2025 16:58:06 +0300 Subject: [PATCH 102/114] dt-bindings: reset: renesas,rzg2l-usbphy-ctrl: Document RZ/G3S support The Renesas USB PHY hardware block needs to have the PWRRDY bit in the system controller set before applying any other settings. The PWRRDY bit must be controlled during power-on, power-off, and system suspend/resume sequences as follows: - during power-on/resume, it must be set to zero before enabling clocks and modules - during power-off/suspend, it must be set to one after disabling clocks and modules Add the renesas,sysc-pwrrdy device tree property, which allows the reset-rzg2l-usbphy-ctrl driver to parse, map, and control the system controller PWRRDY bit at the appropriate time. Along with it add a new compatible for the RZ/G3S SoC. Reviewed-by: Rob Herring (Arm) Signed-off-by: Claudiu Beznea Signed-off-by: Philipp Zabel --- .../reset/renesas,rzg2l-usbphy-ctrl.yaml | 41 ++++++++++++++++--- 1 file changed, 35 insertions(+), 6 deletions(-) diff --git a/Documentation/devicetree/bindings/reset/renesas,rzg2l-usbphy-ctrl.yaml b/Documentation/devicetree/bindings/reset/renesas,rzg2l-usbphy-ctrl.yaml index b0b20af15313..c83469a1b379 100644 --- a/Documentation/devicetree/bindings/reset/renesas,rzg2l-usbphy-ctrl.yaml +++ b/Documentation/devicetree/bindings/reset/renesas,rzg2l-usbphy-ctrl.yaml @@ -15,12 +15,14 @@ description: properties: compatible: - items: - - enum: - - renesas,r9a07g043-usbphy-ctrl # RZ/G2UL and RZ/Five - - renesas,r9a07g044-usbphy-ctrl # RZ/G2{L,LC} - - renesas,r9a07g054-usbphy-ctrl # RZ/V2L - - const: renesas,rzg2l-usbphy-ctrl + oneOf: + - items: + - enum: + - renesas,r9a07g043-usbphy-ctrl # RZ/G2UL and RZ/Five + - renesas,r9a07g044-usbphy-ctrl # RZ/G2{L,LC} + - renesas,r9a07g054-usbphy-ctrl # RZ/V2L + - const: renesas,rzg2l-usbphy-ctrl + - const: renesas,r9a08g045-usbphy-ctrl # RZ/G3S reg: maxItems: 1 @@ -48,6 +50,20 @@ properties: $ref: /schemas/regulator/regulator.yaml# unevaluatedProperties: false + renesas,sysc-pwrrdy: + description: + The system controller PWRRDY indicates to the USB PHY if the power supply + is ready. PWRRDY needs to be set during power-on before applying any + other settings. It also needs to be set before powering off the USB. + $ref: /schemas/types.yaml#/definitions/phandle-array + items: + - items: + - description: + System controller phandle required by USB PHY CTRL driver to set + PWRRDY + - description: Register offset associated with PWRRDY + - description: Register bitmask associated with PWRRDY + required: - compatible - reg @@ -57,6 +73,19 @@ required: - '#reset-cells' - regulator-vbus +allOf: + - if: + properties: + compatible: + contains: + const: renesas,r9a08g045-usbphy-ctrl + then: + required: + - renesas,sysc-pwrrdy + else: + properties: + renesas,sysc-pwrrdy: false + additionalProperties: false examples: From 78f2d64e484753bfede6a0e9eab0ef35830c34fb Mon Sep 17 00:00:00 2001 From: Claudiu Beznea Date: Thu, 23 Oct 2025 16:58:07 +0300 Subject: [PATCH 103/114] reset: rzg2l-usbphy-ctrl: Add support for USB PWRRDY MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On the Renesas RZ/G3S SoC, the USB PHY block has an input signal called PWRRDY. This signal is managed by the system controller and must be de-asserted after powering on the area where USB PHY resides and asserted before powering it off. On power-on/resume the USB PWRRDY signal need to be de-asserted before enabling clock and switching the module to normal state (through MSTOP support). The power-on/resume configuration sequence must be: 1/ PWRRDY=0 2/ CLK_ON=1 3/ MSTOP=0 On power-off/suspend the configuration sequence should be: 1/ MSTOP=1 2/ CLK_ON=0 3/ PWRRDY=1 The CLK_ON and MSTOP functionalities are controlled by clock drivers. The suspend/resume support will be handled by different patches. After long discussions with the internal HW team, it has been confirmed that the HW connection b/w USB PHY block, the USB channels, the system controller, clock, MSTOP, PWRRDY signal is as follows: ┌──────────────────────────────┐ │ │◄── CPG_CLKON_USB.CLK0_ON │ USB CH0 │ ┌──────────────────────────┐ │┌───────────────────────────┐ │◄── CPG_CLKON_USB.CLK2_ON │ ┌────────┐ ││host controller registers │ │ │ │ │ ││function controller registers│ │ │ PHY0 │◄──┤└───────────────────────────┘ │ │ USB PHY │ │ └────────────▲─────────────────┘ │ └────────┘ │ │ │ CPG_BUS_PERI_COM_MSTOP.MSTOP{6, 5}_ON │┌──────────────┐ ┌────────┐ ││USHPHY control│ │ │ ││ registers │ │ PHY1 │ ┌──────────────────────────────┐ │└──────────────┘ │ │◄──┤ USB CH1 │ │ └────────┘ │┌───────────────────────────┐ │◄── CPG_CLKON_USB.CLK1_ON └─▲───────▲─────────▲──────┘ ││ host controller registers │ │ │ │ │ │└───────────────────────────┘ │ │ │ │ └────────────▲─────────────────┘ │ │ │ │ │ │ │ CPG_BUS_PERI_COM_MSTOP.MSTOP7_ON │PWRRDY │ │ │ │ CPG_CLK_ON_USB.CLK3_ON │ │ │ CPG_BUS_PERI_COM_MSTOP.MSTOP4_ON │ ┌────┐ │SYSC│ └────┘ where: - CPG_CLKON_USB.CLK.CLKX_ON is the register bit controlling the clock X of different USB blocks, X in {0, 1, 2, 3} - CPG_BUS_PERI_COM_MSTOP.MSTOPX_ON is the register bit controlling the MSTOP of different USB blocks, X in {4, 5, 6, 7} - USB PHY is the USB PHY block exposing 2 ports, port0 and port1, used by the USB CH0, USB CH1 - SYSC is the system controller block controlling the PWRRDY signal - USB CHx are individual USB block with host and function capabilities (USB CH0 have both host and function capabilities, USB CH1 has only host capabilities) The USBPHY control registers are controlled though the reset-rzg2l-usbphy-ctrl driver. The USB PHY ports are controlled by phy_rcar_gen3_usb2 (drivers/phy/renesas/phy-rcar-gen3-usb2.c file). The USB PHY ports request resets from the reset-rzg2l-usbphy-ctrl driver. The connection b/w the system controller and the USB PHY CTRL driver is implemented through the renesas,sysc-pwrrdy device tree property proposed in this patch. This property specifies the register offset and the bitmask required to control the PWRRDY signal. Since the USB PHY CTRL driver needs to be probed before any other USB-specific driver on RZ/G3S, control of PWRRDY is passed exclusively to it. This guarantees the correct configuration sequence between clocks, MSTOP bits, and the PWRRDY bit on probe/resume and remove/suspend. At the same time, changes are kept minimal by avoiding modifications to the USB PHY driver to also handle the PWRRDY itself. Tested-by: Wolfram Sang Signed-off-by: Claudiu Beznea Reviewed-by: Philipp Zabel Signed-off-by: Philipp Zabel --- drivers/reset/Kconfig | 1 + drivers/reset/reset-rzg2l-usbphy-ctrl.c | 56 +++++++++++++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig index 3fec827056fe..e1ae624661f3 100644 --- a/drivers/reset/Kconfig +++ b/drivers/reset/Kconfig @@ -247,6 +247,7 @@ config RESET_RASPBERRYPI config RESET_RZG2L_USBPHY_CTRL tristate "Renesas RZ/G2L USBPHY control driver" depends on ARCH_RZG2L || COMPILE_TEST + select MFD_SYSCON help Support for USBPHY Control found on RZ/G2L family. It mainly controls reset and power down of the USB/PHY. diff --git a/drivers/reset/reset-rzg2l-usbphy-ctrl.c b/drivers/reset/reset-rzg2l-usbphy-ctrl.c index 8a7f167e405e..f7901112f38c 100644 --- a/drivers/reset/reset-rzg2l-usbphy-ctrl.c +++ b/drivers/reset/reset-rzg2l-usbphy-ctrl.c @@ -13,6 +13,7 @@ #include #include #include +#include #define RESET 0x000 #define VBENCTL 0x03c @@ -91,6 +92,8 @@ static int rzg2l_usbphy_ctrl_status(struct reset_controller_dev *rcdev, return !!(readl(priv->base + RESET) & port_mask); } +#define RZG2L_USBPHY_CTRL_PWRRDY 1 + static const struct of_device_id rzg2l_usbphy_ctrl_match_table[] = { { .compatible = "renesas,rzg2l-usbphy-ctrl" }, { /* Sentinel */ } @@ -110,6 +113,55 @@ static const struct regmap_config rzg2l_usb_regconf = { .max_register = 1, }; +static void rzg2l_usbphy_ctrl_set_pwrrdy(struct regmap_field *pwrrdy, + bool power_on) +{ + u32 val = power_on ? 0 : 1; + + /* The initialization path guarantees that the mask is 1 bit long. */ + regmap_field_update_bits(pwrrdy, 1, val); +} + +static void rzg2l_usbphy_ctrl_pwrrdy_off(void *data) +{ + rzg2l_usbphy_ctrl_set_pwrrdy(data, false); +} + +static int rzg2l_usbphy_ctrl_pwrrdy_init(struct device *dev) +{ + struct regmap_field *pwrrdy; + struct reg_field field; + struct regmap *regmap; + const int *data; + u32 args[2]; + + data = device_get_match_data(dev); + if ((uintptr_t)data != RZG2L_USBPHY_CTRL_PWRRDY) + return 0; + + regmap = syscon_regmap_lookup_by_phandle_args(dev->of_node, + "renesas,sysc-pwrrdy", + ARRAY_SIZE(args), args); + if (IS_ERR(regmap)) + return PTR_ERR(regmap); + + /* Don't allow more than one bit in mask. */ + if (hweight32(args[1]) != 1) + return -EINVAL; + + field.reg = args[0]; + field.lsb = __ffs(args[1]); + field.msb = __fls(args[1]); + + pwrrdy = devm_regmap_field_alloc(dev, regmap, field); + if (!pwrrdy) + return -ENOMEM; + + rzg2l_usbphy_ctrl_set_pwrrdy(pwrrdy, true); + + return devm_add_action_or_reset(dev, rzg2l_usbphy_ctrl_pwrrdy_off, pwrrdy); +} + static int rzg2l_usbphy_ctrl_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; @@ -132,6 +184,10 @@ static int rzg2l_usbphy_ctrl_probe(struct platform_device *pdev) if (IS_ERR(regmap)) return PTR_ERR(regmap); + error = rzg2l_usbphy_ctrl_pwrrdy_init(dev); + if (error) + return error; + priv->rstc = devm_reset_control_get_exclusive(&pdev->dev, NULL); if (IS_ERR(priv->rstc)) return dev_err_probe(dev, PTR_ERR(priv->rstc), From 819ac6b055350c559dbb111f970a96e2c1c812ff Mon Sep 17 00:00:00 2001 From: Claudiu Beznea Date: Thu, 23 Oct 2025 16:58:08 +0300 Subject: [PATCH 104/114] reset: rzg2l-usbphy-ctrl: Add support for RZ/G3S SoC The Renesas RZ/G3S SoC USB PHY HW block receives as input the USB PWRRDY signal from the system controller. Add support for the Renesas RZ/G3S SoC. Tested-by: Wolfram Sang Signed-off-by: Claudiu Beznea Reviewed-by: Philipp Zabel Signed-off-by: Philipp Zabel --- drivers/reset/reset-rzg2l-usbphy-ctrl.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/reset/reset-rzg2l-usbphy-ctrl.c b/drivers/reset/reset-rzg2l-usbphy-ctrl.c index f7901112f38c..eea56687cd0a 100644 --- a/drivers/reset/reset-rzg2l-usbphy-ctrl.c +++ b/drivers/reset/reset-rzg2l-usbphy-ctrl.c @@ -96,6 +96,10 @@ static int rzg2l_usbphy_ctrl_status(struct reset_controller_dev *rcdev, static const struct of_device_id rzg2l_usbphy_ctrl_match_table[] = { { .compatible = "renesas,rzg2l-usbphy-ctrl" }, + { + .compatible = "renesas,r9a08g045-usbphy-ctrl", + .data = (void *)RZG2L_USBPHY_CTRL_PWRRDY + }, { /* Sentinel */ } }; MODULE_DEVICE_TABLE(of, rzg2l_usbphy_ctrl_match_table); From a86aaf2b62fcf52e988fad47cdd18eb47cbd698f Mon Sep 17 00:00:00 2001 From: Bartosz Golaszewski Date: Wed, 22 Oct 2025 15:51:31 +0200 Subject: [PATCH 105/114] clk: davinci: psc: drop unused reset lookup We no longer support any non-DT DaVinci boards so there are no more users of legacy reset lookup. Signed-off-by: Bartosz Golaszewski Acked-by: Stephen Boyd Acked-by: David Lechner Signed-off-by: Philipp Zabel --- drivers/clk/davinci/psc-da850.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/drivers/clk/davinci/psc-da850.c b/drivers/clk/davinci/psc-da850.c index 5a18bca464cd..94081ab1e688 100644 --- a/drivers/clk/davinci/psc-da850.c +++ b/drivers/clk/davinci/psc-da850.c @@ -6,7 +6,6 @@ */ #include -#include #include #include #include @@ -66,14 +65,8 @@ LPSC_CLKDEV3(ecap_clkdev, "fck", "ecap.0", "fck", "ecap.1", "fck", "ecap.2"); -static struct reset_control_lookup da850_psc0_reset_lookup_table[] = { - RESET_LOOKUP("da850-psc0", 15, "davinci-rproc.0", NULL), -}; - static int da850_psc0_init(struct device *dev, void __iomem *base) { - reset_controller_add_lookup(da850_psc0_reset_lookup_table, - ARRAY_SIZE(da850_psc0_reset_lookup_table)); return davinci_psc_register_clocks(dev, da850_psc0_info, 16, base); } From 8bffbfdc01dff26f17f8b382266e71d48e63c5e9 Mon Sep 17 00:00:00 2001 From: Bartosz Golaszewski Date: Wed, 22 Oct 2025 15:51:32 +0200 Subject: [PATCH 106/114] reset: remove legacy reset lookup code There are no more users of this code. Let's remove the exported symbols and the implementation from reset core. Reviewed-by: Philipp Zabel Signed-off-by: Bartosz Golaszewski [p.zabel@pengutronix.de: folded in 8e6ec20e-8965-4b42-99fc-0462269ff2f1@paulmck-laptop] Signed-off-by: Philipp Zabel --- drivers/reset/core.c | 124 +------------------------------ include/linux/reset-controller.h | 33 -------- 2 files changed, 3 insertions(+), 154 deletions(-) diff --git a/drivers/reset/core.c b/drivers/reset/core.c index 22f67fc77ae5..20cd50804ba1 100644 --- a/drivers/reset/core.c +++ b/drivers/reset/core.c @@ -25,9 +25,6 @@ static DEFINE_MUTEX(reset_list_mutex); static LIST_HEAD(reset_controller_list); -static DEFINE_MUTEX(reset_lookup_mutex); -static LIST_HEAD(reset_lookup_list); - /* Protects reset_gpio_lookup_list */ static DEFINE_MUTEX(reset_gpio_lookup_mutex); static LIST_HEAD(reset_gpio_lookup_list); @@ -190,33 +187,6 @@ int devm_reset_controller_register(struct device *dev, } EXPORT_SYMBOL_GPL(devm_reset_controller_register); -/** - * reset_controller_add_lookup - register a set of lookup entries - * @lookup: array of reset lookup entries - * @num_entries: number of entries in the lookup array - */ -void reset_controller_add_lookup(struct reset_control_lookup *lookup, - unsigned int num_entries) -{ - struct reset_control_lookup *entry; - unsigned int i; - - mutex_lock(&reset_lookup_mutex); - for (i = 0; i < num_entries; i++) { - entry = &lookup[i]; - - if (!entry->dev_id || !entry->provider) { - pr_warn("%s(): reset lookup entry badly specified, skipping\n", - __func__); - continue; - } - - list_add_tail(&entry->list, &reset_lookup_list); - } - mutex_unlock(&reset_lookup_mutex); -} -EXPORT_SYMBOL_GPL(reset_controller_add_lookup); - static inline struct reset_control_array * rstc_to_array(struct reset_control *rstc) { return container_of(rstc, struct reset_control_array, base); @@ -1081,75 +1051,12 @@ __of_reset_control_get(struct device_node *node, const char *id, int index, } EXPORT_SYMBOL_GPL(__of_reset_control_get); -static struct reset_controller_dev * -__reset_controller_by_name(const char *name) -{ - struct reset_controller_dev *rcdev; - - lockdep_assert_held(&reset_list_mutex); - - list_for_each_entry(rcdev, &reset_controller_list, list) { - if (!rcdev->dev) - continue; - - if (!strcmp(name, dev_name(rcdev->dev))) - return rcdev; - } - - return NULL; -} - -static struct reset_control * -__reset_control_get_from_lookup(struct device *dev, const char *con_id, - enum reset_control_flags flags) -{ - bool optional = flags & RESET_CONTROL_FLAGS_BIT_OPTIONAL; - const struct reset_control_lookup *lookup; - struct reset_controller_dev *rcdev; - const char *dev_id = dev_name(dev); - struct reset_control *rstc = NULL; - - mutex_lock(&reset_lookup_mutex); - - list_for_each_entry(lookup, &reset_lookup_list, list) { - if (strcmp(lookup->dev_id, dev_id)) - continue; - - if ((!con_id && !lookup->con_id) || - ((con_id && lookup->con_id) && - !strcmp(con_id, lookup->con_id))) { - mutex_lock(&reset_list_mutex); - rcdev = __reset_controller_by_name(lookup->provider); - if (!rcdev) { - mutex_unlock(&reset_list_mutex); - mutex_unlock(&reset_lookup_mutex); - /* Reset provider may not be ready yet. */ - return ERR_PTR(-EPROBE_DEFER); - } - - flags &= ~RESET_CONTROL_FLAGS_BIT_OPTIONAL; - - rstc = __reset_control_get_internal(rcdev, - lookup->index, - flags); - mutex_unlock(&reset_list_mutex); - break; - } - } - - mutex_unlock(&reset_lookup_mutex); - - if (!rstc) - return optional ? NULL : ERR_PTR(-ENOENT); - - return rstc; -} - struct reset_control *__reset_control_get(struct device *dev, const char *id, int index, enum reset_control_flags flags) { bool shared = flags & RESET_CONTROL_FLAGS_BIT_SHARED; bool acquired = flags & RESET_CONTROL_FLAGS_BIT_ACQUIRED; + bool optional = flags & RESET_CONTROL_FLAGS_BIT_OPTIONAL; if (WARN_ON(shared && acquired)) return ERR_PTR(-EINVAL); @@ -1157,7 +1064,7 @@ struct reset_control *__reset_control_get(struct device *dev, const char *id, if (dev->of_node) return __of_reset_control_get(dev->of_node, id, index, flags); - return __reset_control_get_from_lookup(dev, id, flags); + return optional ? NULL : ERR_PTR(-ENOENT); } EXPORT_SYMBOL_GPL(__reset_control_get); @@ -1492,31 +1399,6 @@ devm_reset_control_array_get(struct device *dev, enum reset_control_flags flags) } EXPORT_SYMBOL_GPL(devm_reset_control_array_get); -static int reset_control_get_count_from_lookup(struct device *dev) -{ - const struct reset_control_lookup *lookup; - const char *dev_id; - int count = 0; - - if (!dev) - return -EINVAL; - - dev_id = dev_name(dev); - mutex_lock(&reset_lookup_mutex); - - list_for_each_entry(lookup, &reset_lookup_list, list) { - if (!strcmp(lookup->dev_id, dev_id)) - count++; - } - - mutex_unlock(&reset_lookup_mutex); - - if (count == 0) - count = -ENOENT; - - return count; -} - /** * reset_control_get_count - Count number of resets available with a device * @@ -1530,6 +1412,6 @@ int reset_control_get_count(struct device *dev) if (dev->of_node) return of_reset_control_get_count(dev->of_node); - return reset_control_get_count_from_lookup(dev); + return -ENOENT; } EXPORT_SYMBOL_GPL(reset_control_get_count); diff --git a/include/linux/reset-controller.h b/include/linux/reset-controller.h index 357df16ede32..46514cb1b9e0 100644 --- a/include/linux/reset-controller.h +++ b/include/linux/reset-controller.h @@ -26,31 +26,6 @@ struct module; struct device_node; struct of_phandle_args; -/** - * struct reset_control_lookup - represents a single lookup entry - * - * @list: internal list of all reset lookup entries - * @provider: name of the reset controller device controlling this reset line - * @index: ID of the reset controller in the reset controller device - * @dev_id: name of the device associated with this reset line - * @con_id: name of the reset line (can be NULL) - */ -struct reset_control_lookup { - struct list_head list; - const char *provider; - unsigned int index; - const char *dev_id; - const char *con_id; -}; - -#define RESET_LOOKUP(_provider, _index, _dev_id, _con_id) \ - { \ - .provider = _provider, \ - .index = _index, \ - .dev_id = _dev_id, \ - .con_id = _con_id, \ - } - /** * struct reset_controller_dev - reset controller entity that might * provide multiple reset controls @@ -90,9 +65,6 @@ void reset_controller_unregister(struct reset_controller_dev *rcdev); struct device; int devm_reset_controller_register(struct device *dev, struct reset_controller_dev *rcdev); - -void reset_controller_add_lookup(struct reset_control_lookup *lookup, - unsigned int num_entries); #else static inline int reset_controller_register(struct reset_controller_dev *rcdev) { @@ -108,11 +80,6 @@ static inline int devm_reset_controller_register(struct device *dev, { return 0; } - -static inline void reset_controller_add_lookup(struct reset_control_lookup *lookup, - unsigned int num_entries) -{ -} #endif #endif From 5334eb9de76c74e24821aae89e111e27398b5add Mon Sep 17 00:00:00 2001 From: Yao Zi Date: Tue, 14 Oct 2025 13:10:28 +0000 Subject: [PATCH 107/114] dt-bindings: reset: thead,th1520-reset: Remove non-VO-subsystem resets Registers in control of TH1520_RESET_ID_{NPU,WDT0,WDT1} belong to AP reset controller, not the VO one which is documented as "thead,th1520-reset" and is the only reset controller supported for TH1520 for now. Let's remove the IDs, leaving them to be implemented by AP-subsystem reset controller in the future. Fixes: 30e7573babdc ("dt-bindings: reset: Add T-HEAD TH1520 SoC Reset Controller") Signed-off-by: Yao Zi Acked-by: Rob Herring (Arm) Reviewed-by: Drew Fustini Acked-by: Guo Ren Signed-off-by: Philipp Zabel --- include/dt-bindings/reset/thead,th1520-reset.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/include/dt-bindings/reset/thead,th1520-reset.h b/include/dt-bindings/reset/thead,th1520-reset.h index ee799286c175..e51d6314d131 100644 --- a/include/dt-bindings/reset/thead,th1520-reset.h +++ b/include/dt-bindings/reset/thead,th1520-reset.h @@ -9,9 +9,6 @@ #define TH1520_RESET_ID_GPU 0 #define TH1520_RESET_ID_GPU_CLKGEN 1 -#define TH1520_RESET_ID_NPU 2 -#define TH1520_RESET_ID_WDT0 3 -#define TH1520_RESET_ID_WDT1 4 #define TH1520_RESET_ID_DPU_AHB 5 #define TH1520_RESET_ID_DPU_AXI 6 #define TH1520_RESET_ID_DPU_CORE 7 From a35ac6f3bdb135debc8e1ff599d0009bc64dc329 Mon Sep 17 00:00:00 2001 From: Yao Zi Date: Tue, 14 Oct 2025 13:10:29 +0000 Subject: [PATCH 108/114] dt-bindings: reset: thead,th1520-reset: Add controllers for more subsys TH1520 SoC is divided into several subsystems, most of them have distinct reset controllers. Let's document reset controllers other than the one for VO subsystem and IDs for their reset signals. Signed-off-by: Yao Zi Acked-by: Rob Herring (Arm) Reviewed-by: Drew Fustini Acked-by: Guo Ren Signed-off-by: Philipp Zabel --- .../bindings/reset/thead,th1520-reset.yaml | 8 +- .../dt-bindings/reset/thead,th1520-reset.h | 216 ++++++++++++++++++ 2 files changed, 223 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/reset/thead,th1520-reset.yaml b/Documentation/devicetree/bindings/reset/thead,th1520-reset.yaml index f2e91d0add7a..7b5053c177fe 100644 --- a/Documentation/devicetree/bindings/reset/thead,th1520-reset.yaml +++ b/Documentation/devicetree/bindings/reset/thead,th1520-reset.yaml @@ -16,7 +16,13 @@ maintainers: properties: compatible: enum: - - thead,th1520-reset + - thead,th1520-reset # Reset controller for VO subsystem + - thead,th1520-reset-ao + - thead,th1520-reset-ap + - thead,th1520-reset-dsp + - thead,th1520-reset-misc + - thead,th1520-reset-vi + - thead,th1520-reset-vp reg: maxItems: 1 diff --git a/include/dt-bindings/reset/thead,th1520-reset.h b/include/dt-bindings/reset/thead,th1520-reset.h index e51d6314d131..ba6805b6b12a 100644 --- a/include/dt-bindings/reset/thead,th1520-reset.h +++ b/include/dt-bindings/reset/thead,th1520-reset.h @@ -7,6 +7,200 @@ #ifndef _DT_BINDINGS_TH1520_RESET_H #define _DT_BINDINGS_TH1520_RESET_H +/* AO Subsystem */ +#define TH1520_RESET_ID_SYSTEM 0 +#define TH1520_RESET_ID_RTC_APB 1 +#define TH1520_RESET_ID_RTC_REF 2 +#define TH1520_RESET_ID_AOGPIO_DB 3 +#define TH1520_RESET_ID_AOGPIO_APB 4 +#define TH1520_RESET_ID_AOI2C_APB 5 +#define TH1520_RESET_ID_PVT_APB 6 +#define TH1520_RESET_ID_E902_CORE 7 +#define TH1520_RESET_ID_E902_HAD 8 +#define TH1520_RESET_ID_AOTIMER_APB 9 +#define TH1520_RESET_ID_AOTIMER_CORE 10 +#define TH1520_RESET_ID_AOWDT_APB 11 +#define TH1520_RESET_ID_APSYS 12 +#define TH1520_RESET_ID_NPUSYS 13 +#define TH1520_RESET_ID_DDRSYS 14 +#define TH1520_RESET_ID_AXI_AP2CP 15 +#define TH1520_RESET_ID_AXI_CP2AP 16 +#define TH1520_RESET_ID_AXI_CP2SRAM 17 +#define TH1520_RESET_ID_AUDSYS_CORE 18 +#define TH1520_RESET_ID_AUDSYS_IOPMP 19 +#define TH1520_RESET_ID_AUDSYS 20 +#define TH1520_RESET_ID_DSP0 21 +#define TH1520_RESET_ID_DSP1 22 +#define TH1520_RESET_ID_GPU_MODULE 23 +#define TH1520_RESET_ID_VDEC 24 +#define TH1520_RESET_ID_VENC 25 +#define TH1520_RESET_ID_ADC_APB 26 +#define TH1520_RESET_ID_AUDGPIO_DB 27 +#define TH1520_RESET_ID_AUDGPIO_APB 28 +#define TH1520_RESET_ID_AOUART_IF 29 +#define TH1520_RESET_ID_AOUART_APB 30 +#define TH1520_RESET_ID_SRAM_AXI_P0 31 +#define TH1520_RESET_ID_SRAM_AXI_P1 32 +#define TH1520_RESET_ID_SRAM_AXI_P2 33 +#define TH1520_RESET_ID_SRAM_AXI_P3 34 +#define TH1520_RESET_ID_SRAM_AXI_P4 35 +#define TH1520_RESET_ID_SRAM_AXI_CORE 36 +#define TH1520_RESET_ID_SE 37 + +/* AP Subsystem */ +#define TH1520_RESET_ID_BROM 0 +#define TH1520_RESET_ID_C910_TOP 1 +#define TH1520_RESET_ID_NPU 2 +#define TH1520_RESET_ID_WDT0 3 +#define TH1520_RESET_ID_WDT1 4 +#define TH1520_RESET_ID_C910_C0 5 +#define TH1520_RESET_ID_C910_C1 6 +#define TH1520_RESET_ID_C910_C2 7 +#define TH1520_RESET_ID_C910_C3 8 +#define TH1520_RESET_ID_CHIP_DBG_CORE 9 +#define TH1520_RESET_ID_CHIP_DBG_AXI 10 +#define TH1520_RESET_ID_AXI4_CPUSYS2_AXI 11 +#define TH1520_RESET_ID_AXI4_CPUSYS2_APB 12 +#define TH1520_RESET_ID_X2H_CPUSYS 13 +#define TH1520_RESET_ID_AHB2_CPUSYS 14 +#define TH1520_RESET_ID_APB3_CPUSYS 15 +#define TH1520_RESET_ID_MBOX0_APB 16 +#define TH1520_RESET_ID_MBOX1_APB 17 +#define TH1520_RESET_ID_MBOX2_APB 18 +#define TH1520_RESET_ID_MBOX3_APB 19 +#define TH1520_RESET_ID_TIMER0_APB 20 +#define TH1520_RESET_ID_TIMER0_CORE 21 +#define TH1520_RESET_ID_TIMER1_APB 22 +#define TH1520_RESET_ID_TIMER1_CORE 23 +#define TH1520_RESET_ID_PERISYS_AHB 24 +#define TH1520_RESET_ID_PERISYS_APB1 25 +#define TH1520_RESET_ID_PERISYS_APB2 26 +#define TH1520_RESET_ID_GMAC0_APB 27 +#define TH1520_RESET_ID_GMAC0_AHB 28 +#define TH1520_RESET_ID_GMAC0_CLKGEN 29 +#define TH1520_RESET_ID_GMAC0_AXI 30 +#define TH1520_RESET_ID_UART0_APB 31 +#define TH1520_RESET_ID_UART0_IF 32 +#define TH1520_RESET_ID_UART1_APB 33 +#define TH1520_RESET_ID_UART1_IF 34 +#define TH1520_RESET_ID_UART2_APB 35 +#define TH1520_RESET_ID_UART2_IF 36 +#define TH1520_RESET_ID_UART3_APB 37 +#define TH1520_RESET_ID_UART3_IF 38 +#define TH1520_RESET_ID_UART4_APB 39 +#define TH1520_RESET_ID_UART4_IF 40 +#define TH1520_RESET_ID_UART5_APB 41 +#define TH1520_RESET_ID_UART5_IF 42 +#define TH1520_RESET_ID_QSPI0_IF 43 +#define TH1520_RESET_ID_QSPI0_APB 44 +#define TH1520_RESET_ID_QSPI1_IF 45 +#define TH1520_RESET_ID_QSPI1_APB 46 +#define TH1520_RESET_ID_SPI_IF 47 +#define TH1520_RESET_ID_SPI_APB 48 +#define TH1520_RESET_ID_I2C0_APB 49 +#define TH1520_RESET_ID_I2C0_CORE 50 +#define TH1520_RESET_ID_I2C1_APB 51 +#define TH1520_RESET_ID_I2C1_CORE 52 +#define TH1520_RESET_ID_I2C2_APB 53 +#define TH1520_RESET_ID_I2C2_CORE 54 +#define TH1520_RESET_ID_I2C3_APB 55 +#define TH1520_RESET_ID_I2C3_CORE 56 +#define TH1520_RESET_ID_I2C4_APB 57 +#define TH1520_RESET_ID_I2C4_CORE 58 +#define TH1520_RESET_ID_I2C5_APB 59 +#define TH1520_RESET_ID_I2C5_CORE 60 +#define TH1520_RESET_ID_GPIO0_DB 61 +#define TH1520_RESET_ID_GPIO0_APB 62 +#define TH1520_RESET_ID_GPIO1_DB 63 +#define TH1520_RESET_ID_GPIO1_APB 64 +#define TH1520_RESET_ID_GPIO2_DB 65 +#define TH1520_RESET_ID_GPIO2_APB 66 +#define TH1520_RESET_ID_PWM_COUNTER 67 +#define TH1520_RESET_ID_PWM_APB 68 +#define TH1520_RESET_ID_PADCTRL0_APB 69 +#define TH1520_RESET_ID_CPU2PERI_X2H 70 +#define TH1520_RESET_ID_CPU2AON_X2H 71 +#define TH1520_RESET_ID_AON2CPU_A2X 72 +#define TH1520_RESET_ID_NPUSYS_AXI 73 +#define TH1520_RESET_ID_NPUSYS_AXI_APB 74 +#define TH1520_RESET_ID_CPU2VP_X2P 75 +#define TH1520_RESET_ID_CPU2VI_X2H 76 +#define TH1520_RESET_ID_BMU_AXI 77 +#define TH1520_RESET_ID_BMU_APB 78 +#define TH1520_RESET_ID_DMAC_CPUSYS_AXI 79 +#define TH1520_RESET_ID_DMAC_CPUSYS_AHB 80 +#define TH1520_RESET_ID_SPINLOCK 81 +#define TH1520_RESET_ID_CFG2TEE 82 +#define TH1520_RESET_ID_DSMART 83 +#define TH1520_RESET_ID_GPIO3_DB 84 +#define TH1520_RESET_ID_GPIO3_APB 85 +#define TH1520_RESET_ID_PERI_I2S 86 +#define TH1520_RESET_ID_PERI_APB3 87 +#define TH1520_RESET_ID_PERI2PERI1_APB 88 +#define TH1520_RESET_ID_VPSYS_APB 89 +#define TH1520_RESET_ID_PERISYS_APB4 90 +#define TH1520_RESET_ID_GMAC1_APB 91 +#define TH1520_RESET_ID_GMAC1_AHB 92 +#define TH1520_RESET_ID_GMAC1_CLKGEN 93 +#define TH1520_RESET_ID_GMAC1_AXI 94 +#define TH1520_RESET_ID_GMAC_AXI 95 +#define TH1520_RESET_ID_GMAC_AXI_APB 96 +#define TH1520_RESET_ID_PADCTRL1_APB 97 +#define TH1520_RESET_ID_VOSYS_AXI 98 +#define TH1520_RESET_ID_VOSYS_AXI_APB 99 +#define TH1520_RESET_ID_VOSYS_AXI_X2X 100 +#define TH1520_RESET_ID_MISC2VP_X2X 101 +#define TH1520_RESET_ID_DSPSYS 102 +#define TH1520_RESET_ID_VISYS 103 +#define TH1520_RESET_ID_VOSYS 104 +#define TH1520_RESET_ID_VPSYS 105 + +/* DSP Subsystem */ +#define TH1520_RESET_ID_X2X_DSP1 0 +#define TH1520_RESET_ID_X2X_DSP0 1 +#define TH1520_RESET_ID_X2X_SLAVE_DSP1 2 +#define TH1520_RESET_ID_X2X_SLAVE_DSP0 3 +#define TH1520_RESET_ID_DSP0_CORE 4 +#define TH1520_RESET_ID_DSP0_DEBUG 5 +#define TH1520_RESET_ID_DSP0_APB 6 +#define TH1520_RESET_ID_DSP1_CORE 7 +#define TH1520_RESET_ID_DSP1_DEBUG 8 +#define TH1520_RESET_ID_DSP1_APB 9 +#define TH1520_RESET_ID_DSPSYS_APB 10 +#define TH1520_RESET_ID_AXI4_DSPSYS_SLV 11 +#define TH1520_RESET_ID_AXI4_DSPSYS 12 +#define TH1520_RESET_ID_AXI4_DSP_RS 13 + +/* MISC Subsystem */ +#define TH1520_RESET_ID_EMMC_SDIO_CLKGEN 0 +#define TH1520_RESET_ID_EMMC 1 +#define TH1520_RESET_ID_MISCSYS_AXI 2 +#define TH1520_RESET_ID_MISCSYS_AXI_APB 3 +#define TH1520_RESET_ID_SDIO0 4 +#define TH1520_RESET_ID_SDIO1 5 +#define TH1520_RESET_ID_USB3_APB 6 +#define TH1520_RESET_ID_USB3_PHY 7 +#define TH1520_RESET_ID_USB3_VCC 8 + +/* VI Subsystem */ +#define TH1520_RESET_ID_ISP0 0 +#define TH1520_RESET_ID_ISP1 1 +#define TH1520_RESET_ID_CSI0_APB 2 +#define TH1520_RESET_ID_CSI1_APB 3 +#define TH1520_RESET_ID_CSI2_APB 4 +#define TH1520_RESET_ID_MIPI_FIFO 5 +#define TH1520_RESET_ID_ISP_VENC_APB 6 +#define TH1520_RESET_ID_VIPRE_APB 7 +#define TH1520_RESET_ID_VIPRE_AXI 8 +#define TH1520_RESET_ID_DW200_APB 9 +#define TH1520_RESET_ID_VISYS3_AXI 10 +#define TH1520_RESET_ID_VISYS2_AXI 11 +#define TH1520_RESET_ID_VISYS1_AXI 12 +#define TH1520_RESET_ID_VISYS_AXI 13 +#define TH1520_RESET_ID_VISYS_APB 14 +#define TH1520_RESET_ID_ISP_VENC_AXI 15 + +/* VO Subsystem */ #define TH1520_RESET_ID_GPU 0 #define TH1520_RESET_ID_GPU_CLKGEN 1 #define TH1520_RESET_ID_DPU_AHB 5 @@ -16,5 +210,27 @@ #define TH1520_RESET_ID_DSI1_APB 9 #define TH1520_RESET_ID_HDMI 10 #define TH1520_RESET_ID_HDMI_APB 11 +#define TH1520_RESET_ID_VOAXI 12 +#define TH1520_RESET_ID_VOAXI_APB 13 +#define TH1520_RESET_ID_X2H_DPU_AXI 14 +#define TH1520_RESET_ID_X2H_DPU_AHB 15 +#define TH1520_RESET_ID_X2H_DPU1_AXI 16 +#define TH1520_RESET_ID_X2H_DPU1_AHB 17 + +/* VP Subsystem */ +#define TH1520_RESET_ID_VPSYS_AXI_APB 0 +#define TH1520_RESET_ID_VPSYS_AXI 1 +#define TH1520_RESET_ID_FCE_APB 2 +#define TH1520_RESET_ID_FCE_CORE 3 +#define TH1520_RESET_ID_FCE_X2X_MASTER 4 +#define TH1520_RESET_ID_FCE_X2X_SLAVE 5 +#define TH1520_RESET_ID_G2D_APB 6 +#define TH1520_RESET_ID_G2D_ACLK 7 +#define TH1520_RESET_ID_G2D_CORE 8 +#define TH1520_RESET_ID_VDEC_APB 9 +#define TH1520_RESET_ID_VDEC_ACLK 10 +#define TH1520_RESET_ID_VDEC_CORE 11 +#define TH1520_RESET_ID_VENC_APB 12 +#define TH1520_RESET_ID_VENC_CORE 13 #endif /* _DT_BINDINGS_TH1520_RESET_H */ From 0040d9eac391bacefcb0c748cf32c8fe5900b13b Mon Sep 17 00:00:00 2001 From: Yao Zi Date: Tue, 14 Oct 2025 13:10:30 +0000 Subject: [PATCH 109/114] reset: th1520: Prepare for supporting multiple controllers TH1520 SoC is divided into several subsystems, shipping distinct reset controllers with similar control logic. Let's make reset signal mapping a data structure specific to one compatible to prepare for introduction of more reset controllers in the future. Signed-off-by: Yao Zi Acked-by: Guo Ren Reviewed-by: Drew Fustini Signed-off-by: Philipp Zabel --- drivers/reset/reset-th1520.c | 46 +++++++++++++++++++++++++----------- 1 file changed, 32 insertions(+), 14 deletions(-) diff --git a/drivers/reset/reset-th1520.c b/drivers/reset/reset-th1520.c index 14d964a9c6b6..2b65a95ed021 100644 --- a/drivers/reset/reset-th1520.c +++ b/drivers/reset/reset-th1520.c @@ -29,16 +29,22 @@ #define TH1520_HDMI_SW_MAIN_RST BIT(0) #define TH1520_HDMI_SW_PRST BIT(1) -struct th1520_reset_priv { - struct reset_controller_dev rcdev; - struct regmap *map; -}; - struct th1520_reset_map { u32 bit; u32 reg; }; +struct th1520_reset_priv { + struct reset_controller_dev rcdev; + struct regmap *map; + const struct th1520_reset_map *resets; +}; + +struct th1520_reset_data { + const struct th1520_reset_map *resets; + size_t num; +}; + static const struct th1520_reset_map th1520_resets[] = { [TH1520_RESET_ID_GPU] = { .bit = TH1520_GPU_SW_GPU_RST, @@ -90,7 +96,7 @@ static int th1520_reset_assert(struct reset_controller_dev *rcdev, struct th1520_reset_priv *priv = to_th1520_reset(rcdev); const struct th1520_reset_map *reset; - reset = &th1520_resets[id]; + reset = &priv->resets[id]; return regmap_update_bits(priv->map, reset->reg, reset->bit, 0); } @@ -101,7 +107,7 @@ static int th1520_reset_deassert(struct reset_controller_dev *rcdev, struct th1520_reset_priv *priv = to_th1520_reset(rcdev); const struct th1520_reset_map *reset; - reset = &th1520_resets[id]; + reset = &priv->resets[id]; return regmap_update_bits(priv->map, reset->reg, reset->bit, reset->bit); @@ -120,11 +126,14 @@ static const struct regmap_config th1520_reset_regmap_config = { static int th1520_reset_probe(struct platform_device *pdev) { + const struct th1520_reset_data *data; struct device *dev = &pdev->dev; struct th1520_reset_priv *priv; void __iomem *base; int ret; + data = device_get_match_data(dev); + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); if (!priv) return -ENOMEM; @@ -138,22 +147,31 @@ static int th1520_reset_probe(struct platform_device *pdev) if (IS_ERR(priv->map)) return PTR_ERR(priv->map); - /* Initialize GPU resets to asserted state */ - ret = regmap_update_bits(priv->map, TH1520_GPU_RST_CFG, - TH1520_GPU_RST_CFG_MASK, 0); - if (ret) - return ret; + if (of_device_is_compatible(dev->of_node, "thead,th1520-reset")) { + /* Initialize GPU resets to asserted state */ + ret = regmap_update_bits(priv->map, TH1520_GPU_RST_CFG, + TH1520_GPU_RST_CFG_MASK, 0); + if (ret) + return ret; + } priv->rcdev.owner = THIS_MODULE; - priv->rcdev.nr_resets = ARRAY_SIZE(th1520_resets); + priv->rcdev.nr_resets = data->num; priv->rcdev.ops = &th1520_reset_ops; priv->rcdev.of_node = dev->of_node; + priv->resets = data->resets; + return devm_reset_controller_register(dev, &priv->rcdev); } +static const struct th1520_reset_data th1520_reset_data = { + .resets = th1520_resets, + .num = ARRAY_SIZE(th1520_resets), +}; + static const struct of_device_id th1520_reset_match[] = { - { .compatible = "thead,th1520-reset" }, + { .compatible = "thead,th1520-reset", .data = &th1520_reset_data }, { /* sentinel */ } }; MODULE_DEVICE_TABLE(of, th1520_reset_match); From da91533c2b7a569b272b8271f0b2c407f86407ed Mon Sep 17 00:00:00 2001 From: Yao Zi Date: Tue, 14 Oct 2025 13:10:31 +0000 Subject: [PATCH 110/114] reset: th1520: Support reset controllers in more subsystems Introduce reset controllers for AP, MISC, VI, VP and DSP subsystems and add their reset signal mappings. Signed-off-by: Yao Zi Reviewed-by: Drew Fustini Acked-by: Guo Ren Signed-off-by: Philipp Zabel --- drivers/reset/reset-th1520.c | 793 +++++++++++++++++++++++++++++++++++ 1 file changed, 793 insertions(+) diff --git a/drivers/reset/reset-th1520.c b/drivers/reset/reset-th1520.c index 2b65a95ed021..fd32e991c4cb 100644 --- a/drivers/reset/reset-th1520.c +++ b/drivers/reset/reset-th1520.c @@ -11,6 +11,85 @@ #include + /* register offset in RSTGEN_R */ +#define TH1520_BROM_RST_CFG 0x0 +#define TH1520_C910_RST_CFG 0x4 +#define TH1520_CHIP_DBG_RST_CFG 0xc +#define TH1520_AXI4_CPUSYS2_RST_CFG 0x10 +#define TH1520_X2H_CPUSYS_RST_CFG 0x18 +#define TH1520_AHB2_CPUSYS_RST_CFG 0x1c +#define TH1520_APB3_CPUSYS_RST_CFG 0x20 +#define TH1520_MBOX0_RST_CFG 0x24 +#define TH1520_MBOX1_RST_CFG 0x28 +#define TH1520_MBOX2_RST_CFG 0x2c +#define TH1520_MBOX3_RST_CFG 0x30 +#define TH1520_WDT0_RST_CFG 0x34 +#define TH1520_WDT1_RST_CFG 0x38 +#define TH1520_TIMER0_RST_CFG 0x3c +#define TH1520_TIMER1_RST_CFG 0x40 +#define TH1520_PERISYS_AHB_RST_CFG 0x44 +#define TH1520_PERISYS_APB1_RST_CFG 0x48 +#define TH1520_PERISYS_APB2_RST_CFG 0x4c +#define TH1520_GMAC0_RST_CFG 0x68 +#define TH1520_UART0_RST_CFG 0x70 +#define TH1520_UART1_RST_CFG 0x74 +#define TH1520_UART2_RST_CFG 0x78 +#define TH1520_UART3_RST_CFG 0x7c +#define TH1520_UART4_RST_CFG 0x80 +#define TH1520_UART5_RST_CFG 0x84 +#define TH1520_QSPI0_RST_CFG 0x8c +#define TH1520_QSPI1_RST_CFG 0x90 +#define TH1520_SPI_RST_CFG 0x94 +#define TH1520_I2C0_RST_CFG 0x98 +#define TH1520_I2C1_RST_CFG 0x9c +#define TH1520_I2C2_RST_CFG 0xa0 +#define TH1520_I2C3_RST_CFG 0xa4 +#define TH1520_I2C4_RST_CFG 0xa8 +#define TH1520_I2C5_RST_CFG 0xac +#define TH1520_GPIO0_RST_CFG 0xb0 +#define TH1520_GPIO1_RST_CFG 0xb4 +#define TH1520_GPIO2_RST_CFG 0xb8 +#define TH1520_PWM_RST_CFG 0xc0 +#define TH1520_PADCTRL0_APSYS_RST_CFG 0xc4 +#define TH1520_CPU2PERI_X2H_RST_CFG 0xcc +#define TH1520_CPU2AON_X2H_RST_CFG 0xe4 +#define TH1520_AON2CPU_A2X_RST_CFG 0xfc +#define TH1520_NPUSYS_AXI_RST_CFG 0x128 +#define TH1520_CPU2VP_X2P_RST_CFG 0x12c +#define TH1520_CPU2VI_X2H_RST_CFG 0x138 +#define TH1520_BMU_C910_RST_CFG 0x148 +#define TH1520_DMAC_CPUSYS_RST_CFG 0x14c +#define TH1520_SPINLOCK_RST_CFG 0x178 +#define TH1520_CFG2TEE_X2H_RST_CFG 0x188 +#define TH1520_DSMART_RST_CFG 0x18c +#define TH1520_GPIO3_RST_CFG 0x1a8 +#define TH1520_I2S_RST_CFG 0x1ac +#define TH1520_IMG_NNA_RST_CFG 0x1b0 +#define TH1520_PERI_APB3_RST_CFG 0x1dc +#define TH1520_VP_SUBSYS_RST_CFG 0x1ec +#define TH1520_PERISYS_APB4_RST_CFG 0x1f8 +#define TH1520_GMAC1_RST_CFG 0x204 +#define TH1520_GMAC_AXI_RST_CFG 0x208 +#define TH1520_PADCTRL1_APSYS_RST_CFG 0x20c +#define TH1520_VOSYS_AXI_RST_CFG 0x210 +#define TH1520_VOSYS_X2X_RST_CFG 0x214 +#define TH1520_MISC2VP_X2X_RST_CFG 0x218 +#define TH1520_SUBSYS_RST_CFG 0x220 + + /* register offset in DSP_REGMAP */ +#define TH1520_DSPSYS_RST_CFG 0x0 + + /* register offset in MISCSYS_REGMAP */ +#define TH1520_EMMC_RST_CFG 0x0 +#define TH1520_MISCSYS_AXI_RST_CFG 0x8 +#define TH1520_SDIO0_RST_CFG 0xc +#define TH1520_SDIO1_RST_CFG 0x10 +#define TH1520_USB3_DRD_RST_CFG 0x14 + + /* register offset in VISYS_REGMAP */ +#define TH1520_VISYS_RST_CFG 0x0 +#define TH1520_VISYS_2_RST_CFG 0x4 + /* register offset in VOSYS_REGMAP */ #define TH1520_GPU_RST_CFG 0x0 #define TH1520_GPU_RST_CFG_MASK GENMASK(1, 0) @@ -18,6 +97,8 @@ #define TH1520_DSI0_RST_CFG 0x8 #define TH1520_DSI1_RST_CFG 0xc #define TH1520_HDMI_RST_CFG 0x14 +#define TH1520_AXI4_VO_DW_AXI_RST_CFG 0x18 +#define TH1520_X2H_X4_VOSYS_DW_RST_CFG 0x20 /* register values */ #define TH1520_GPU_SW_GPU_RST BIT(0) @@ -29,6 +110,13 @@ #define TH1520_HDMI_SW_MAIN_RST BIT(0) #define TH1520_HDMI_SW_PRST BIT(1) + /* register offset in VPSYS_REGMAP */ +#define TH1520_AXIBUS_RST_CFG 0x0 +#define TH1520_FCE_RST_CFG 0x4 +#define TH1520_G2D_RST_CFG 0x8 +#define TH1520_VDEC_RST_CFG 0xc +#define TH1520_VENC_RST_CFG 0x10 + struct th1520_reset_map { u32 bit; u32 reg; @@ -82,6 +170,681 @@ static const struct th1520_reset_map th1520_resets[] = { .bit = TH1520_HDMI_SW_PRST, .reg = TH1520_HDMI_RST_CFG, }, + [TH1520_RESET_ID_VOAXI] = { + .bit = BIT(0), + .reg = TH1520_AXI4_VO_DW_AXI_RST_CFG, + }, + [TH1520_RESET_ID_VOAXI_APB] = { + .bit = BIT(1), + .reg = TH1520_AXI4_VO_DW_AXI_RST_CFG, + }, + [TH1520_RESET_ID_X2H_DPU_AXI] = { + .bit = BIT(0), + .reg = TH1520_X2H_X4_VOSYS_DW_RST_CFG, + }, + [TH1520_RESET_ID_X2H_DPU_AHB] = { + .bit = BIT(1), + .reg = TH1520_X2H_X4_VOSYS_DW_RST_CFG, + }, + [TH1520_RESET_ID_X2H_DPU1_AXI] = { + .bit = BIT(2), + .reg = TH1520_X2H_X4_VOSYS_DW_RST_CFG, + }, + [TH1520_RESET_ID_X2H_DPU1_AHB] = { + .bit = BIT(3), + .reg = TH1520_X2H_X4_VOSYS_DW_RST_CFG, + }, +}; + +static const struct th1520_reset_map th1520_ap_resets[] = { + [TH1520_RESET_ID_BROM] = { + .bit = BIT(0), + .reg = TH1520_BROM_RST_CFG, + }, + [TH1520_RESET_ID_C910_TOP] = { + .bit = BIT(0), + .reg = TH1520_C910_RST_CFG, + }, + [TH1520_RESET_ID_NPU] = { + .bit = BIT(0), + .reg = TH1520_IMG_NNA_RST_CFG, + }, + [TH1520_RESET_ID_WDT0] = { + .bit = BIT(0), + .reg = TH1520_WDT0_RST_CFG, + }, + [TH1520_RESET_ID_WDT1] = { + .bit = BIT(0), + .reg = TH1520_WDT1_RST_CFG, + }, + [TH1520_RESET_ID_C910_C0] = { + .bit = BIT(1), + .reg = TH1520_C910_RST_CFG, + }, + [TH1520_RESET_ID_C910_C1] = { + .bit = BIT(2), + .reg = TH1520_C910_RST_CFG, + }, + [TH1520_RESET_ID_C910_C2] = { + .bit = BIT(3), + .reg = TH1520_C910_RST_CFG, + }, + [TH1520_RESET_ID_C910_C3] = { + .bit = BIT(4), + .reg = TH1520_C910_RST_CFG, + }, + [TH1520_RESET_ID_CHIP_DBG_CORE] = { + .bit = BIT(0), + .reg = TH1520_CHIP_DBG_RST_CFG, + }, + [TH1520_RESET_ID_CHIP_DBG_AXI] = { + .bit = BIT(1), + .reg = TH1520_CHIP_DBG_RST_CFG, + }, + [TH1520_RESET_ID_AXI4_CPUSYS2_AXI] = { + .bit = BIT(0), + .reg = TH1520_AXI4_CPUSYS2_RST_CFG, + }, + [TH1520_RESET_ID_AXI4_CPUSYS2_APB] = { + .bit = BIT(1), + .reg = TH1520_AXI4_CPUSYS2_RST_CFG, + }, + [TH1520_RESET_ID_X2H_CPUSYS] = { + .bit = BIT(0), + .reg = TH1520_X2H_CPUSYS_RST_CFG, + }, + [TH1520_RESET_ID_AHB2_CPUSYS] = { + .bit = BIT(0), + .reg = TH1520_AHB2_CPUSYS_RST_CFG, + }, + [TH1520_RESET_ID_APB3_CPUSYS] = { + .bit = BIT(0), + .reg = TH1520_APB3_CPUSYS_RST_CFG, + }, + [TH1520_RESET_ID_MBOX0_APB] = { + .bit = BIT(0), + .reg = TH1520_MBOX0_RST_CFG, + }, + [TH1520_RESET_ID_MBOX1_APB] = { + .bit = BIT(0), + .reg = TH1520_MBOX1_RST_CFG, + }, + [TH1520_RESET_ID_MBOX2_APB] = { + .bit = BIT(0), + .reg = TH1520_MBOX2_RST_CFG, + }, + [TH1520_RESET_ID_MBOX3_APB] = { + .bit = BIT(0), + .reg = TH1520_MBOX3_RST_CFG, + }, + [TH1520_RESET_ID_TIMER0_APB] = { + .bit = BIT(0), + .reg = TH1520_TIMER0_RST_CFG, + }, + [TH1520_RESET_ID_TIMER0_CORE] = { + .bit = BIT(1), + .reg = TH1520_TIMER0_RST_CFG, + }, + [TH1520_RESET_ID_TIMER1_APB] = { + .bit = BIT(0), + .reg = TH1520_TIMER1_RST_CFG, + }, + [TH1520_RESET_ID_TIMER1_CORE] = { + .bit = BIT(1), + .reg = TH1520_TIMER1_RST_CFG, + }, + [TH1520_RESET_ID_PERISYS_AHB] = { + .bit = BIT(0), + .reg = TH1520_PERISYS_AHB_RST_CFG, + }, + [TH1520_RESET_ID_PERISYS_APB1] = { + .bit = BIT(0), + .reg = TH1520_PERISYS_APB1_RST_CFG, + }, + [TH1520_RESET_ID_PERISYS_APB2] = { + .bit = BIT(0), + .reg = TH1520_PERISYS_APB2_RST_CFG, + }, + [TH1520_RESET_ID_GMAC0_APB] = { + .bit = BIT(0), + .reg = TH1520_GMAC0_RST_CFG, + }, + [TH1520_RESET_ID_GMAC0_AHB] = { + .bit = BIT(1), + .reg = TH1520_GMAC0_RST_CFG, + }, + [TH1520_RESET_ID_GMAC0_CLKGEN] = { + .bit = BIT(2), + .reg = TH1520_GMAC0_RST_CFG, + }, + [TH1520_RESET_ID_GMAC0_AXI] = { + .bit = BIT(3), + .reg = TH1520_GMAC0_RST_CFG, + }, + [TH1520_RESET_ID_UART0_APB] = { + .bit = BIT(0), + .reg = TH1520_UART0_RST_CFG, + }, + [TH1520_RESET_ID_UART0_IF] = { + .bit = BIT(1), + .reg = TH1520_UART0_RST_CFG, + }, + [TH1520_RESET_ID_UART1_APB] = { + .bit = BIT(0), + .reg = TH1520_UART1_RST_CFG, + }, + [TH1520_RESET_ID_UART1_IF] = { + .bit = BIT(1), + .reg = TH1520_UART1_RST_CFG, + }, + [TH1520_RESET_ID_UART2_APB] = { + .bit = BIT(0), + .reg = TH1520_UART2_RST_CFG, + }, + [TH1520_RESET_ID_UART2_IF] = { + .bit = BIT(1), + .reg = TH1520_UART2_RST_CFG, + }, + [TH1520_RESET_ID_UART3_APB] = { + .bit = BIT(0), + .reg = TH1520_UART3_RST_CFG, + }, + [TH1520_RESET_ID_UART3_IF] = { + .bit = BIT(1), + .reg = TH1520_UART3_RST_CFG, + }, + [TH1520_RESET_ID_UART4_APB] = { + .bit = BIT(0), + .reg = TH1520_UART4_RST_CFG, + }, + [TH1520_RESET_ID_UART4_IF] = { + .bit = BIT(1), + .reg = TH1520_UART4_RST_CFG, + }, + [TH1520_RESET_ID_UART5_APB] = { + .bit = BIT(0), + .reg = TH1520_UART5_RST_CFG, + }, + [TH1520_RESET_ID_UART5_IF] = { + .bit = BIT(1), + .reg = TH1520_UART5_RST_CFG, + }, + [TH1520_RESET_ID_QSPI0_IF] = { + .bit = BIT(0), + .reg = TH1520_QSPI0_RST_CFG, + }, + [TH1520_RESET_ID_QSPI0_APB] = { + .bit = BIT(1), + .reg = TH1520_QSPI0_RST_CFG, + }, + [TH1520_RESET_ID_QSPI1_IF] = { + .bit = BIT(0), + .reg = TH1520_QSPI1_RST_CFG, + }, + [TH1520_RESET_ID_QSPI1_APB] = { + .bit = BIT(1), + .reg = TH1520_QSPI1_RST_CFG, + }, + [TH1520_RESET_ID_SPI_IF] = { + .bit = BIT(0), + .reg = TH1520_SPI_RST_CFG, + }, + [TH1520_RESET_ID_SPI_APB] = { + .bit = BIT(1), + .reg = TH1520_SPI_RST_CFG, + }, + [TH1520_RESET_ID_I2C0_APB] = { + .bit = BIT(0), + .reg = TH1520_I2C0_RST_CFG, + }, + [TH1520_RESET_ID_I2C0_CORE] = { + .bit = BIT(1), + .reg = TH1520_I2C0_RST_CFG, + }, + [TH1520_RESET_ID_I2C1_APB] = { + .bit = BIT(0), + .reg = TH1520_I2C1_RST_CFG, + }, + [TH1520_RESET_ID_I2C1_CORE] = { + .bit = BIT(1), + .reg = TH1520_I2C1_RST_CFG, + }, + [TH1520_RESET_ID_I2C2_APB] = { + .bit = BIT(0), + .reg = TH1520_I2C2_RST_CFG, + }, + [TH1520_RESET_ID_I2C2_CORE] = { + .bit = BIT(1), + .reg = TH1520_I2C2_RST_CFG, + }, + [TH1520_RESET_ID_I2C3_APB] = { + .bit = BIT(0), + .reg = TH1520_I2C3_RST_CFG, + }, + [TH1520_RESET_ID_I2C3_CORE] = { + .bit = BIT(1), + .reg = TH1520_I2C3_RST_CFG, + }, + [TH1520_RESET_ID_I2C4_APB] = { + .bit = BIT(0), + .reg = TH1520_I2C4_RST_CFG, + }, + [TH1520_RESET_ID_I2C4_CORE] = { + .bit = BIT(1), + .reg = TH1520_I2C4_RST_CFG, + }, + [TH1520_RESET_ID_I2C5_APB] = { + .bit = BIT(0), + .reg = TH1520_I2C5_RST_CFG, + }, + [TH1520_RESET_ID_I2C5_CORE] = { + .bit = BIT(1), + .reg = TH1520_I2C5_RST_CFG, + }, + [TH1520_RESET_ID_GPIO0_DB] = { + .bit = BIT(0), + .reg = TH1520_GPIO0_RST_CFG, + }, + [TH1520_RESET_ID_GPIO0_APB] = { + .bit = BIT(1), + .reg = TH1520_GPIO0_RST_CFG, + }, + [TH1520_RESET_ID_GPIO1_DB] = { + .bit = BIT(0), + .reg = TH1520_GPIO1_RST_CFG, + }, + [TH1520_RESET_ID_GPIO1_APB] = { + .bit = BIT(1), + .reg = TH1520_GPIO1_RST_CFG, + }, + [TH1520_RESET_ID_GPIO2_DB] = { + .bit = BIT(0), + .reg = TH1520_GPIO2_RST_CFG, + }, + [TH1520_RESET_ID_GPIO2_APB] = { + .bit = BIT(1), + .reg = TH1520_GPIO2_RST_CFG, + }, + [TH1520_RESET_ID_PWM_COUNTER] = { + .bit = BIT(0), + .reg = TH1520_PWM_RST_CFG, + }, + [TH1520_RESET_ID_PWM_APB] = { + .bit = BIT(1), + .reg = TH1520_PWM_RST_CFG, + }, + [TH1520_RESET_ID_PADCTRL0_APB] = { + .bit = BIT(0), + .reg = TH1520_PADCTRL0_APSYS_RST_CFG, + }, + [TH1520_RESET_ID_CPU2PERI_X2H] = { + .bit = BIT(1), + .reg = TH1520_CPU2PERI_X2H_RST_CFG, + }, + [TH1520_RESET_ID_CPU2AON_X2H] = { + .bit = BIT(0), + .reg = TH1520_CPU2AON_X2H_RST_CFG, + }, + [TH1520_RESET_ID_AON2CPU_A2X] = { + .bit = BIT(0), + .reg = TH1520_AON2CPU_A2X_RST_CFG, + }, + [TH1520_RESET_ID_NPUSYS_AXI] = { + .bit = BIT(0), + .reg = TH1520_NPUSYS_AXI_RST_CFG, + }, + [TH1520_RESET_ID_NPUSYS_AXI_APB] = { + .bit = BIT(1), + .reg = TH1520_NPUSYS_AXI_RST_CFG, + }, + [TH1520_RESET_ID_CPU2VP_X2P] = { + .bit = BIT(0), + .reg = TH1520_CPU2VP_X2P_RST_CFG, + }, + [TH1520_RESET_ID_CPU2VI_X2H] = { + .bit = BIT(0), + .reg = TH1520_CPU2VI_X2H_RST_CFG, + }, + [TH1520_RESET_ID_BMU_AXI] = { + .bit = BIT(0), + .reg = TH1520_BMU_C910_RST_CFG, + }, + [TH1520_RESET_ID_BMU_APB] = { + .bit = BIT(1), + .reg = TH1520_BMU_C910_RST_CFG, + }, + [TH1520_RESET_ID_DMAC_CPUSYS_AXI] = { + .bit = BIT(0), + .reg = TH1520_DMAC_CPUSYS_RST_CFG, + }, + [TH1520_RESET_ID_DMAC_CPUSYS_AHB] = { + .bit = BIT(1), + .reg = TH1520_DMAC_CPUSYS_RST_CFG, + }, + [TH1520_RESET_ID_SPINLOCK] = { + .bit = BIT(0), + .reg = TH1520_SPINLOCK_RST_CFG, + }, + [TH1520_RESET_ID_CFG2TEE] = { + .bit = BIT(0), + .reg = TH1520_CFG2TEE_X2H_RST_CFG, + }, + [TH1520_RESET_ID_DSMART] = { + .bit = BIT(0), + .reg = TH1520_DSMART_RST_CFG, + }, + [TH1520_RESET_ID_GPIO3_DB] = { + .bit = BIT(0), + .reg = TH1520_GPIO3_RST_CFG, + }, + [TH1520_RESET_ID_GPIO3_APB] = { + .bit = BIT(1), + .reg = TH1520_GPIO3_RST_CFG, + }, + [TH1520_RESET_ID_PERI_I2S] = { + .bit = BIT(0), + .reg = TH1520_I2S_RST_CFG, + }, + [TH1520_RESET_ID_PERI_APB3] = { + .bit = BIT(0), + .reg = TH1520_PERI_APB3_RST_CFG, + }, + [TH1520_RESET_ID_PERI2PERI1_APB] = { + .bit = BIT(1), + .reg = TH1520_PERI_APB3_RST_CFG, + }, + [TH1520_RESET_ID_VPSYS_APB] = { + .bit = BIT(0), + .reg = TH1520_VP_SUBSYS_RST_CFG, + }, + [TH1520_RESET_ID_PERISYS_APB4] = { + .bit = BIT(0), + .reg = TH1520_PERISYS_APB4_RST_CFG, + }, + [TH1520_RESET_ID_GMAC1_APB] = { + .bit = BIT(0), + .reg = TH1520_GMAC1_RST_CFG, + }, + [TH1520_RESET_ID_GMAC1_AHB] = { + .bit = BIT(1), + .reg = TH1520_GMAC1_RST_CFG, + }, + [TH1520_RESET_ID_GMAC1_CLKGEN] = { + .bit = BIT(2), + .reg = TH1520_GMAC1_RST_CFG, + }, + [TH1520_RESET_ID_GMAC1_AXI] = { + .bit = BIT(3), + .reg = TH1520_GMAC1_RST_CFG, + }, + [TH1520_RESET_ID_GMAC_AXI] = { + .bit = BIT(0), + .reg = TH1520_GMAC_AXI_RST_CFG, + }, + [TH1520_RESET_ID_GMAC_AXI_APB] = { + .bit = BIT(1), + .reg = TH1520_GMAC_AXI_RST_CFG, + }, + [TH1520_RESET_ID_PADCTRL1_APB] = { + .bit = BIT(0), + .reg = TH1520_PADCTRL1_APSYS_RST_CFG, + }, + [TH1520_RESET_ID_VOSYS_AXI] = { + .bit = BIT(0), + .reg = TH1520_VOSYS_AXI_RST_CFG, + }, + [TH1520_RESET_ID_VOSYS_AXI_APB] = { + .bit = BIT(1), + .reg = TH1520_VOSYS_AXI_RST_CFG, + }, + [TH1520_RESET_ID_VOSYS_AXI_X2X] = { + .bit = BIT(0), + .reg = TH1520_VOSYS_X2X_RST_CFG, + }, + [TH1520_RESET_ID_MISC2VP_X2X] = { + .bit = BIT(0), + .reg = TH1520_MISC2VP_X2X_RST_CFG, + }, + [TH1520_RESET_ID_DSPSYS] = { + .bit = BIT(0), + .reg = TH1520_SUBSYS_RST_CFG, + }, + [TH1520_RESET_ID_VISYS] = { + .bit = BIT(1), + .reg = TH1520_SUBSYS_RST_CFG, + }, + [TH1520_RESET_ID_VOSYS] = { + .bit = BIT(2), + .reg = TH1520_SUBSYS_RST_CFG, + }, + [TH1520_RESET_ID_VPSYS] = { + .bit = BIT(3), + .reg = TH1520_SUBSYS_RST_CFG, + }, +}; + +static const struct th1520_reset_map th1520_dsp_resets[] = { + [TH1520_RESET_ID_X2X_DSP1] = { + .bit = BIT(0), + .reg = TH1520_DSPSYS_RST_CFG, + }, + [TH1520_RESET_ID_X2X_DSP0] = { + .bit = BIT(1), + .reg = TH1520_DSPSYS_RST_CFG, + }, + [TH1520_RESET_ID_X2X_SLAVE_DSP1] = { + .bit = BIT(2), + .reg = TH1520_DSPSYS_RST_CFG, + }, + [TH1520_RESET_ID_X2X_SLAVE_DSP0] = { + .bit = BIT(3), + .reg = TH1520_DSPSYS_RST_CFG, + }, + [TH1520_RESET_ID_DSP0_CORE] = { + .bit = BIT(8), + .reg = TH1520_DSPSYS_RST_CFG, + }, + [TH1520_RESET_ID_DSP0_DEBUG] = { + .bit = BIT(9), + .reg = TH1520_DSPSYS_RST_CFG, + }, + [TH1520_RESET_ID_DSP0_APB] = { + .bit = BIT(10), + .reg = TH1520_DSPSYS_RST_CFG, + }, + [TH1520_RESET_ID_DSP1_CORE] = { + .bit = BIT(12), + .reg = TH1520_DSPSYS_RST_CFG, + }, + [TH1520_RESET_ID_DSP1_DEBUG] = { + .bit = BIT(13), + .reg = TH1520_DSPSYS_RST_CFG, + }, + [TH1520_RESET_ID_DSP1_APB] = { + .bit = BIT(14), + .reg = TH1520_DSPSYS_RST_CFG, + }, + [TH1520_RESET_ID_DSPSYS_APB] = { + .bit = BIT(16), + .reg = TH1520_DSPSYS_RST_CFG, + }, + [TH1520_RESET_ID_AXI4_DSPSYS_SLV] = { + .bit = BIT(20), + .reg = TH1520_DSPSYS_RST_CFG, + }, + [TH1520_RESET_ID_AXI4_DSPSYS] = { + .bit = BIT(24), + .reg = TH1520_DSPSYS_RST_CFG, + }, + [TH1520_RESET_ID_AXI4_DSP_RS] = { + .bit = BIT(26), + .reg = TH1520_DSPSYS_RST_CFG, + }, +}; + +static const struct th1520_reset_map th1520_misc_resets[] = { + [TH1520_RESET_ID_EMMC_SDIO_CLKGEN] = { + .bit = BIT(0), + .reg = TH1520_EMMC_RST_CFG, + }, + [TH1520_RESET_ID_EMMC] = { + .bit = BIT(1), + .reg = TH1520_EMMC_RST_CFG, + }, + [TH1520_RESET_ID_MISCSYS_AXI] = { + .bit = BIT(0), + .reg = TH1520_MISCSYS_AXI_RST_CFG, + }, + [TH1520_RESET_ID_MISCSYS_AXI_APB] = { + .bit = BIT(1), + .reg = TH1520_MISCSYS_AXI_RST_CFG, + }, + [TH1520_RESET_ID_SDIO0] = { + .bit = BIT(0), + .reg = TH1520_SDIO0_RST_CFG, + }, + [TH1520_RESET_ID_SDIO1] = { + .bit = BIT(1), + .reg = TH1520_SDIO1_RST_CFG, + }, + [TH1520_RESET_ID_USB3_APB] = { + .bit = BIT(0), + .reg = TH1520_USB3_DRD_RST_CFG, + }, + [TH1520_RESET_ID_USB3_PHY] = { + .bit = BIT(1), + .reg = TH1520_USB3_DRD_RST_CFG, + }, + [TH1520_RESET_ID_USB3_VCC] = { + .bit = BIT(2), + .reg = TH1520_USB3_DRD_RST_CFG, + }, +}; + +static const struct th1520_reset_map th1520_vi_resets[] = { + [TH1520_RESET_ID_ISP0] = { + .bit = BIT(0), + .reg = TH1520_VISYS_RST_CFG, + }, + [TH1520_RESET_ID_ISP1] = { + .bit = BIT(4), + .reg = TH1520_VISYS_RST_CFG, + }, + [TH1520_RESET_ID_CSI0_APB] = { + .bit = BIT(16), + .reg = TH1520_VISYS_RST_CFG, + }, + [TH1520_RESET_ID_CSI1_APB] = { + .bit = BIT(17), + .reg = TH1520_VISYS_RST_CFG, + }, + [TH1520_RESET_ID_CSI2_APB] = { + .bit = BIT(18), + .reg = TH1520_VISYS_RST_CFG, + }, + [TH1520_RESET_ID_MIPI_FIFO] = { + .bit = BIT(20), + .reg = TH1520_VISYS_RST_CFG, + }, + [TH1520_RESET_ID_ISP_VENC_APB] = { + .bit = BIT(24), + .reg = TH1520_VISYS_RST_CFG, + }, + [TH1520_RESET_ID_VIPRE_APB] = { + .bit = BIT(28), + .reg = TH1520_VISYS_RST_CFG, + }, + [TH1520_RESET_ID_VIPRE_AXI] = { + .bit = BIT(29), + .reg = TH1520_VISYS_RST_CFG, + }, + [TH1520_RESET_ID_DW200_APB] = { + .bit = BIT(31), + .reg = TH1520_VISYS_RST_CFG, + }, + [TH1520_RESET_ID_VISYS3_AXI] = { + .bit = BIT(8), + .reg = TH1520_VISYS_2_RST_CFG, + }, + [TH1520_RESET_ID_VISYS2_AXI] = { + .bit = BIT(9), + .reg = TH1520_VISYS_2_RST_CFG, + }, + [TH1520_RESET_ID_VISYS1_AXI] = { + .bit = BIT(10), + .reg = TH1520_VISYS_2_RST_CFG, + }, + [TH1520_RESET_ID_VISYS_AXI] = { + .bit = BIT(12), + .reg = TH1520_VISYS_2_RST_CFG, + }, + [TH1520_RESET_ID_VISYS_APB] = { + .bit = BIT(16), + .reg = TH1520_VISYS_2_RST_CFG, + }, + [TH1520_RESET_ID_ISP_VENC_AXI] = { + .bit = BIT(20), + .reg = TH1520_VISYS_2_RST_CFG, + }, +}; + +static const struct th1520_reset_map th1520_vp_resets[] = { + [TH1520_RESET_ID_VPSYS_AXI_APB] = { + .bit = BIT(0), + .reg = TH1520_AXIBUS_RST_CFG, + }, + [TH1520_RESET_ID_VPSYS_AXI] = { + .bit = BIT(1), + .reg = TH1520_AXIBUS_RST_CFG, + }, + [TH1520_RESET_ID_FCE_APB] = { + .bit = BIT(0), + .reg = TH1520_FCE_RST_CFG, + }, + [TH1520_RESET_ID_FCE_CORE] = { + .bit = BIT(1), + .reg = TH1520_FCE_RST_CFG, + }, + [TH1520_RESET_ID_FCE_X2X_MASTER] = { + .bit = BIT(4), + .reg = TH1520_FCE_RST_CFG, + }, + [TH1520_RESET_ID_FCE_X2X_SLAVE] = { + .bit = BIT(5), + .reg = TH1520_FCE_RST_CFG, + }, + [TH1520_RESET_ID_G2D_APB] = { + .bit = BIT(0), + .reg = TH1520_G2D_RST_CFG, + }, + [TH1520_RESET_ID_G2D_ACLK] = { + .bit = BIT(1), + .reg = TH1520_G2D_RST_CFG, + }, + [TH1520_RESET_ID_G2D_CORE] = { + .bit = BIT(2), + .reg = TH1520_G2D_RST_CFG, + }, + [TH1520_RESET_ID_VDEC_APB] = { + .bit = BIT(0), + .reg = TH1520_VDEC_RST_CFG, + }, + [TH1520_RESET_ID_VDEC_ACLK] = { + .bit = BIT(1), + .reg = TH1520_VDEC_RST_CFG, + }, + [TH1520_RESET_ID_VDEC_CORE] = { + .bit = BIT(2), + .reg = TH1520_VDEC_RST_CFG, + }, + [TH1520_RESET_ID_VENC_APB] = { + .bit = BIT(0), + .reg = TH1520_VENC_RST_CFG, + }, + [TH1520_RESET_ID_VENC_CORE] = { + .bit = BIT(1), + .reg = TH1520_VENC_RST_CFG, + }, }; static inline struct th1520_reset_priv * @@ -170,8 +933,38 @@ static const struct th1520_reset_data th1520_reset_data = { .num = ARRAY_SIZE(th1520_resets), }; +static const struct th1520_reset_data th1520_ap_reset_data = { + .resets = th1520_ap_resets, + .num = ARRAY_SIZE(th1520_ap_resets), +}; + +static const struct th1520_reset_data th1520_dsp_reset_data = { + .resets = th1520_dsp_resets, + .num = ARRAY_SIZE(th1520_dsp_resets), +}; + +static const struct th1520_reset_data th1520_misc_reset_data = { + .resets = th1520_misc_resets, + .num = ARRAY_SIZE(th1520_misc_resets), +}; + +static const struct th1520_reset_data th1520_vi_reset_data = { + .resets = th1520_vi_resets, + .num = ARRAY_SIZE(th1520_vi_resets), +}; + +static const struct th1520_reset_data th1520_vp_reset_data = { + .resets = th1520_vp_resets, + .num = ARRAY_SIZE(th1520_vp_resets), +}; + static const struct of_device_id th1520_reset_match[] = { { .compatible = "thead,th1520-reset", .data = &th1520_reset_data }, + { .compatible = "thead,th1520-reset-ap", .data = &th1520_ap_reset_data }, + { .compatible = "thead,th1520-reset-dsp", .data = &th1520_dsp_reset_data }, + { .compatible = "thead,th1520-reset-misc", .data = &th1520_misc_reset_data }, + { .compatible = "thead,th1520-reset-vi", .data = &th1520_vi_reset_data }, + { .compatible = "thead,th1520-reset-vp", .data = &th1520_vp_reset_data }, { /* sentinel */ } }; MODULE_DEVICE_TABLE(of, th1520_reset_match); From cea5d43b63b221522f8532a7894149f3d8d11f4b Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Sat, 1 Nov 2025 16:27:07 +0300 Subject: [PATCH 111/114] reset: rzg2l-usbphy-ctrl: Fix a NULL vs IS_ERR() bug in probe The devm_regmap_field_alloc() function never returns NULL, it returns error pointers. Update the error checking to match. Fixes: 58128aa88867 ("reset: rzg2l-usbphy-ctrl: Add support for USB PWRRDY") Signed-off-by: Dan Carpenter Reviewed-by: Claudiu Beznea Signed-off-by: Philipp Zabel --- drivers/reset/reset-rzg2l-usbphy-ctrl.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/reset/reset-rzg2l-usbphy-ctrl.c b/drivers/reset/reset-rzg2l-usbphy-ctrl.c index eea56687cd0a..4ecb9acb2641 100644 --- a/drivers/reset/reset-rzg2l-usbphy-ctrl.c +++ b/drivers/reset/reset-rzg2l-usbphy-ctrl.c @@ -158,8 +158,8 @@ static int rzg2l_usbphy_ctrl_pwrrdy_init(struct device *dev) field.msb = __fls(args[1]); pwrrdy = devm_regmap_field_alloc(dev, regmap, field); - if (!pwrrdy) - return -ENOMEM; + if (IS_ERR(pwrrdy)) + return PTR_ERR(pwrrdy); rzg2l_usbphy_ctrl_set_pwrrdy(pwrrdy, true); From f3d8b64ee46c9b4b0b82b1a4642027728bac95b8 Mon Sep 17 00:00:00 2001 From: Encrow Thorne Date: Mon, 10 Nov 2025 14:10:37 +0800 Subject: [PATCH 112/114] reset: fix BIT macro reference RESET_CONTROL_FLAGS_BIT_* macros use BIT(), but reset.h does not include bits.h. This causes compilation errors when including reset.h standalone. Include bits.h to make reset.h self-contained. Suggested-by: Troy Mitchell Reviewed-by: Troy Mitchell Reviewed-by: Philipp Zabel Signed-off-by: Encrow Thorne Signed-off-by: Philipp Zabel --- include/linux/reset.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/linux/reset.h b/include/linux/reset.h index 840d75d172f6..44f9e3415f92 100644 --- a/include/linux/reset.h +++ b/include/linux/reset.h @@ -2,6 +2,7 @@ #ifndef _LINUX_RESET_H_ #define _LINUX_RESET_H_ +#include #include #include #include From 1387cb78f101553c7fc14ec04ba730cab03ea3df Mon Sep 17 00:00:00 2001 From: Yue Haibing Date: Fri, 14 Nov 2025 10:05:31 +0800 Subject: [PATCH 113/114] Documentation: reset: Remove reset_controller_add_lookup() Commit 205b261463ff ("reset: remove legacy reset lookup code") removed this api, so update the document. Signed-off-by: Yue Haibing Signed-off-by: Philipp Zabel --- Documentation/driver-api/reset.rst | 1 - 1 file changed, 1 deletion(-) diff --git a/Documentation/driver-api/reset.rst b/Documentation/driver-api/reset.rst index 84e03d7039cc..f773100daaa4 100644 --- a/Documentation/driver-api/reset.rst +++ b/Documentation/driver-api/reset.rst @@ -218,4 +218,3 @@ devm_reset_controller_register(). reset_controller_register reset_controller_unregister devm_reset_controller_register - reset_controller_add_lookup From 1463299a227d02b40c842a5d91d989cb26da5bbb Mon Sep 17 00:00:00 2001 From: Jon Hunter Date: Thu, 6 Nov 2025 19:05:50 +0000 Subject: [PATCH 114/114] memory: tegra186-emc: Fix missing put_bpmp Commit a52ddb98a674 ("memory: tegra186-emc: Simplify and handle deferred probe with dev_err_probe()") accidently dropped a call to 'put_bpmp' to release a handle to the BPMP when getting the EMC clock fails. Fix this by restoring the 'goto put_bpmp' if devm_clk_get() fails. Fixes: a52ddb98a674 ("memory: tegra186-emc: Simplify and handle deferred probe with dev_err_probe()") Signed-off-by: Jon Hunter Link: https://patch.msgid.link/20251106190550.1776974-1-jonathanh@nvidia.com Signed-off-by: Krzysztof Kozlowski --- drivers/memory/tegra/tegra186-emc.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/memory/tegra/tegra186-emc.c b/drivers/memory/tegra/tegra186-emc.c index 9959ad5804b4..dfddceecdd1a 100644 --- a/drivers/memory/tegra/tegra186-emc.c +++ b/drivers/memory/tegra/tegra186-emc.c @@ -322,9 +322,11 @@ static int tegra186_emc_probe(struct platform_device *pdev) "failed to get BPMP\n"); emc->clk = devm_clk_get(&pdev->dev, "emc"); - if (IS_ERR(emc->clk)) - return dev_err_probe(&pdev->dev, PTR_ERR(emc->clk), - "failed to get EMC clock\n"); + if (IS_ERR(emc->clk)) { + err = dev_err_probe(&pdev->dev, PTR_ERR(emc->clk), + "failed to get EMC clock\n"); + goto put_bpmp; + } platform_set_drvdata(pdev, emc); emc->dev = &pdev->dev;