From nobody Fri Jul 24 21:27:34 2026 Received: from mail-pj1-f45.google.com (mail-pj1-f45.google.com [209.85.216.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 28AA1440A11 for ; Fri, 24 Jul 2026 20:13:59 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.216.45 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784924048; cv=none; b=ngn9Yckl4JyKHDekE1dxFuUvNPAxed8B9+OCXNjxHSdqoBuGayZN0AeY0iDkKcB1IVLen89UBweJDPO6dgeAO70Xjgz1n53nf6GJbT/EsKvIP7Rl5gT+5NITpZvdW6tMBU7XEmBC+PA0gQU/oM0rqnRNXqGAzXcIHx4oK8utseU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784924048; c=relaxed/simple; bh=3BfKO1lcycbbs7e5gsWvcpH4V/zivQXN//VhP15u6gE=; h=From:To:Cc:Subject:Date:Message-ID:MIME-Version; b=AuMebXkcranOS8y3YNpU01q+tzNBiEODDzTD2buEjWRbwQEpA30VEM74pKFL7NvxtG4JfT8jkru0q5wW+k58V8lk1kYjT69ARcVeuzxg3pszmbPDreqNU+rNjaJkl1g9uC8k+Ry+xlXSC2cGRLUUvOeZmvjshvXfO2E2Gq0UHe8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=HP7OApoT; arc=none smtp.client-ip=209.85.216.45 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="HP7OApoT" Received: by mail-pj1-f45.google.com with SMTP id 98e67ed59e1d1-38de840f2f0so733803a91.0 for ; Fri, 24 Jul 2026 13:13:58 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1784924036; x=1785528836; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to:content-type; bh=b3eDk2AKIB7oouamFfigrUPQRcoPts0plkwt9xT+u6Y=; b=HP7OApoT2OWXpFlZQCF7vkjYBdG3UPiJBC15wC2EJ7tm4tpfxjbcsaTkXLKFVXw0g5 pJg84og/I19NriexFU7VRl/ha/LI7dcmJGgLM2cUf7Ugata2cq1qyNCojlEVbdv4i+bz rUrS7A/eXi1jOP4/EaRsa5DojDidraJrDRrFEMt0fGUH6WjZvd37Sv3ic2U9WWwLHLf9 2Y9WJKBH1+lkc7DHLWeFAECdcROe91ZQyLI9z4iE5Y5Q/QfPfLD2xNDoJNhIizP557OJ vzFf2I5T1095SJzpKyNJws+XKgWQ23uk2vbjV7FSliVYPMXC+0EX43knBCeE2nUkVyei q1xg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1784924036; x=1785528836; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-gg:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to:content-type; bh=b3eDk2AKIB7oouamFfigrUPQRcoPts0plkwt9xT+u6Y=; b=h/gajIQUOV54dJilfgdYb74SChAHWIkrn/ViPyQbNIDVK+vj1wc8q1s6TOdc/5syV2 LF89JtTenLFgz3h87s4444hXu2z/mhXAOc1NCsf1yfPKopZx0HfEBanPfb72MTpOHRQ6 Jwu6r99bji/urrhEUdVkaw935hd8oDiA1Yph5bydoDaeTmn8zqLg2PvX4+Vp9saN6rbR dzrmqrN9fxgRfWImSP/VbtW568LUzrV/DVfhDoz+h9fAGxBTdsadR0ahXDp9mRXlLVel wHpUfR1Tfxmp6+lfL6so6GacVj8x75nL2zyOrVBdvXVB9M4u1fCp/ai3ffMJ2ZLBWxEV LUjw== X-Gm-Message-State: AOJu0YzdLS/MraKXN76Phv7J5tes3oBKYu3D6I1Nf0M5bXnSSRrGnrJp P/aOn+kJd05qv69N2LdE1HCaWtgOmaj3NppRSJKfx3NpTuqHrWnkYyx/ X-Gm-Gg: AR+sD13a7NwfjzcWRyl8FFmKU0xsiCWNt911NIWnJahdi5S+xMbwjrBN4DLpFzdEN2b DR1oJ1h4onD+OGLHOHqBIpzFxMB6xUzEBthVk07URc+V8Od3u213S8lPr/0w1B6jcliJxpUcQwC Gp21YygRE3Z9rfj+iQzP0KNKhFWGCM6KMJTVfosNOd37fy/EU/n/b0aBJCLP743styVMN1r5nwR DYJbzISaoS0wgiCekUlQWHRQ8g9GHXPWzcHMoxCU/gCsQDoxuPBcuAV/6EwQU5ksf5MzngXYo65 q5MmQEPnHeYYTGqdKuXWWapeEGDGhf0Tp0g1oeAZv32UhDZQICoB8ra62gShNWGGIIB07Egb/bq SKoVQ9Jka1m8YdZSjvdMkGOOKaCXcrBhqQG+YVI3h2Tesncdjdcg7pyn3rg9RhgwwMq6ofpCOGZ I9Jee6C+T6xTm+0vefrvO9Y6BkN50gUeCSWre2UFQ8eqSDzj3OO50= X-Received: by 2002:a17:90b:568b:b0:38e:7d77:2fbb with SMTP id 98e67ed59e1d1-38ec6631f60mr8543951a91.32.1784924036263; Fri, 24 Jul 2026 13:13:56 -0700 (PDT) Received: from fabio-X870-EAGLE-WIFI7.. ([2804:1b3:a801:60b4:ddf8:a4ba:150b:5c93]) by smtp.gmail.com with ESMTPSA id a92af1059eb24-13d130158c0sm28850203c88.6.2026.07.24.13.13.54 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 24 Jul 2026 13:13:55 -0700 (PDT) From: Fabio Estevam To: broonie@kernel.org Cc: linux-kernel@vger.kernel.org, imx@lists.linux.dev, Fabio Estevam Subject: [PATCH] regulator: pca9450: Support regulator-off-in-suspend Date: Fri, 24 Jul 2026 17:13:22 -0300 Message-ID: <20260724201322.73937-1-festevam@gmail.com> X-Mailer: git-send-email 2.43.0 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Fabio Estevam The PCA9450 uses each regulator's ENMODE field to control whether the regulator remains enabled when the PMIC transitions from RUN to STANDBY mode. The driver does not currently implement set_suspend_disable(), so a regulator configured with regulator-off-in-suspend remains enabled during system suspend. Implement set_suspend_disable() for the buck regulators and LDO3-LDO5 by programming ENMODE to 10b. This keeps the regulator enabled in RUN mode, turns it off when PMIC_STBY_REQ is asserted, and enables it again when the PMIC returns to RUN mode. Keep LDO1 and LDO2 on regulator operations without set_suspend_disable(), because these regulators supply the SNVS domain and must remain enabled in STANDBY mode. Measured on a custom i.MX8MP board, turning off NVCC_SD2 (LDO5) during system suspend reduced power consumption by approximately 64 mW. Signed-off-by: Fabio Estevam --- drivers/regulator/pca9450-regulator.c | 43 +++++++++++++++++++++++---- include/linux/regulator/pca9450.h | 3 ++ 2 files changed, 40 insertions(+), 6 deletions(-) diff --git a/drivers/regulator/pca9450-regulator.c b/drivers/regulator/pca9= 450-regulator.c index c41db70fa052..13082585140f 100644 --- a/drivers/regulator/pca9450-regulator.c +++ b/drivers/regulator/pca9450-regulator.c @@ -77,6 +77,24 @@ static const unsigned int pca9450_dvs_buck_ramp_table[] = =3D { 25000, 12500, 6250, 3125 }; =20 +/* + * ENMODE =3D 10b keeps the regulator enabled in RUN mode and disables it + * while PMIC_STBY_REQ is asserted. + */ +static int pca9450_buck_set_suspend_disable(struct regulator_dev *rdev) +{ + return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg, + rdev->desc->enable_mask, + BUCK_ENMODE_ONREQ_STBYREQ); +} + +static int pca9450_ldo_set_suspend_disable(struct regulator_dev *rdev) +{ + return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg, + rdev->desc->enable_mask, + LDO_ENMODE_ONREQ_STBYREQ); +} + static const struct regulator_ops pca9450_dvs_buck_regulator_ops =3D { .enable =3D regulator_enable_regmap, .disable =3D regulator_disable_regmap, @@ -88,6 +106,7 @@ static const struct regulator_ops pca9450_dvs_buck_regul= ator_ops =3D { .set_ramp_delay =3D regulator_set_ramp_delay_regmap, .set_mode =3D pca9450_buck_set_mode, .get_mode =3D pca9450_buck_get_mode, + .set_suspend_disable =3D pca9450_buck_set_suspend_disable, }; =20 static const struct regulator_ops pca9450_buck_regulator_ops =3D { @@ -100,6 +119,7 @@ static const struct regulator_ops pca9450_buck_regulato= r_ops =3D { .set_voltage_time_sel =3D regulator_set_voltage_time_sel, .set_mode =3D pca9450_buck_set_mode, .get_mode =3D pca9450_buck_get_mode, + .set_suspend_disable =3D pca9450_buck_set_suspend_disable, }; =20 static const struct regulator_ops pca9450_ldo_regulator_ops =3D { @@ -111,6 +131,16 @@ static const struct regulator_ops pca9450_ldo_regulato= r_ops =3D { .get_voltage_sel =3D regulator_get_voltage_sel_regmap, }; =20 +static const struct regulator_ops pca9450_ldo_suspend_regulator_ops =3D { + .enable =3D regulator_enable_regmap, + .disable =3D regulator_disable_regmap, + .is_enabled =3D regulator_is_enabled_regmap, + .list_voltage =3D regulator_list_voltage_linear_range, + .set_voltage_sel =3D regulator_set_voltage_sel_regmap, + .get_voltage_sel =3D regulator_get_voltage_sel_regmap, + .set_suspend_disable =3D pca9450_ldo_set_suspend_disable, +}; + static unsigned int pca9450_ldo5_get_reg_voltage_sel(struct regulator_dev = *rdev) { struct pca9450 *pca9450 =3D rdev_get_drvdata(rdev); @@ -164,6 +194,7 @@ static const struct regulator_ops pca9450_ldo5_regulato= r_ops =3D { .list_voltage =3D regulator_list_voltage_linear_range, .set_voltage_sel =3D pca9450_ldo5_set_voltage_sel_regmap, .get_voltage_sel =3D pca9450_ldo5_get_voltage_sel_regmap, + .set_suspend_disable =3D pca9450_ldo_set_suspend_disable, }; =20 /* @@ -575,7 +606,7 @@ static struct pca9450_regulator_desc pca9450a_regulator= s[] =3D { .of_match =3D of_match_ptr("LDO3"), .regulators_node =3D of_match_ptr("regulators"), .id =3D PCA9450_LDO3, - .ops =3D &pca9450_ldo_regulator_ops, + .ops =3D &pca9450_ldo_suspend_regulator_ops, .type =3D REGULATOR_VOLTAGE, .n_voltages =3D PCA9450_LDO3_VOLTAGE_NUM, .linear_ranges =3D pca9450_ldo34_volts, @@ -594,7 +625,7 @@ static struct pca9450_regulator_desc pca9450a_regulator= s[] =3D { .of_match =3D of_match_ptr("LDO4"), .regulators_node =3D of_match_ptr("regulators"), .id =3D PCA9450_LDO4, - .ops =3D &pca9450_ldo_regulator_ops, + .ops =3D &pca9450_ldo_suspend_regulator_ops, .type =3D REGULATOR_VOLTAGE, .n_voltages =3D PCA9450_LDO4_VOLTAGE_NUM, .linear_ranges =3D pca9450_ldo34_volts, @@ -820,7 +851,7 @@ static struct pca9450_regulator_desc pca9450bc_regulato= rs[] =3D { .of_match =3D of_match_ptr("LDO3"), .regulators_node =3D of_match_ptr("regulators"), .id =3D PCA9450_LDO3, - .ops =3D &pca9450_ldo_regulator_ops, + .ops =3D &pca9450_ldo_suspend_regulator_ops, .type =3D REGULATOR_VOLTAGE, .n_voltages =3D PCA9450_LDO3_VOLTAGE_NUM, .linear_ranges =3D pca9450_ldo34_volts, @@ -839,7 +870,7 @@ static struct pca9450_regulator_desc pca9450bc_regulato= rs[] =3D { .of_match =3D of_match_ptr("LDO4"), .regulators_node =3D of_match_ptr("regulators"), .id =3D PCA9450_LDO4, - .ops =3D &pca9450_ldo_regulator_ops, + .ops =3D &pca9450_ldo_suspend_regulator_ops, .type =3D REGULATOR_VOLTAGE, .n_voltages =3D PCA9450_LDO4_VOLTAGE_NUM, .linear_ranges =3D pca9450_ldo34_volts, @@ -1040,7 +1071,7 @@ static struct pca9450_regulator_desc pca9451a_regulat= ors[] =3D { .of_match =3D of_match_ptr("LDO3"), .regulators_node =3D of_match_ptr("regulators"), .id =3D PCA9450_LDO3, - .ops =3D &pca9450_ldo_regulator_ops, + .ops =3D &pca9450_ldo_suspend_regulator_ops, .type =3D REGULATOR_VOLTAGE, .n_voltages =3D PCA9450_LDO3_VOLTAGE_NUM, .linear_ranges =3D pca9450_ldo34_volts, @@ -1059,7 +1090,7 @@ static struct pca9450_regulator_desc pca9451a_regulat= ors[] =3D { .of_match =3D of_match_ptr("LDO4"), .regulators_node =3D of_match_ptr("regulators"), .id =3D PCA9450_LDO4, - .ops =3D &pca9450_ldo_regulator_ops, + .ops =3D &pca9450_ldo_suspend_regulator_ops, .type =3D REGULATOR_VOLTAGE, .n_voltages =3D PCA9450_LDO4_VOLTAGE_NUM, .linear_ranges =3D pca9450_ldo34_volts, diff --git a/include/linux/regulator/pca9450.h b/include/linux/regulator/pc= a9450.h index 0df8b3c48082..8925e9c9376b 100644 --- a/include/linux/regulator/pca9450.h +++ b/include/linux/regulator/pca9450.h @@ -213,6 +213,9 @@ enum { #define LDO5H_EN_MASK 0xC0 #define LDO5HOUT_MASK 0x0F =20 +/* LDO ENMODE value: ON in RUN, OFF while PMIC_STBY_REQ is asserted */ +#define LDO_ENMODE_ONREQ_STBYREQ 0x80 + /* PCA9450_REG_IRQ bits */ #define IRQ_PWRON 0x80 #define IRQ_WDOGB 0x40 --=20 2.43.0