From nobody Tue Feb 10 19:14:46 2026 Received: from mail-wm1-f45.google.com (mail-wm1-f45.google.com [209.85.128.45]) (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 4EB823590DA for ; Mon, 19 Jan 2026 12:08:56 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.45 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768824540; cv=none; b=F5iS2+TI9/aoan7wTyBwHBHkKcKehe4ZtTeT9FZiCHRlB/+L5EOnWjut0UHzYevakYhKlRHIYS1CCnQ4fJmT5eO89BsV93xme7BlLYaXjJdB/aQpk4Tljv20gn7nZY/h+lgoa4tIHl4a0A0dZtzSHzfG8vooeCpTUzyal+n57mM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768824540; c=relaxed/simple; bh=xm2Bk0tp2/dYXXAn7n3eVAFPnJF+Lc6bvpH8padRGcg=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=Fd73v/Eo71vCpGo9uB2qc4nb5Koo6fTv4J7H1ADcA0fiiNWf9TAZcnk5deU7LeGA/yQmdbkoS5o+xD3vzkEE0ibXjUWcrxM2WBKh/8HJlN/CJ3FFCdqTzNyqPMiDaVGvkzfsh6JOvgBcYznAdfFPlbGpvmcmCh6X0mRnKa/maME= 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=bDaDpHod; arc=none smtp.client-ip=209.85.128.45 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="bDaDpHod" Received: by mail-wm1-f45.google.com with SMTP id 5b1f17b1804b1-47ee07570deso28162025e9.1 for ; Mon, 19 Jan 2026 04:08:56 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1768824534; x=1769429334; 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=ylfAjxpOUxlcbMBmHFNtPCkWSO4scZYP0qkSe//RiXk=; b=bDaDpHodg/dQSlTPwJwQ/1Bnrq4HBx7QlMrWdmEsnWmBdzegxiG3yE4xqYTgxQSwvO 45BCEmuTONx4/vZLL/STWc9WIP2MYa7w+JfvMW+0mJWX5r9/5cp8771wZ7itYIy1GefE 6UUK826AWUcFoMhGwrBjs0AU5eYUACNiNpdVy6h7OwHbblnDWkszvQ2AGkRl/q20FLVt ++ytKO4VPUe7ILrfLaKGlKSWYltcpatk4z4U+nuegNb3Jx+fxlNNABpA5mtQ294z56HN hTqFe1tOeHoYaJh39mgxCTgEfZuF/dKb7TGSQBO0N9JMZGabGatsw2ePu9h9i5SyL4QD 0rHg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1768824534; x=1769429334; 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=ylfAjxpOUxlcbMBmHFNtPCkWSO4scZYP0qkSe//RiXk=; b=vDesNQR+esnb0FbRkFXaMd8zBKK7/EME7sNQdBT2DjRXcdTT37drLs9BmLGAo5frVh QZml0QfVYSPYzxAtN1zi6P0lWQTfIJuAHC4fCVybs5zNn9C8dWMicrzppHz8V2X1JZio ROR2S8OD3RP8ZnU9apsdnwz4OxQ3sOrTeeQFKOtwVOrzuV/lz/Wx1ByHu+W26CPrJN/j aVSaTCnbHwygfvVTXeZX5TNGvzzi0y5d1YyhAdoTHMCZISghPzPD37HzDWn/V1AmXwGp nlu/r3D3Jme6ekHCkO3qhCe+8o3HdLwMqq5osNNNfrqYe4wlnxCA5dFENYtLAc5iFZIN I9xQ== X-Forwarded-Encrypted: i=1; AJvYcCUe9BwOIG0+mWTS3N5GdMsw+Pzu8BkZ4pw6sGk3DygaS0ZY5jQ8g2+q4JJpq4XyP5qfFeFmN6CCwpSo5I8=@vger.kernel.org X-Gm-Message-State: AOJu0Yx4G0kkaf/lVkgZNeEe9P5K3oCIGAxdqqIiY2uKRLLxSKlbLV0i btdw5nmACFkjEctVZwLpsFPgOEOOeccCFP7EPTBX1nqG+dCvgvHzn3XTRfV0GqoMNpI= X-Gm-Gg: AY/fxX7GorxS1FVuJ2gsjaAggxQcVwEGRQ7T8gPi9VwcYnPkGwc/mKBVTijFRtmoqrk 1oxeZ8dSNrGMsjySjp8j26COpMwDKks0SEJU7UB9zNYXKYertvV8pNiY/uD1KwcxGZPOzYz5Cav SyBtKswrbPROWKIChxrpQJEt4kqN/wvq1wBe8K0NrYzyBMCPwbNDV03egKA+vTXK8n0kKpWiesY FFiHcXJPKOJEHkcnN25fqT2bFkZ+ci/1X0z1RS9XESRQGV2/cETxdzPeiW22w9bVAcEIsaptALz sX+pXaew/Yh24GcKkqTrt1//Yq96U101V6uy56dAo8GFcYxP+rLnzB681vZP/uHT+eyT5bbIxdq oDJn7DcxX+RzGZguiqgeozrYi3qxSWE4vc05MpfTonYxKOJpxQsq9+YgQm+m43TMnaOHguMFboR gOOCYm2EUdYCgOq17HZK/JyoXT9ido94sNqdCAchKBQpUhcl9cHn7RssGG5uGkMbDC+CIxRxpPa PsDkLTf X-Received: by 2002:a05:600c:1c28:b0:45d:f81d:eae7 with SMTP id 5b1f17b1804b1-4801eb109e0mr130549215e9.28.1768824534313; Mon, 19 Jan 2026 04:08:54 -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 ffacd0b85a97d-4356997e664sm20698421f8f.30.2026.01.19.04.08.53 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 19 Jan 2026 04:08:53 -0800 (PST) From: Tudor Ambarus Date: Mon, 19 Jan 2026 12:08:48 +0000 Subject: [PATCH v2 2/7] 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: <20260119-acpm-tmu-v2-2-e02a834f04c6@linaro.org> References: <20260119-acpm-tmu-v2-0-e02a834f04c6@linaro.org> In-Reply-To: <20260119-acpm-tmu-v2-0-e02a834f04c6@linaro.org> To: "Rafael J. Wysocki" , Daniel Lezcano , Zhang Rui , Lukasz Luba , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Krzysztof Kozlowski , Alim Akhtar , Bartlomiej Zolnierkiewicz , Kees Cook , "Gustavo A. R. Silva" , Peter Griffin , =?utf-8?q?Andr=C3=A9_Draszik?= Cc: willmcvicker@google.com, jyescas@google.com, shin.son@samsung.com, linux-samsung-soc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-pm@vger.kernel.org, devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-hardening@vger.kernel.org, Tudor Ambarus X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1768824532; l=11506; i=tudor.ambarus@linaro.org; s=20241212; h=from:subject:message-id; bh=xm2Bk0tp2/dYXXAn7n3eVAFPnJF+Lc6bvpH8padRGcg=; b=rK0SJyctMob1vdqVS1D3IM9jdQOu7BrB06o+UuhUxD6Fa9dPj+HX2X3tOmK6b3Z9riwIfmBH8 25iPEkXpzD/Ccb0PKShVmQz+ixWvGYzX5PWtpZj5zVaHXf8pMfbSn/E X-Developer-Key: i=tudor.ambarus@linaro.org; a=ed25519; pk=uQzE0NXo3dIjeowMTOPCpIiPHEz12IA/MbyzrZVh9WI= The Thermal Management Unit (TMU) on the Google GS101 SoC is managed through a hybrid model shared between the kernel and 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. 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