From bf544a7a60e9eb45f3e22bd1a5184ccc16d75cc8 Mon Sep 17 00:00:00 2001 From: Loic Poulain Date: Fri, 4 Sep 2026 17:42:18 +0200 Subject: power: sequencing: Add pwrseq_is_controllable() API On some boards a power sequencing target has no host-controllable enable for its function, for instance when the enable line is not wired up to a GPIO and is hardwired to an always-on level. The pcie-m2 "uart" target is one such example: when the M.2 connector does not route the W_DISABLE2# signal to a host GPIO, its enable/disable are no-ops and the consumer cannot gate the Bluetooth function at all or exclusively. Add a generic pwrseq_is_controllable() helper. It reports whether the target's final unit provides a host-controllable dedicated power actuator. The target can implement a new optional is_controllable() callback, reporting whether that actuator is effective on this target (for example depending on GPIO presence). If the target does not provide the callback, it is assumed to be controllable. Note this only describes the target's own enable actuator. It does not imply that a power-off reaches an electrical OFF state, since a target may have multiple consumers. It also does not mean that power is uncontrolled for the target's dependencies: those may still be gated on their own. And it does not restrict consumers from calling pwrseq_power_off() either, which remains valid to drop this consumer's vote on the (possibly shared) resources and dependencies of the target. Reviewed-by: Manivannan Sadhasivam Acked-by: Bartosz Golaszewski Reviewed-by: Manivannan Sadhasivam Signed-off-by: Loic Poulain Link: https://patch.msgid.link/20260904-monza-wireless-v6-3-d8c5042b3efd@oss.qualcomm.com Signed-off-by: Bartosz Golaszewski --- include/linux/pwrseq/consumer.h | 7 +++++++ include/linux/pwrseq/provider.h | 8 ++++++++ 2 files changed, 15 insertions(+) (limited to 'include/linux/pwrseq') diff --git a/include/linux/pwrseq/consumer.h b/include/linux/pwrseq/consumer.h index 16fad5f3e3ab..b69117ad3fa7 100644 --- a/include/linux/pwrseq/consumer.h +++ b/include/linux/pwrseq/consumer.h @@ -25,6 +25,8 @@ int pwrseq_disable(struct pwrseq_desc *desc); struct device *pwrseq_to_device(struct pwrseq_desc *desc); +bool pwrseq_is_controllable(struct pwrseq_desc *desc); + #else /* CONFIG_POWER_SEQUENCING */ static inline struct pwrseq_desc * __must_check @@ -58,6 +60,11 @@ static inline struct device *pwrseq_to_device(struct pwrseq_desc *desc) return NULL; } +static inline bool pwrseq_is_controllable(struct pwrseq_desc *desc) +{ + return false; +} + #endif /* CONFIG_POWER_SEQUENCING */ #endif /* __POWER_SEQUENCING_CONSUMER_H__ */ diff --git a/include/linux/pwrseq/provider.h b/include/linux/pwrseq/provider.h index 33b3d2c2e39d..7285ad94a221 100644 --- a/include/linux/pwrseq/provider.h +++ b/include/linux/pwrseq/provider.h @@ -6,12 +6,15 @@ #ifndef __POWER_SEQUENCING_PROVIDER_H__ #define __POWER_SEQUENCING_PROVIDER_H__ +#include + struct device; struct module; struct pwrseq_device; typedef int (*pwrseq_power_state_func)(struct pwrseq_device *); typedef int (*pwrseq_match_func)(struct pwrseq_device *, struct device *); +typedef bool (*pwrseq_is_controllable_func)(struct pwrseq_device *); #define PWRSEQ_NO_MATCH 0 #define PWRSEQ_MATCH_OK 1 @@ -43,11 +46,16 @@ struct pwrseq_unit_data { * the state lock has been released. It's useful for implementing * boot-up delays without blocking other users from powering up * using the same power sequencer. + * @is_controllable: Optional callback checking whether enabling/disabling this + * target actually controls power (for example when the + * controlling GPIO is wired up). If not provided, the + * target's power is assumed to be always controllable. */ struct pwrseq_target_data { const char *name; const struct pwrseq_unit_data *unit; pwrseq_power_state_func post_enable; + pwrseq_is_controllable_func is_controllable; }; /** -- cgit v1.2.3