From nobody Mon Feb 9 23:16:14 2026 Received: from mail-wm1-f54.google.com (mail-wm1-f54.google.com [209.85.128.54]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 633512DEA68 for ; Wed, 14 Jan 2026 14:17:17 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.54 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768400240; cv=none; b=e8QCD1AmT45bTre49xf2jvnDpjN/Ygqm2Fz7ZJfvnLOGxGmkbF2zCRAGg2l8He8CHefks2HTnLRENAvLq/vgvet9CTLuwO/lKSXqCflYK6g+EY6RxulJB7px2oW5lacEWiBgF9LFOLnSRfNifxnrnVsK62EUGpPbSTLky0UxevI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768400240; c=relaxed/simple; bh=scZVLwTECj4CGzumXSOMKU8Ox6ZHln+/s1mUJJlsDnc=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=VooGIFahJp2GuGsk9IThmAMq/ORKszxTOczwgmIl/TVrsLfPtDiz4rnI3s+YPAupkmwVee8SSinT8EsG3swTfpXBNOf/N42xvmm8V0QN9htr3X7wcEy9FrO+/bVNu03Rdp9oSvmygCy7il1ASa20I1OonAaavEyybJQsaOBE/Ck= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linaro.org; spf=pass smtp.mailfrom=linaro.org; dkim=pass (2048-bit key) header.d=linaro.org header.i=@linaro.org header.b=vyXj9OQx; arc=none smtp.client-ip=209.85.128.54 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linaro.org Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linaro.org header.i=@linaro.org header.b="vyXj9OQx" Received: by mail-wm1-f54.google.com with SMTP id 5b1f17b1804b1-4779a4fc95aso6097805e9.1 for ; Wed, 14 Jan 2026 06:17:17 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1768400236; x=1769005036; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=RUpc7tPcYauEJYqevhj0yziHsT/ZtjU3a5lZkEZyS1w=; b=vyXj9OQxuGNd3gMpdt5ywRHr+7FxdNcTSon0/pXhS6rznhF0WD27kBFhJc6tpExwXv pTZ3wwDSG0nesHCwIyuRPcWcuVL/IJylg+eUwQOghk2qjpMXkWquPqP23anm9L4UHrx9 GXt4W9fZkJ+KW0cHAmOlupXM+0j1gmbHxCBrrfnCGnLs270ot1ryP9SG1J3yXWFCeOig iVFleKwWWdIzc1dBCF/1EsNMrpYELNJcDrEjVBQvhk0kNbCGf3jPNUPx9SM8TilwDKlo HGso+57f+OXA+gxj3TtAaleOpdnECKG6KtfgVi/sLYkGbzJ05A+4DSobCQ7mfgvtCjIr UzaQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1768400236; x=1769005036; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=RUpc7tPcYauEJYqevhj0yziHsT/ZtjU3a5lZkEZyS1w=; b=mFlHb2aRal1VTZTp6410G4I4OrH52Xq7swcc4Exvuwct4KFN2JMLiT560sjTb8MU1z Zo2k2at1HAoELcAecVolV0TclDzm23mCZJMqLavq9z47tixTdEDPak6ukRhPPwR1RmFl qmb2mLBmKJra0A88sCl/TWpEw95iKGKHTO7od7d9qFRG60OIqYTAtT0X1pOq/OnDYR+0 z+XsEoLf+O6/izCDtS1ajt+swKWM/ijFhwOTYmR4PJveeX1BqGOwMP1kn8osZM0dn/wx ozjFf92boisuPCYvQkY39uSFs95e/nTCsYeF545noqrAa3t9pbEXPifx/lLuzU0fOhx5 M53A== X-Forwarded-Encrypted: i=1; AJvYcCX6eBGWjktu1GsFdoE3DLRosWQbiefj7h27Pe7jnvAmrymP38JuFnvfghYqNa0cH6S7gGLi1Qs5ZJPxuqI=@vger.kernel.org X-Gm-Message-State: AOJu0Yx7Ge/C5RL6uOjZC2/AJnBgA3hb85jyg347bJMXTo8Oi666ykzq ArXNrmywqJeseysnSBcmTBFxh0F8YLeNaVPTu48JBV4Y6B3pg47xEP2mH7/Htdyts9o= X-Gm-Gg: AY/fxX6h8LPHbHyx7bor5uyxq0WzhjYWOKTX0S5+GNPdLkiYjHpSyZfGQv9Zz2HdSTr 3qjgvEuTrp4gH+SVUkY/6tfGAwwdcjcl3a9hQjKigTpKTwtpaFAzwdAs2CkJDNgwblTGzLjCnhU gIJYYyqH26btuvNj7qkDacdy9uU//3XsaC9yBymoWJ8U01QnkZliQOaFq+ZVrXXNoeE+4u4keZh C1Kwz4HK/0cSA1EuMyPyj4wIgFaUJHDEQL4G2NEaFg+w9fyiGEqezHy42GATMCPkcC+7zvRIGzx xwY+e77Xqc5B0sw82GDm7KLpF+3TrN0pqZFZMgIzQGY3ZCYraPrDCxSlyHI9pWpfQ8LNMkpxJdg K9ww1831XMERDXyFYlhwJggmfBNWOfgiQhU00T5+gb3UE6gBTDz1jFEVmuOs876Zb+ibC0nxJ4o sZQwgGkH5mVxFyJYlBwhgknKDGgSwSzZNxnGYO6pHYeL/0Ut9EoIB+dHWGS1wnv/DF2HT3cA== X-Received: by 2002:a05:600c:747:b0:477:9d31:9f76 with SMTP id 5b1f17b1804b1-47ed7c284f3mr55537135e9.12.1768400235738; Wed, 14 Jan 2026 06:17:15 -0800 (PST) Received: from ta2.c.googlers.com (164.102.240.35.bc.googleusercontent.com. [35.240.102.164]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-47ee57a2613sm29595445e9.6.2026.01.14.06.17.14 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 14 Jan 2026 06:17:14 -0800 (PST) From: Tudor Ambarus Date: Wed, 14 Jan 2026 14:16:32 +0000 Subject: [PATCH 4/8] firmware: samsung: acpm: Add TMU protocol support Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260114-acpm-tmu-v1-4-cfe56d93e90f@linaro.org> References: <20260114-acpm-tmu-v1-0-cfe56d93e90f@linaro.org> In-Reply-To: <20260114-acpm-tmu-v1-0-cfe56d93e90f@linaro.org> To: "Rafael J. Wysocki" , Daniel Lezcano , Zhang Rui , Lukasz Luba , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Lee Jones , Krzysztof Kozlowski , Alim Akhtar , Peter Griffin , =?utf-8?q?Andr=C3=A9_Draszik?= , Bartlomiej Zolnierkiewicz , Kees Cook , "Gustavo A. R. Silva" Cc: willmcvicker@google.com, jyescas@google.com, shin.son@samsung.com, linux-pm@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-samsung-soc@vger.kernel.org, linux-hardening@vger.kernel.org, Tudor Ambarus X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1768400224; l=11917; i=tudor.ambarus@linaro.org; s=20241212; h=from:subject:message-id; bh=scZVLwTECj4CGzumXSOMKU8Ox6ZHln+/s1mUJJlsDnc=; b=5mBrS0mafIwBfkzAx7jh6ZJxc7p3Byf+AqDcw5Ue/nSlE+ZkDs76evSOIhSrOHLU1kRnnU0Oc B2lX0e++yktClE8dn7EwV6KxxKpjWxAEcl8FGBqCsiOlyY9Yx+lm++m X-Developer-Key: i=tudor.ambarus@linaro.org; a=ed25519; pk=uQzE0NXo3dIjeowMTOPCpIiPHEz12IA/MbyzrZVh9WI= The Thermal Management Unit (TMU) on Google GS101 SoC is primarily managed by the Alive Clock and Power Manager (ACPM) firmware. Add the protocol helpers required to communicate with the ACPM for thermal operations, including initialization, threshold configuration, temperature reading, and system suspend/resume handshakes. This architecture requires a split responsibility between the kernel and firmware. While the kernel can read the interrupt pending status directly via a syscon interface (for low-latency sensor identification), it shall not write to the status registers directly. Instead, the kernel must issue an ACPM IPC request (`ACPM_TMU_IRQ_CLEAR`) to acknowledge and clear the interrupt, ensuring the firmware's internal state machine remains synchronized. Signed-off-by: Tudor Ambarus --- drivers/firmware/samsung/Makefile | 1 + drivers/firmware/samsung/exynos-acpm-tmu.c | 212 +++++++++++++++++= ++++ drivers/firmware/samsung/exynos-acpm-tmu.h | 33 ++++ drivers/firmware/samsung/exynos-acpm.c | 12 ++ .../linux/firmware/samsung/exynos-acpm-protocol.h | 24 +++ 5 files changed, 282 insertions(+) diff --git a/drivers/firmware/samsung/Makefile b/drivers/firmware/samsung/M= akefile index 80d4f89b33a9558b68c9083da675c70ec3d05f19..5a6f72bececfd98ba5af37d1d65= fed48a3d8f912 100644 --- a/drivers/firmware/samsung/Makefile +++ b/drivers/firmware/samsung/Makefile @@ -3,4 +3,5 @@ acpm-protocol-objs :=3D exynos-acpm.o acpm-protocol-objs +=3D exynos-acpm-pmic.o acpm-protocol-objs +=3D exynos-acpm-dvfs.o +acpm-protocol-objs +=3D exynos-acpm-tmu.o obj-$(CONFIG_EXYNOS_ACPM_PROTOCOL) +=3D acpm-protocol.o diff --git a/drivers/firmware/samsung/exynos-acpm-tmu.c b/drivers/firmware/= samsung/exynos-acpm-tmu.c new file mode 100644 index 0000000000000000000000000000000000000000..7ec4b48074eb8b4e569b39d4bb5= 963d887aa9521 --- /dev/null +++ b/drivers/firmware/samsung/exynos-acpm-tmu.c @@ -0,0 +1,212 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright 2020 Samsung Electronics Co., Ltd. + * Copyright 2020 Google LLC. + * Copyright 2026 Linaro Ltd. + */ + +#include +#include +#include +#include +#include +#include + +#include "exynos-acpm.h" +#include "exynos-acpm-tmu.h" + +/* IPC Request Types */ +#define ACPM_TMU_INIT 0x01 +#define ACPM_TMU_READ_TEMP 0x02 +#define ACPM_TMU_SUSPEND 0x04 +#define ACPM_TMU_RESUME 0x10 +#define ACPM_TMU_THRESHOLD 0x11 +#define ACPM_TMU_INTEN 0x12 +#define ACPM_TMU_CONTROL 0x13 +#define ACPM_TMU_IRQ_CLEAR 0x14 +#define ACPM_TMU_HYSTERESIS 0x16 + +#define ACPM_TMU_TX_DATA_LEN 8 +#define ACPM_TMU_RX_DATA_LEN 7 + +struct acpm_tmu_tx { + u16 ctx; + u16 fw_use; + u8 type; + u8 rsvd0; + u8 tzid; + u8 rsvd1; + u8 data[ACPM_TMU_TX_DATA_LEN]; +} __packed; + +struct acpm_tmu_rx { + u16 ctx; + u16 fw_use; + u8 type; + s8 ret; + u8 tzid; + s8 temp; + u8 rsvd; + u8 data[ACPM_TMU_RX_DATA_LEN]; +} __packed; + +union acpm_tmu_msg { + u32 data[4]; + struct acpm_tmu_tx tx; + struct acpm_tmu_rx rx; +} __packed; + +static void acpm_tmu_set_xfer(struct acpm_xfer *xfer, u32 *cmd, size_t cmd= len, + unsigned int acpm_chan_id) +{ + xfer->acpm_chan_id =3D acpm_chan_id; + xfer->txd =3D cmd; + xfer->txlen =3D cmdlen; + xfer->rxd =3D cmd; + xfer->rxlen =3D cmdlen; +} + +int acpm_tmu_init(const struct acpm_handle *handle, unsigned int acpm_chan= _id) +{ + union acpm_tmu_msg msg =3D {0}; + struct acpm_xfer xfer; + + msg.tx.type =3D ACPM_TMU_INIT; + acpm_tmu_set_xfer(&xfer, msg.data, sizeof(msg.data), acpm_chan_id); + + return acpm_do_xfer(handle, &xfer); +} + +int acpm_tmu_read_temp(const struct acpm_handle *handle, + unsigned int acpm_chan_id, u8 tz, int *temp) +{ + union acpm_tmu_msg msg =3D {0}; + struct acpm_xfer xfer; + int ret; + + msg.tx.type =3D ACPM_TMU_READ_TEMP; + msg.tx.tzid =3D tz; + + acpm_tmu_set_xfer(&xfer, msg.data, sizeof(msg.data), acpm_chan_id); + + ret =3D acpm_do_xfer(handle, &xfer); + if (ret) + return ret; + + *temp =3D msg.rx.temp; + + return 0; +} + +int acpm_tmu_set_threshold(const struct acpm_handle *handle, + unsigned int acpm_chan_id, u8 tz, + const u8 temperature[8], size_t tlen) +{ + union acpm_tmu_msg msg =3D {0}; + struct acpm_xfer xfer; + int i; + + if (tlen > ACPM_TMU_TX_DATA_LEN) + return -EINVAL; + + msg.tx.type =3D ACPM_TMU_THRESHOLD; + msg.tx.tzid =3D tz; + + for (i =3D 0; i < tlen; i++) + msg.tx.data[i] =3D temperature[i]; + + acpm_tmu_set_xfer(&xfer, msg.data, sizeof(msg.data), acpm_chan_id); + + return acpm_do_xfer(handle, &xfer); +} + +int acpm_tmu_set_hysteresis(const struct acpm_handle *handle, + unsigned int acpm_chan_id, u8 tz, + const u8 hysteresis[8], size_t hlen) +{ + union acpm_tmu_msg msg =3D {0}; + struct acpm_xfer xfer; + int i; + + if (hlen > ACPM_TMU_TX_DATA_LEN) + return -EINVAL; + + msg.tx.type =3D ACPM_TMU_HYSTERESIS; + msg.tx.tzid =3D tz; + + for (i =3D 0; i < hlen; i++) + msg.tx.data[i] =3D hysteresis[i]; + + acpm_tmu_set_xfer(&xfer, msg.data, sizeof(msg.data), acpm_chan_id); + + return acpm_do_xfer(handle, &xfer); +} + +int acpm_tmu_set_interrupt_enable(const struct acpm_handle *handle, + unsigned int acpm_chan_id, u8 tz, u8 inten) +{ + union acpm_tmu_msg msg =3D {0}; + struct acpm_xfer xfer; + + msg.tx.type =3D ACPM_TMU_INTEN; + msg.tx.tzid =3D tz; + msg.tx.data[0] =3D inten; + + acpm_tmu_set_xfer(&xfer, msg.data, sizeof(msg.data), acpm_chan_id); + + return acpm_do_xfer(handle, &xfer); +} + +int acpm_tmu_tz_control(const struct acpm_handle *handle, + unsigned int acpm_chan_id, u8 tz, bool enable) +{ + union acpm_tmu_msg msg =3D {0}; + struct acpm_xfer xfer; + + msg.tx.type =3D ACPM_TMU_CONTROL; + msg.tx.tzid =3D tz; + msg.tx.data[0] =3D enable ? 1 : 0; + + acpm_tmu_set_xfer(&xfer, msg.data, sizeof(msg.data), acpm_chan_id); + + return acpm_do_xfer(handle, &xfer); +} + +int acpm_tmu_clear_tz_irq(const struct acpm_handle *handle, + unsigned int acpm_chan_id, u8 tz) +{ + union acpm_tmu_msg msg =3D {0}; + struct acpm_xfer xfer; + + msg.tx.type =3D ACPM_TMU_IRQ_CLEAR; + msg.tx.tzid =3D tz; + + acpm_tmu_set_xfer(&xfer, msg.data, sizeof(msg.data), acpm_chan_id); + + return acpm_do_xfer(handle, &xfer); +} + +int acpm_tmu_suspend(const struct acpm_handle *handle, + unsigned int acpm_chan_id) +{ + union acpm_tmu_msg msg =3D {0}; + struct acpm_xfer xfer; + + msg.tx.type =3D ACPM_TMU_SUSPEND; + + acpm_tmu_set_xfer(&xfer, msg.data, sizeof(msg.data), acpm_chan_id); + + return acpm_do_xfer(handle, &xfer); +} + +int acpm_tmu_resume(const struct acpm_handle *handle, unsigned int acpm_ch= an_id) +{ + union acpm_tmu_msg msg =3D {0}; + struct acpm_xfer xfer; + + msg.tx.type =3D ACPM_TMU_RESUME; + + acpm_tmu_set_xfer(&xfer, msg.data, sizeof(msg.data), acpm_chan_id); + + return acpm_do_xfer(handle, &xfer); +} diff --git a/drivers/firmware/samsung/exynos-acpm-tmu.h b/drivers/firmware/= samsung/exynos-acpm-tmu.h new file mode 100644 index 0000000000000000000000000000000000000000..f1a1ac21736d52bea0ad2a7cb3b= 280201fa74ffe --- /dev/null +++ b/drivers/firmware/samsung/exynos-acpm-tmu.h @@ -0,0 +1,33 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright 2020 Samsung Electronics Co., Ltd. + * Copyright 2020 Google LLC. + * Copyright 2026 Linaro Ltd. + */ +#ifndef __EXYNOS_ACPM_TMU_H__ +#define __EXYNOS_ACPM_TMU_H__ + +#include + +struct acpm_handle; + +int acpm_tmu_init(const struct acpm_handle *handle, unsigned int acpm_chan= _id); +int acpm_tmu_read_temp(const struct acpm_handle *handle, + unsigned int acpm_chan_id, u8 tz, int *temp); +int acpm_tmu_set_threshold(const struct acpm_handle *handle, + unsigned int acpm_chan_id, u8 tz, + const u8 temperature[8], size_t tlen); +int acpm_tmu_set_hysteresis(const struct acpm_handle *handle, + unsigned int acpm_chan_id, u8 tz, + const u8 hysteresis[8], size_t hlen); +int acpm_tmu_set_interrupt_enable(const struct acpm_handle *handle, + unsigned int acpm_chan_id, u8 tz, u8 inten); +int acpm_tmu_tz_control(const struct acpm_handle *handle, + unsigned int acpm_chan_id, u8 tz, bool enable); +int acpm_tmu_clear_tz_irq(const struct acpm_handle *handle, + unsigned int acpm_chan_id, u8 tz); +int acpm_tmu_suspend(const struct acpm_handle *handle, + unsigned int acpm_chan_id); +int acpm_tmu_resume(const struct acpm_handle *handle, + unsigned int acpm_chan_id); +#endif /* __EXYNOS_ACPM_TMU_H__ */ diff --git a/drivers/firmware/samsung/exynos-acpm.c b/drivers/firmware/sams= ung/exynos-acpm.c index 0cb269c7046015d4c5fe5731ba0d61d48dcaeee1..cc045370f4b0dc6ccea99e3c2d6= f86a43b2e9671 100644 --- a/drivers/firmware/samsung/exynos-acpm.c +++ b/drivers/firmware/samsung/exynos-acpm.c @@ -31,6 +31,7 @@ #include "exynos-acpm.h" #include "exynos-acpm-dvfs.h" #include "exynos-acpm-pmic.h" +#include "exynos-acpm-tmu.h" =20 #define ACPM_PROTOCOL_SEQNUM GENMASK(21, 16) =20 @@ -595,6 +596,7 @@ static void acpm_setup_ops(struct acpm_info *acpm) { struct acpm_dvfs_ops *dvfs_ops =3D &acpm->handle.ops.dvfs_ops; struct acpm_pmic_ops *pmic_ops =3D &acpm->handle.ops.pmic_ops; + struct acpm_tmu_ops *tmu_ops =3D &acpm->handle.ops.tmu; =20 dvfs_ops->set_rate =3D acpm_dvfs_set_rate; dvfs_ops->get_rate =3D acpm_dvfs_get_rate; @@ -604,6 +606,16 @@ static void acpm_setup_ops(struct acpm_info *acpm) pmic_ops->write_reg =3D acpm_pmic_write_reg; pmic_ops->bulk_write =3D acpm_pmic_bulk_write; pmic_ops->update_reg =3D acpm_pmic_update_reg; + + tmu_ops->init =3D acpm_tmu_init; + tmu_ops->read_temp =3D acpm_tmu_read_temp; + tmu_ops->set_threshold =3D acpm_tmu_set_threshold; + tmu_ops->set_hysteresis =3D acpm_tmu_set_hysteresis; + tmu_ops->set_interrupt_enable =3D acpm_tmu_set_interrupt_enable; + tmu_ops->tz_control =3D acpm_tmu_tz_control; + tmu_ops->clear_tz_irq =3D acpm_tmu_clear_tz_irq; + tmu_ops->suspend =3D acpm_tmu_suspend; + tmu_ops->resume =3D acpm_tmu_resume; } =20 static void acpm_clk_pdev_unregister(void *data) diff --git a/include/linux/firmware/samsung/exynos-acpm-protocol.h b/includ= e/linux/firmware/samsung/exynos-acpm-protocol.h index 2091da965a5ad238b5e16c567a72fe88fafe6095..43d41e11ad2eb985e27a918ce3f= 9e9ac15a194ee 100644 --- a/include/linux/firmware/samsung/exynos-acpm-protocol.h +++ b/include/linux/firmware/samsung/exynos-acpm-protocol.h @@ -40,9 +40,33 @@ struct acpm_pmic_ops { u8 value, u8 mask); }; =20 +struct acpm_tmu_ops { + int (*init)(const struct acpm_handle *handle, + unsigned int acpm_chan_id); + int (*read_temp)(const struct acpm_handle *handle, + unsigned int acpm_chan_id, u8 tz, int *temp); + int (*set_threshold)(const struct acpm_handle *handle, + unsigned int acpm_chan_id, u8 tz, + const u8 temperature[8], size_t tlen); + int (*set_hysteresis)(const struct acpm_handle *handle, + unsigned int acpm_chan_id, u8 tz, + const u8 hysteresis[8], size_t hlen); + int (*set_interrupt_enable)(const struct acpm_handle *handle, + unsigned int acpm_chan_id, u8 tz, u8 inten); + int (*tz_control)(const struct acpm_handle *handle, + unsigned int acpm_chan_id, u8 tz, bool enable); + int (*clear_tz_irq)(const struct acpm_handle *handle, + unsigned int acpm_chan_id, u8 tz); + int (*suspend)(const struct acpm_handle *handle, + unsigned int acpm_chan_id); + int (*resume)(const struct acpm_handle *handle, + unsigned int acpm_chan_id); +}; + struct acpm_ops { struct acpm_dvfs_ops dvfs_ops; struct acpm_pmic_ops pmic_ops; + struct acpm_tmu_ops tmu; }; =20 /** --=20 2.52.0.457.g6b5491de43-goog