From nobody Sat Sep 26 03:12:00 2026 Received: from mail-pl1-f170.google.com (mail-pl1-f170.google.com [209.85.214.170]) (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 53EF43FD121 for ; Fri, 4 Sep 2026 21:20:21 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.170 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788556823; cv=none; b=VKIm5wJKgZWZq0xfcjZ6hrIYTmQ6teGDO8rZypIJGtCrXxT3gOUo4N3dvdliU3PZew/AwS0kr2a7kdQBq7Q9pJZqMdcugRTKMw9wYrVdUnioCawdKca+mDaD9uZ2L5TTKo/YLezSaMqJFGahs+a0FIafrGIY6TNIh8YAax7GzVU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788556823; c=relaxed/simple; bh=D2sTRkXI+U1SD3+QdSTnvj0X0Jbvf2TQ6H0iBo0j+84=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=MkrtnwNm45Bpt0eRiTci2Q/Jzfc3Z8RwPXIrHNS3xGQtaZX9Zt5zTH/rTGwlIE4bU1sBcH2Rc7fE0YTLeyst09uRtz+CXMqWCRKyJuSP1/M9961uMBmh6iP6AuzOS6Qv5g6f2k2KmiDwSMrXVxEncL6fAsdPIMMgpbPQsZ7usYw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=chromium.org; spf=pass smtp.mailfrom=chromium.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b=Dprkws3O; arc=none smtp.client-ip=209.85.214.170 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=chromium.org Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=chromium.org Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b="Dprkws3O" Received: by mail-pl1-f170.google.com with SMTP id d9443c01a7336-2ceab75934dso13444355ad.2 for ; Fri, 04 Sep 2026 14:20:21 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; t=1788556821; x=1789161621; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=MrnYpRzoj88ITEj49c8hPybU6W+S4YMZn8H5haI/CBI=; b=Dprkws3O6i5+KoP1ChARXUAMapbP4m142So2ZGiHCMGvAscgWmDlglsIvaDNqs5N0s H84f0b4gclQNTPyj7OH+kcvl5fj3v1ZLbrYsHgDFl881/PUe0/37pNErMHCGco+V1Qju 6hQjkwXhS/4xEEeR+6JCmTjzXloI6QmW7Bzuk= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1788556821; x=1789161621; h=content-transfer-encoding:mime-version:references:in-reply-to :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=MrnYpRzoj88ITEj49c8hPybU6W+S4YMZn8H5haI/CBI=; b=gRIaX0DtmjBv1Z+EB9MOoeB06oAjcPxTYFlHFjuWmy/qv2yWmL463JVHEVTG7KQ+Q5 BF9mSFLElSZvfxRF2crYI1WViupzDVjelvA8H9BszMBqEqzzuRZk3WWJvUZXvov/Gazq VTyvPsqzpAyupviDnAFIriqj5fnTleIPduRJaKM0Wm6OYDwAPXNM/GSQzzbC6Zp6l3gT udm3EbP8Q/eiJDbNL+sP6LX0WARJz+2CaUYY7Te5Gr2YtBCvKylAxF3oiXWLdJpuTwTL cmdjjZHXqLpawUnv5WlwfZYPKHKHatbb8T2BADoGURL0N7akTjRjZexBSGTqemNWn5zE qXgg== X-Gm-Message-State: AFuF++lp915MoQqWlY7oEZoZ1WRgi8+7ocJn076gO6tN9KNBO1XZjcCo +EP1ftqntlZSDRZGducETJKzwG7ktMgptNpK/0NPJR/tO/WOd8xOMNbQ+B/g0Tx9yg== X-Gm-Gg: AYBFou2QM1vI+B+ooSMneb+A1cHoNWT+I3qIO5fbBu/BgzjscgL3sRbib/l5gfiRpXc J1REOW72Puabmp2hDv25Ot0Jvhi3hV0lLm0ae3VTWpvWj/ToOhAUIaDxHvzp9GZIynF+EviRb0k xF6oXuRjBKCxedvuu6FGM2Yw/PzmSeVvmNJ4+xFC7NxnEVvJxnuCgODndHcIockCdqbVl/wmO+M CRM0UurkcF2EKrhNZSYqL3ZRkeYJEJeGZQeCJW+2XvNEUZ6rFHIu90OcugrMTjAz+zLe3wozqKw etsvu1GL96KzUomJRqHelfva3jE9LTuc6Y7HISjaPHgFdPbEbDNmUMKN8BoDJQ+HibiYT+jvzhE fRj8MbPIAS235iMQ1PWNy4p1Mj54pFmCVoQmI08pFeQbeSIw54ZZntTg5wagoK1VJfRuPLSjynV DOsCaiVEQJdNJzAXrbboLnIvB76IPX1GdtCoxawO+YBzh+F5sXQ/1WttR/Cykq9fd6wa7BJuG2d XpBPmvIR6/GgYlUiT5v32KfTbA= X-Received: by 2002:a17:90b:4c41:b0:398:9bd5:490e with SMTP id 98e67ed59e1d1-39b2623ac0fmr11596376a91.21.1788556820428; Fri, 04 Sep 2026 14:20:20 -0700 (PDT) Received: from localhost ([2a00:79e0:2e7c:8:5597:62ab:c321:4a7f]) by smtp.gmail.com with UTF8SMTPSA id 5a478bee46e88-3339885d29esm9867791eec.2.2026.09.04.14.20.18 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Fri, 04 Sep 2026 14:20:19 -0700 (PDT) From: Brian Norris To: "Rafael J . Wysocki" Cc: linux-kernel@vger.kernel.org, Len Brown , Ulf Hansson , linux-pm@vger.kernel.org, Pavel Machek , Doug Anderson , Brian Norris Subject: [PATCH 01/11] PM: runtime: kerneldoc fixes Date: Fri, 4 Sep 2026 14:12:06 -0700 Message-ID: <20260904141215.1.Ib31d6be7e93f6c02321d03c78ea410e02d7380fc@changeid> X-Mailer: git-send-email 2.55.0.979.g7e5102b832-goog In-Reply-To: <20260904212000.4167880-1-briannorris@chromium.org> References: <20260904212000.4167880-1-briannorris@chromium.org> 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" When included into a Documentation/.../*.rst file, `make htmldocs` complains: ./include/linux/pm_runtime.h:359: WARNING: Bullet list ends without a blank= line; unexpected unindent. [docutils] [... more ...] We should fix up the list format here to look nicer in HTML form, and avoid warnings. Adjust to a few other kerneldoc-isms (formatting, "Return:") while we're at it too. The result now passes 'make htmldocs' without warning, once these files are included in Documentation/.../*.rst. Signed-off-by: Brian Norris --- drivers/base/power/runtime.c | 24 ++- include/linux/pm_runtime.h | 291 ++++++++++++++++++++--------------- 2 files changed, 183 insertions(+), 132 deletions(-) diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c index fab38bc98113..0c0931763d07 100644 --- a/drivers/base/power/runtime.c +++ b/drivers/base/power/runtime.c @@ -162,7 +162,7 @@ static void pm_runtime_cancel_pending(struct device *de= v) dev->power.request =3D RPM_REQ_NONE; } =20 -/* +/** * pm_runtime_autosuspend_expiration - Get a device's autosuspend-delay ex= piration time. * @dev: Device to handle. * @@ -200,7 +200,7 @@ static int dev_memalloc_noio(struct device *dev, void *= data) return dev->power.memalloc_noio; } =20 -/* +/** * pm_runtime_set_memalloc_noio - Set a device's memalloc_noio flag. * @dev: Device to handle. * @enable: True for setting the flag and False for clearing the flag. @@ -1043,6 +1043,11 @@ static enum hrtimer_restart pm_suspend_timer_fn(str= uct hrtimer *timer) * pm_schedule_suspend - Set up a timer to submit a suspend request in fut= ure. * @dev: Device to suspend. * @delay: Time to wait before submitting a suspend request, in millisecon= ds. + * + * Return: + * * %1: Success; @dev is already %RPM_SUSPENDED. + * * %0: Success. + * * Error code on failure. */ int pm_schedule_suspend(struct device *dev, unsigned int delay) { @@ -1105,7 +1110,7 @@ static int rpm_drop_usage_count(struct device *dev) * warning, increment it, and return an error). Then carry out an idle * notification, either synchronous or asynchronous. * - * This routine may be called in atomic context if the RPM_ASYNC flag is s= et, + * This routine may be called in atomic context if the %RPM_ASYNC flag is = set, * or if pm_runtime_irq_safe() has been called. */ int __pm_runtime_idle(struct device *dev, int rpmflags) @@ -1143,7 +1148,7 @@ EXPORT_SYMBOL_GPL(__pm_runtime_idle); * warning, increment it, and return an error). Then carry out a suspend, * either synchronous or asynchronous. * - * This routine may be called in atomic context if the RPM_ASYNC flag is s= et, + * This routine may be called in atomic context if the %RPM_ASYNC flag is = set, * or if pm_runtime_irq_safe() has been called. */ int __pm_runtime_suspend(struct device *dev, int rpmflags) @@ -1179,7 +1184,7 @@ EXPORT_SYMBOL_GPL(__pm_runtime_suspend); * If the RPM_GET_PUT flag is set, increment the device's usage count. Th= en * carry out a resume, either synchronous or asynchronous. * - * This routine may be called in atomic context if the RPM_ASYNC flag is s= et, + * This routine may be called in atomic context if the %RPM_ASYNC flag is = set, * or if pm_runtime_irq_safe() has been called. */ int __pm_runtime_resume(struct device *dev, int rpmflags) @@ -1254,9 +1259,12 @@ static int pm_runtime_get_conditional(struct device = *dev, bool ign_usage_count) * @dev: Target device. * * Increment the runtime PM usage counter of @dev if its runtime PM status= is - * %RPM_ACTIVE, in which case it returns 1. If the device is in a different - * state, 0 is returned. -EINVAL is returned if runtime PM is disabled for= the - * device, in which case also the usage_count will remain unmodified. + * already %RPM_ACTIVE + * + * Return: + * * %-EINVAL: Runtime PM is disabled for @dev. The usage counter is not i= ncremented. + * * %1: Success; usage counter is incremented. + * * %0: @dev was not active. */ int pm_runtime_get_if_active(struct device *dev) { diff --git a/include/linux/pm_runtime.h b/include/linux/pm_runtime.h index 64921b10ac74..ab6a19a85880 100644 --- a/include/linux/pm_runtime.h +++ b/include/linux/pm_runtime.h @@ -137,13 +137,14 @@ static inline void pm_runtime_put_noidle(struct devic= e *dev) * pm_runtime_suspended - Check whether or not a device is runtime-suspend= ed. * @dev: Target device. * - * Return %true if runtime PM is enabled for @dev and its runtime PM statu= s is - * %RPM_SUSPENDED, or %false otherwise. - * * Note that the return value of this function can only be trusted if it is * called under the runtime PM lock of @dev or under conditions in which * runtime PM cannot be either disabled or enabled for @dev and its runtim= e PM * status cannot change. + * + * Return: + * * %true: @dev has runtime PM enabled and its status is %RPM_SUSPENDED. + * * %false: Otherwise. */ static inline bool pm_runtime_suspended(struct device *dev) { @@ -155,13 +156,14 @@ static inline bool pm_runtime_suspended(struct device= *dev) * pm_runtime_active - Check whether or not a device is runtime-active. * @dev: Target device. * - * Return %true if runtime PM is disabled for @dev or its runtime PM statu= s is - * %RPM_ACTIVE, or %false otherwise. - * * Note that the return value of this function can only be trusted if it is * called under the runtime PM lock of @dev or under conditions in which * runtime PM cannot be either disabled or enabled for @dev and its runtim= e PM * status cannot change. + * + * Return: + * * %true: Runtime PM is disabled for @dev or its status is %RPM_ACTIVE. + * * %false: Otherwise. */ static inline bool pm_runtime_active(struct device *dev) { @@ -173,12 +175,13 @@ static inline bool pm_runtime_active(struct device *d= ev) * pm_runtime_status_suspended - Check if runtime PM status is "suspended". * @dev: Target device. * - * Return %true if the runtime PM status of @dev is %RPM_SUSPENDED, or %fa= lse - * otherwise, regardless of whether or not runtime PM has been enabled for= @dev. - * * Note that the return value of this function can only be trusted if it is * called under the runtime PM lock of @dev or under conditions in which t= he * runtime PM status of @dev cannot change. + * + * Return: + * * %true: Runtime PM status of @dev is %RPM_SUSPENDED. + * * %false: Otherwise. */ static inline bool pm_runtime_status_suspended(struct device *dev) { @@ -189,11 +192,13 @@ static inline bool pm_runtime_status_suspended(struct= device *dev) * pm_runtime_enabled - Check if runtime PM is enabled. * @dev: Target device. * - * Return %true if runtime PM is enabled for @dev or %false otherwise. - * * Note that the return value of this function can only be trusted if it is * called under the runtime PM lock of @dev or under conditions in which * runtime PM cannot be either disabled or enabled for @dev. + * + * Return: + * * %true: Runtime PM is enabled for @dev. + * * %false: Otherwise. */ static inline bool pm_runtime_enabled(struct device *dev) { @@ -205,6 +210,10 @@ static inline bool pm_runtime_enabled(struct device *d= ev) * @dev: Target device. * * Do not call this function outside system suspend/resume code paths. + * + * Return: + * * %true: Runtime PM enabling is blocked for @dev. + * * %false: Otherwise. */ static inline bool pm_runtime_blocked(struct device *dev) { @@ -215,8 +224,9 @@ static inline bool pm_runtime_blocked(struct device *de= v) * pm_runtime_has_no_callbacks - Check if runtime PM callbacks may be pres= ent. * @dev: Target device. * - * Return %true if @dev is a special device without runtime PM callbacks or - * %false otherwise. + * Return: + * * %true: @dev is marked as having no runtime PM callbacks. + * * %false: Otherwise. */ static inline bool pm_runtime_has_no_callbacks(struct device *dev) { @@ -239,9 +249,11 @@ static inline void pm_runtime_mark_last_busy(struct de= vice *dev) * pm_runtime_is_irq_safe - Check if runtime PM can work in interrupt cont= ext. * @dev: Target device. * - * Return %true if @dev has been marked as an "IRQ-safe" device (with resp= ect - * to runtime PM), in which case its runtime PM callabcks can be expected = to - * work correctly when invoked from interrupt handlers. + * Return: + * * %true: @dev has been marked as an "IRQ-safe" device, in which case its + * runtime PM callbacks can be expected to work correctly from interrupt + * handlers. + * * %false: Otherwise. */ static inline bool pm_runtime_is_irq_safe(struct device *dev) { @@ -348,17 +360,17 @@ static inline int pm_runtime_force_resume(struct devi= ce *dev) { return -ENXIO; } * autosuspend has been enabled for it). * * Return: - * * 0: Success. - * * -EINVAL: Runtime PM error. - * * -EACCES: Runtime PM disabled. - * * -EAGAIN: Runtime PM usage counter non-zero, Runtime PM status change - * ongoing or device not in %RPM_ACTIVE state. - * * -EBUSY: Runtime PM child_count non-zero. - * * -EPERM: Device PM QoS resume latency 0. - * * -EINPROGRESS: Suspend already in progress. - * * -ENOSYS: CONFIG_PM not enabled. - * Other values and conditions for the above values are possible as return= ed by - * Runtime PM idle and suspend callbacks. + * * %0: Success. + * * %-EINVAL: Runtime PM error. + * * %-EACCES: Runtime PM disabled. + * * %-EAGAIN: Runtime PM usage counter non-zero, Runtime PM status change + * ongoing or device not in %RPM_ACTIVE state. + * * %-EBUSY: Runtime PM child_count non-zero. + * * %-EPERM: Device PM QoS resume latency 0. + * * %-EINPROGRESS: Suspend already in progress. + * * %-ENOSYS: %CONFIG_PM not enabled. + * * Other values and conditions for the above values are possible as retu= rned + * by Runtime PM idle and suspend callbacks. */ static inline int pm_runtime_idle(struct device *dev) { @@ -370,17 +382,17 @@ static inline int pm_runtime_idle(struct device *dev) * @dev: Target device. * * Return: - * * 1: Success; device was already suspended. - * * 0: Success. - * * -EINVAL: Runtime PM error. - * * -EACCES: Runtime PM disabled. - * * -EAGAIN: Runtime PM usage counter non-zero or Runtime PM status change - * ongoing. - * * -EBUSY: Runtime PM child_count non-zero. - * * -EPERM: Device PM QoS resume latency 0. - * * -ENOSYS: CONFIG_PM not enabled. - * Other values and conditions for the above values are possible as return= ed by - * Runtime PM suspend callbacks. + * * %1: Success; device was already suspended. + * * %0: Success. + * * %-EINVAL: Runtime PM error. + * * %-EACCES: Runtime PM disabled. + * * %-EAGAIN: Runtime PM usage counter non-zero or Runtime PM status chan= ge + * ongoing. + * * %-EBUSY: Runtime PM child_count non-zero. + * * %-EPERM: Device PM QoS resume latency 0. + * * %-ENOSYS: %CONFIG_PM not enabled. + * * Other values and conditions for the above values are possible as retu= rned + * by Runtime PM suspend callbacks. */ static inline int pm_runtime_suspend(struct device *dev) { @@ -397,17 +409,17 @@ static inline int pm_runtime_suspend(struct device *d= ev) * engaging its "idle check" callback. * * Return: - * * 1: Success; device was already suspended. - * * 0: Success. - * * -EINVAL: Runtime PM error. - * * -EACCES: Runtime PM disabled. - * * -EAGAIN: Runtime PM usage counter non-zero or Runtime PM status change - * ongoing. - * * -EBUSY: Runtime PM child_count non-zero. - * * -EPERM: Device PM QoS resume latency 0. - * * -ENOSYS: CONFIG_PM not enabled. - * Other values and conditions for the above values are possible as return= ed by - * Runtime PM suspend callbacks. + * * %1: Success; device was already suspended. + * * %0: Success. + * * %-EINVAL: Runtime PM error. + * * %-EACCES: Runtime PM disabled. + * * %-EAGAIN: Runtime PM usage counter non-zero or Runtime PM status chan= ge + * ongoing. + * * %-EBUSY: Runtime PM child_count non-zero. + * * %-EPERM: Device PM QoS resume latency 0. + * * %-ENOSYS: %CONFIG_PM not enabled. + * * Other values and conditions for the above values are possible as retu= rned + * by Runtime PM suspend callbacks. */ static inline int pm_runtime_autosuspend(struct device *dev) { @@ -418,6 +430,11 @@ static inline int pm_runtime_autosuspend(struct device= *dev) /** * pm_runtime_resume - Resume a device synchronously. * @dev: Target device. + * + * Return: + * * %1: Success; @dev is already %RPM_ACTIVE. + * * %0: Success. + * * Error code on failure. */ static inline int pm_runtime_resume(struct device *dev) { @@ -432,15 +449,15 @@ static inline int pm_runtime_resume(struct device *de= v) * asynchronously. * * Return: - * * 0: Success. - * * -EINVAL: Runtime PM error. - * * -EACCES: Runtime PM disabled. - * * -EAGAIN: Runtime PM usage counter non-zero, Runtime PM status change - * ongoing or device not in %RPM_ACTIVE state. - * * -EBUSY: Runtime PM child_count non-zero. - * * -EPERM: Device PM QoS resume latency 0. - * * -EINPROGRESS: Suspend already in progress. - * * -ENOSYS: CONFIG_PM not enabled. + * * %0: Success. + * * %-EINVAL: Runtime PM error. + * * %-EACCES: Runtime PM disabled. + * * %-EAGAIN: Runtime PM usage counter non-zero, Runtime PM status change + * ongoing or device not in %RPM_ACTIVE state. + * * %-EBUSY: Runtime PM child_count non-zero. + * * %-EPERM: Device PM QoS resume latency 0. + * * %-EINPROGRESS: Suspend already in progress. + * * %-ENOSYS: %CONFIG_PM not enabled. */ static inline int pm_request_idle(struct device *dev) { @@ -450,6 +467,11 @@ static inline int pm_request_idle(struct device *dev) /** * pm_request_resume - Queue up runtime-resume of a device. * @dev: Target device. + * + * Return: + * * %1: Success; @dev is already %RPM_ACTIVE. + * * %0: Success. + * * Error code on failure. */ static inline int pm_request_resume(struct device *dev) { @@ -465,16 +487,16 @@ static inline int pm_request_resume(struct device *de= v) * equivalent pm_runtime_autosuspend() for @dev asynchronously. * * Return: - * * 1: Success; device was already suspended. - * * 0: Success. - * * -EINVAL: Runtime PM error. - * * -EACCES: Runtime PM disabled. - * * -EAGAIN: Runtime PM usage counter non-zero or Runtime PM status change - * ongoing. - * * -EBUSY: Runtime PM child_count non-zero. - * * -EPERM: Device PM QoS resume latency 0. - * * -EINPROGRESS: Suspend already in progress. - * * -ENOSYS: CONFIG_PM not enabled. + * * %1: Success; device was already suspended. + * * %0: Success. + * * %-EINVAL: Runtime PM error. + * * %-EACCES: Runtime PM disabled. + * * %-EAGAIN: Runtime PM usage counter non-zero or Runtime PM status chan= ge + * ongoing. + * * %-EBUSY: Runtime PM child_count non-zero. + * * %-EPERM: Device PM QoS resume latency 0. + * * %-EINPROGRESS: Suspend already in progress. + * * %-ENOSYS: %CONFIG_PM not enabled. */ static inline int pm_request_autosuspend(struct device *dev) { @@ -488,6 +510,11 @@ static inline int pm_request_autosuspend(struct device= *dev) * * Bump up the runtime PM usage counter of @dev and queue up a work item to * carry out runtime-resume of it. + * + * Return: + * * %1: Success; @dev is already %RPM_ACTIVE. + * * %0: Success; runtime-resume was queued. + * * Error code on failure. */ static inline int pm_runtime_get(struct device *dev) { @@ -507,6 +534,11 @@ static inline int pm_runtime_get(struct device *dev) * Consider using pm_runtime_resume_and_get() instead of it, especially * if its return value is checked by the caller, as this is likely to resu= lt * in cleaner code. + * + * Return: + * * %1: Success; @dev is already %RPM_ACTIVE. + * * %0: Success. + * * Error code on failure. */ static inline int pm_runtime_get_sync(struct device *dev) { @@ -531,8 +563,11 @@ static inline int pm_runtime_get_active(struct device = *dev, int rpmflags) * @dev: Target device. * * Resume @dev synchronously and if that is successful, increment its runt= ime - * PM usage counter. Return 0 if the runtime PM usage counter of @dev has = been - * incremented or a negative error code otherwise. + * PM usage counter. + * + * Return: + * * %0: Success; @dev is active and its usage counter has been incremente= d. + * * Negative error code on failure; usage counter is unchanged. */ static inline int pm_runtime_resume_and_get(struct device *dev) { @@ -559,16 +594,16 @@ static inline void pm_runtime_put(struct device *dev) * equal to 0, queue up a work item for @dev like in pm_request_autosuspen= d(). * * Return: - * * 1: Success. Usage counter dropped to zero, but device was already sus= pended. - * * 0: Success. - * * -EINVAL: Runtime PM error. - * * -EACCES: Runtime PM disabled. - * * -EAGAIN: Runtime PM usage counter became non-zero or Runtime PM status - * change ongoing. - * * -EBUSY: Runtime PM child_count non-zero. - * * -EPERM: Device PM QoS resume latency 0. - * * -EINPROGRESS: Suspend already in progress. - * * -ENOSYS: CONFIG_PM not enabled. + * * %1: Success. Usage counter dropped to zero, but device was already su= spended. + * * %0: Success. + * * %-EINVAL: Runtime PM error. + * * %-EACCES: Runtime PM disabled. + * * %-EAGAIN: Runtime PM usage counter became non-zero or Runtime PM stat= us + * change ongoing. + * * %-EBUSY: Runtime PM child_count non-zero. + * * %-EPERM: Device PM QoS resume latency 0. + * * %-EINPROGRESS: Suspend already in progress. + * * %-ENOSYS: %CONFIG_PM not enabled. */ static inline int __pm_runtime_put_autosuspend(struct device *dev) { @@ -585,16 +620,16 @@ static inline int __pm_runtime_put_autosuspend(struct= device *dev) * in pm_request_autosuspend(). * * Return: - * * 1: Success. Usage counter dropped to zero, but device was already sus= pended. - * * 0: Success. - * * -EINVAL: Runtime PM error. - * * -EACCES: Runtime PM disabled. - * * -EAGAIN: Runtime PM usage counter became non-zero or Runtime PM status - * change ongoing. - * * -EBUSY: Runtime PM child_count non-zero. - * * -EPERM: Device PM QoS resume latency 0. - * * -EINPROGRESS: Suspend already in progress. - * * -ENOSYS: CONFIG_PM not enabled. + * * %1: Success. Usage counter dropped to zero, but device was already su= spended. + * * %0: Success. + * * %-EINVAL: Runtime PM error. + * * %-EACCES: Runtime PM disabled. + * * %-EAGAIN: Runtime PM usage counter became non-zero or Runtime PM stat= us + * change ongoing. + * * %-EBUSY: Runtime PM child_count non-zero. + * * %-EPERM: Device PM QoS resume latency 0. + * * %-EINPROGRESS: Suspend already in progress. + * * %-ENOSYS: %CONFIG_PM not enabled. */ static inline int pm_runtime_put_autosuspend(struct device *dev) { @@ -662,17 +697,17 @@ DEFINE_GUARD_COND(pm_runtime_active_auto, _try_enable= d, * if it returns an error code. * * Return: - * * 1: Success. Usage counter dropped to zero, but device was already sus= pended. - * * 0: Success. - * * -EINVAL: Runtime PM error. - * * -EACCES: Runtime PM disabled. - * * -EAGAIN: Runtime PM usage counter became non-zero or Runtime PM status - * change ongoing. - * * -EBUSY: Runtime PM child_count non-zero. - * * -EPERM: Device PM QoS resume latency 0. - * * -ENOSYS: CONFIG_PM not enabled. - * Other values and conditions for the above values are possible as return= ed by - * Runtime PM suspend callbacks. + * * %1: Success. Usage counter dropped to zero, but device was already su= spended. + * * %0: Success. + * * %-EINVAL: Runtime PM error. + * * %-EACCES: Runtime PM disabled. + * * %-EAGAIN: Runtime PM usage counter became non-zero or Runtime PM stat= us + * change ongoing. + * * %-EBUSY: Runtime PM child_count non-zero. + * * %-EPERM: Device PM QoS resume latency 0. + * * %-ENOSYS: %CONFIG_PM not enabled. + * * Other values and conditions for the above values are possible as retu= rned + * by Runtime PM suspend callbacks. */ static inline int pm_runtime_put_sync(struct device *dev) { @@ -690,17 +725,17 @@ static inline int pm_runtime_put_sync(struct device *= dev) * if it returns an error code. * * Return: - * * 1: Success. Usage counter dropped to zero, but device was already sus= pended. - * * 0: Success. - * * -EINVAL: Runtime PM error. - * * -EACCES: Runtime PM disabled. - * * -EAGAIN: Runtime PM usage counter became non-zero or Runtime PM status - * change ongoing. - * * -EBUSY: Runtime PM child_count non-zero. - * * -EPERM: Device PM QoS resume latency 0. - * * -ENOSYS: CONFIG_PM not enabled. - * Other values and conditions for the above values are possible as return= ed by - * Runtime PM suspend callbacks. + * * %1: Success. Usage counter dropped to zero, but device was already su= spended. + * * %0: Success. + * * %-EINVAL: Runtime PM error. + * * %-EACCES: Runtime PM disabled. + * * %-EAGAIN: Runtime PM usage counter became non-zero or Runtime PM stat= us + * change ongoing. + * * %-EBUSY: Runtime PM child_count non-zero. + * * %-EPERM: Device PM QoS resume latency 0. + * * %-ENOSYS: %CONFIG_PM not enabled. + * * Other values and conditions for the above values are possible as retu= rned + * by Runtime PM suspend callbacks. */ static inline int pm_runtime_put_sync_suspend(struct device *dev) { @@ -721,18 +756,18 @@ static inline int pm_runtime_put_sync_suspend(struct = device *dev) * if it returns an error code. * * Return: - * * 1: Success. Usage counter dropped to zero, but device was already sus= pended. - * * 0: Success. - * * -EINVAL: Runtime PM error. - * * -EACCES: Runtime PM disabled. - * * -EAGAIN: Runtime PM usage counter became non-zero or Runtime PM status - * change ongoing. - * * -EBUSY: Runtime PM child_count non-zero. - * * -EPERM: Device PM QoS resume latency 0. - * * -EINPROGRESS: Suspend already in progress. - * * -ENOSYS: CONFIG_PM not enabled. - * Other values and conditions for the above values are possible as return= ed by - * Runtime PM suspend callbacks. + * * %1: Success. Usage counter dropped to zero, but device was already su= spended. + * * %0: Success. + * * %-EINVAL: Runtime PM error. + * * %-EACCES: Runtime PM disabled. + * * %-EAGAIN: Runtime PM usage counter became non-zero or Runtime PM stat= us + * change ongoing. + * * %-EBUSY: Runtime PM child_count non-zero. + * * %-EPERM: Device PM QoS resume latency 0. + * * %-EINPROGRESS: Suspend already in progress. + * * %-ENOSYS: %CONFIG_PM not enabled. + * * Other values and conditions for the above values are possible as retu= rned + * by Runtime PM suspend callbacks. */ static inline int pm_runtime_put_sync_autosuspend(struct device *dev) { @@ -748,6 +783,10 @@ static inline int pm_runtime_put_sync_autosuspend(stru= ct device *dev) * of it will be taken into account. * * It is not valid to call this function for devices with runtime PM enabl= ed. + * + * Return: + * * %0: Success. + * * Error code on failure. */ static inline int pm_runtime_set_active(struct device *dev) { @@ -762,6 +801,10 @@ static inline int pm_runtime_set_active(struct device = *dev) * dependencies of it will be taken into account. * * It is not valid to call this function for devices with runtime PM enabl= ed. + * + * Return: + * * %0: Success. + * * Error code on failure. */ static inline int pm_runtime_set_suspended(struct device *dev) { --=20 2.55.0.979.g7e5102b832-goog From nobody Sat Sep 26 03:12:00 2026 Received: from mail-pg1-f180.google.com (mail-pg1-f180.google.com [209.85.215.180]) (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 D5BC3421223 for ; Fri, 4 Sep 2026 21:20:23 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.215.180 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788556826; cv=none; b=r9ypswe/HEwQfdYkdSqu1QZ0lfHM7iUbey4J1geA1PQBnTNW/mlKOmJugo0tF+OmoKQSKWcZXAiFlpkDahqBPFw/WSTQ49oUAMOQCWqSqP/ogYoMibhV4J5aH07y7XL2+RdY//vNgrf1UGzCX3LiIC0hQuFJAIXPxjwyipsysW8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788556826; c=relaxed/simple; bh=GjCuMqwTKFKTr1bVwbH2MBuyd3Kpcf7SljlzS5pGAKI=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=QwKEx9Mk003r5a/KX3fo8vu+HzRw3Bf4T3LG0B7RLP6+ndO9tU0/mKx97Ttm5IJo2qlp8EJcnRnVDIDHrJmSWwo8csvyxHFOtIv6HIZlD3ibcnyXMZf/DC165z0ganzPTpM1pXVl/3g4Sl2/YJpjRRGLJGeNnix/EYATF09FZ1w= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=chromium.org; spf=pass smtp.mailfrom=chromium.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b=Qy1yQPsN; arc=none smtp.client-ip=209.85.215.180 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=chromium.org Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=chromium.org Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b="Qy1yQPsN" Received: by mail-pg1-f180.google.com with SMTP id 41be03b00d2f7-cc1d57602e8so1334334a12.3 for ; Fri, 04 Sep 2026 14:20:23 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; t=1788556823; x=1789161623; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=h4nRO1s9pLzcSKrRPhFfQyfVY01to/RP04/bcAAweRU=; b=Qy1yQPsNXly+ocPuxiugGW+fldep9gQErsWfsfX7AHLcs5p2CztIcT5wwMW1ocvXpf KNZ6aE646NEOeHbGj2ezHc2TQbI0B9j8yD17ILK6QicMDksewjmY81Cud1cV+T6jpmil Lfox3eoaP/dwEOMtnJrmHVM8WEq97B43m5emc= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1788556823; x=1789161623; h=content-transfer-encoding:mime-version:references:in-reply-to :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=h4nRO1s9pLzcSKrRPhFfQyfVY01to/RP04/bcAAweRU=; b=j0U/LkSbfl1XqWC00CRR2nm9kNdyf93TROgkHYCSvqqxYhhRoH13tFnVUoQhK7CFV4 b4yAvaPxHmzuo4E50bdGv7ffk9rCEMvO8ukMN22vNsTc/cCTeuptSAcBuJPh4uBYwbj2 viJbRBI4rWh8pblNTEn2sdcgE21tSpE7EkKj6IcbUN78GXY4kzbXe+UDvNUCQoaQQFat LtgSn50T0SQ02fY+7y14li5vcOq+AqzxfM+2PrYgoXQe7S26VJiQh9mZ7jWuBCNGO40U JhspKjaRjwbPLUB9XsPMLNj7lY5IiyaWZI+3vtKHNS3rR+yamceuZzpI9iBwoXDdjbmk sDLw== X-Gm-Message-State: AFuF++l4TYgRmH8SE8QHi3O7H/gQpeRw1EVZQire3wDjOGmf/jl+iAdb 8dx1ngDxFtkG0efvlicyOPR2H35iRBPjUohjrqkqk5QvVZ6lP8Y5U06h5m7I4nwLsOVAtWpZ5DG GJho= X-Gm-Gg: AYBFou3jRir21eE8NCACBugxHkpmZOz82EliqkF/7VHcP77WQLKVZuTotc3a9VbeBa6 IiPHd11yVLQO+mnTSlpzZrQR1wny5pqmv9YUspvtmrhu+Ui2z949kNC16gL4dICJyr58mr/6iWM BKhAxDWkTGI8ir8daIH9KfLKfxzc8P8VhNuXpYzB5lLbK/2YAZz75sKqQf+uBMVXW4R7JK3vS7a qskSZp2nsw4rne2YAOYIGj+QMeB0Yvi9K0wweoc0u1mAn6sxIkQbL4xavtFL5U3CFjphgfMvqZJ d33yVMHw6wrIbUqexZ/h1qfgXqMjhOPEm6RG15XR2thYx6blyORPZCR0eezUsDLy7zXTQrNjMiF q1XhpYVnJE9dZ2mtJK78TNp9XgyvH0rD08yAUQP+oSEJ906IePVVmTdmuM1TT5L3quLOYQAEjQl +xB58n7Tmn3kKWXGvCc3tkqrBXcdF1CviOh0kIE0dPP9XXX9CTe7tv+F9JAoLQsXiLEu4cK6BJi Fs4AldfYSar3P50ys2f3hOgVuk= X-Received: by 2002:a17:90b:3c42:b0:38e:fea2:df53 with SMTP id 98e67ed59e1d1-39b260d2977mr12114905a91.4.1788556823137; Fri, 04 Sep 2026 14:20:23 -0700 (PDT) Received: from localhost ([2a00:79e0:2e7c:8:5597:62ab:c321:4a7f]) by smtp.gmail.com with UTF8SMTPSA id a92af1059eb24-1432423f99fsm8514617c88.1.2026.09.04.14.20.21 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Fri, 04 Sep 2026 14:20:22 -0700 (PDT) From: Brian Norris To: "Rafael J . Wysocki" Cc: linux-kernel@vger.kernel.org, Len Brown , Ulf Hansson , linux-pm@vger.kernel.org, Pavel Machek , Doug Anderson , Brian Norris Subject: [PATCH 02/11] PM: runtime: Improve set_{status,active,suspended} docs Date: Fri, 4 Sep 2026 14:12:07 -0700 Message-ID: <20260904141215.2.If02a538531ea004987c9a28a8d030ee9f71221cd@changeid> X-Mailer: git-send-email 2.55.0.979.g7e5102b832-goog In-Reply-To: <20260904212000.4167880-1-briannorris@chromium.org> References: <20260904212000.4167880-1-briannorris@chromium.org> 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" The set_active()/set_suspended() docs don't mention that they also clear the 'runtime_error' field. This is a very important note, since that's one key purpose for using them. Fix a typo in __pm_runtime_set_status() while we're at it. Signed-off-by: Brian Norris --- drivers/base/power/runtime.c | 4 ++-- include/linux/pm_runtime.h | 23 +++++++++++++++-------- 2 files changed, 17 insertions(+), 10 deletions(-) diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c index 0c0931763d07..ce7e08e628a2 100644 --- a/drivers/base/power/runtime.c +++ b/drivers/base/power/runtime.c @@ -1295,7 +1295,7 @@ int pm_runtime_get_if_in_use(struct device *dev) EXPORT_SYMBOL_GPL(pm_runtime_get_if_in_use); =20 /** - * __pm_runtime_set_status - Set runtime PM status of a device. + * __pm_runtime_set_status - Set runtime PM status of a device and clear e= rrors. * @dev: Device to handle. * @status: New runtime PM status of the device. * @@ -1314,7 +1314,7 @@ EXPORT_SYMBOL_GPL(pm_runtime_get_if_in_use); * If @dev has any suppliers (as reflected by device links to them), and @= status * is RPM_ACTIVE, they will be activated upfront and if the activation of = one * of them fails, the status of @dev will be changed to RPM_SUSPENDED (ins= tead - * of the @status value) and the suppliers will be deacticated on exit. T= he + * of the @status value) and the suppliers will be deactivated on exit. T= he * error returned by the failing supplier activation will be returned in t= hat * case. */ diff --git a/include/linux/pm_runtime.h b/include/linux/pm_runtime.h index ab6a19a85880..1ffd9d5c3010 100644 --- a/include/linux/pm_runtime.h +++ b/include/linux/pm_runtime.h @@ -776,13 +776,18 @@ static inline int pm_runtime_put_sync_autosuspend(str= uct device *dev) } =20 /** - * pm_runtime_set_active - Set runtime PM status to "active". + * pm_runtime_set_active - Set runtime PM status to "active" and clear err= ors. * @dev: Target device. * - * Set the runtime PM status of @dev to %RPM_ACTIVE and ensure that depend= encies - * of it will be taken into account. + * Set the runtime PM status of @dev to %RPM_ACTIVE and ensure that its + * dependencies will be taken into account. Also clear the device's error + * status (@dev->power.runtime_error). * - * It is not valid to call this function for devices with runtime PM enabl= ed. + * It is only valid to call this function if runtime PM is disabled or if + * @dev->power.runtime_error is set. + * + * This will fail if suppliers cannot be resumed, or if the parent is not = in + * the correct state. * * Return: * * %0: Success. @@ -794,13 +799,15 @@ static inline int pm_runtime_set_active(struct device= *dev) } =20 /** - * pm_runtime_set_suspended - Set runtime PM status to "suspended". + * pm_runtime_set_suspended - Set runtime PM status to "suspended" and cle= ar errors. * @dev: Target device. * - * Set the runtime PM status of @dev to %RPM_SUSPENDED and ensure that - * dependencies of it will be taken into account. + * Set the runtime PM status of @dev to %RPM_SUSPENDED and ensure that its + * dependencies will be taken into account. Also clear the device's error + * status (@dev->power.runtime_error). * - * It is not valid to call this function for devices with runtime PM enabl= ed. + * It is only valid to call this function if runtime PM is disabled or if + * @dev->power.runtime_error is set. * * Return: * * %0: Success. --=20 2.55.0.979.g7e5102b832-goog From nobody Sat Sep 26 03:12:00 2026 Received: from mail-pl1-f169.google.com (mail-pl1-f169.google.com [209.85.214.169]) (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 764793E5594 for ; Fri, 4 Sep 2026 21:20:26 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.169 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788556828; cv=none; b=Jee9dYQC9y0VBw9ABKEvUEDcDi8Dpz2j6ODhSapXRohl3+XxLG6F2SIGaKnEjQNfNYtd1QptgH624yzkop6vMKAJO9xIL0BzZCbzfMh4g2WRzbhchf8jpeoJkENt+MQ2KnP9upKpHWeZAgIdKiMkeWPIrwFH9exbg/0MaL7MD8Y= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788556828; c=relaxed/simple; bh=DuSGfp51Xf6/n7M7ml+kwYVXFwSh35utIU++rb689EE=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=fZoSXCRjpBWwPlRwFw36MqwFwgEr95Yz0CJYpuD5mASB8xWMBGfBo6SguNxLlV02gzNKZOZ3eTMw8K5KxroQgMQSJ0MoFQy+pR1ZvZW02RJw1IVUq+uDtou0kP5Ow7yGg8rF8poaWr4dgnCnsM+OaOQt/o4y4piThmn0516iK0w= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=chromium.org; spf=pass smtp.mailfrom=chromium.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b=ERWHbeVf; arc=none smtp.client-ip=209.85.214.169 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=chromium.org Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=chromium.org Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b="ERWHbeVf" Received: by mail-pl1-f169.google.com with SMTP id d9443c01a7336-2ce98cb8165so16932005ad.1 for ; Fri, 04 Sep 2026 14:20:26 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; t=1788556826; x=1789161626; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=T6q1VnyWEoTKWyOgQ9OahNNcGYr+xXm1NffFlxt/MKM=; b=ERWHbeVfePqQI3GQtqx9i0XuDwJKHyVJxWChmst4Fhajzsq+IqmOpS7+neIKdE5qNs E+tDICCdI+V3xcVCsCUpwOMUC4tcncbP4b5llhUhlFD5nyJ7TagNH/WJrLOtTS3xZDrv fEmBwA76fE4YqCYrdR9kjEJoQMoTACbvIHLjQ= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1788556826; x=1789161626; h=content-transfer-encoding:mime-version:references:in-reply-to :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=T6q1VnyWEoTKWyOgQ9OahNNcGYr+xXm1NffFlxt/MKM=; b=h0MDB6mCNYmhS1bsn/GfmPAuJHy1gGaCQc6tvM/yHMBDkdAOchacDjMaaqPjSRuoTS dsuggX5zxvuEk1tIbXeNAjfJIWnmZ3LGmdtMef7AjLBW4zuBTrjI93KUs5RdwQZrh0+L C7SJ2/siZ+QI5iWoutbUwl8W6+/igxsU/zJsoD6zVxWBbPM2CMUq5D6kFxf9TmeEKlbb 4ziEMU/gJuGmQpp4zptAJpD7CxiXsl5AYqacW/aBcYjBfZiJHX/T8/8+BK4dMtgFYzrN jDbrzum6CgA7swQ5mBEAtgdWP7PFff4cHG7fevJhMyzEbZYcMkSvHFvFx6mlrHblAuLB Q3ew== X-Gm-Message-State: AFuF++l+35cRmFMseJtyIflXr/rEdMxuUHvbaAZDIfxVxpwmoOjkRdr9 ryLrH67AhOuYpQE0GVTCAOnF4dQKRe+I//37ZdMeWZzLIVashN9UELsrmaeRwaa33Q== X-Gm-Gg: AYBFou0ciXmlEMy3tB07Oaoakq9q5OitArAwuD/irX5hnAsU3dTlJi7CgLIqRwCqy8u tuOiiMUZDDde8iZskbOdAS8zGrj6PhpZ6xwFoS4FcBy69v5WHLBOS0/WaGTNxkiVd4eJT43gZ61 P1gFB39d8KgRctUCyjcRpTOn+dCQjjz5nRsp1fGx5W2mKo/zdaPlarKTXcEaPQYvkoX0mVbQB6l ACwsTIdwxzseY0Kognc6el/xCiwvBrJKWmAH1PKd7bbJyIG/DpgyOEq1klVYekhoxws98ks2Hea xqVw/V7jn2BXCPmVXW6R89um2foe0sZxzZiKIbA8UoOz+WBKq8EOlcvX+6jOkfRpWyr0bqIGBj9 YJzOc2ufb/bynQ1M7jUuzFIqz4g+3SwaP5oiX826HR+jGEIIbSpnhoUZUcvNvqfO5F8IVUwCCoi 1657TnyRd4Zpy6nAphAqJN9Akon5m3ky5Iesa6yAwvBbuZCUvmkj47keuUi6MMA59xbr/O37FF/ 2rbJZaYhyFRASzJX7SQm6rsmlkzemX+iv1ebKhxDoz/HAvVVw== X-Received: by 2002:a17:903:2ac6:b0:2d7:1858:1d96 with SMTP id d9443c01a7336-2dafaf5f50dmr146868315ad.7.1788556825495; Fri, 04 Sep 2026 14:20:25 -0700 (PDT) Received: from localhost ([2a00:79e0:2e7c:8:5597:62ab:c321:4a7f]) by smtp.gmail.com with UTF8SMTPSA id 5a478bee46e88-3339885d29esm9868188eec.2.2026.09.04.14.20.24 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Fri, 04 Sep 2026 14:20:24 -0700 (PDT) From: Brian Norris To: "Rafael J . Wysocki" Cc: linux-kernel@vger.kernel.org, Len Brown , Ulf Hansson , linux-pm@vger.kernel.org, Pavel Machek , Doug Anderson , Brian Norris Subject: [PATCH 03/11] PM: runtime: kerneldoc wording improvements Date: Fri, 4 Sep 2026 14:12:08 -0700 Message-ID: <20260904141215.3.I3bdec7dcda46e1bee6d4f91530518fbe9c9096fd@changeid> X-Mailer: git-send-email 2.55.0.979.g7e5102b832-goog In-Reply-To: <20260904212000.4167880-1-briannorris@chromium.org> References: <20260904212000.4167880-1-briannorris@chromium.org> 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" In preparation for removing duplicate documentation from Documentation/power/runtime_pm.rst, borrow some of the useful wording from runtime_pm.rst, and update other language for clarity, ease of reading, and completeness. Other guiding principles in this change: * Try to highlight "core", as in, "functions that are not for driver use but are exported because the real entrypoints are inline functions" * Rework pm_runtime_barrier() docs significantly. More below. * Include some clarifying cross-references and recommendations for pm_runtime_put_sync{,_suspend,_autosuspend}() * Attempt to deemphasize some of the implementation details (e.g., "asynchronous" instead of "queue") * Try for more clear user-facing language. For example, "set up autosuspend" isn't quite clear whether we're configuring autosuspend, or if we're initiating an attempt to autosuspend (i.e., setting a timer). pm_runtime_barrier(): currently, we speak a lot about implementation details and sequences of events, but obscure the key point that it treats "pending resume" and "pending suspend" very differently -- I try to improve that. Signed-off-by: Brian Norris --- drivers/base/power/runtime.c | 65 +++++++++++++----------- include/linux/pm_runtime.h | 95 +++++++++++++++++++----------------- 2 files changed, 87 insertions(+), 73 deletions(-) diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c index ce7e08e628a2..f24b84757606 100644 --- a/drivers/base/power/runtime.c +++ b/drivers/base/power/runtime.c @@ -1101,14 +1101,13 @@ static int rpm_drop_usage_count(struct device *dev) } =20 /** - * __pm_runtime_idle - Entry point for runtime idle operations. + * __pm_runtime_idle - Core entry point for runtime idle operations. * @dev: Device to send idle notification for. * @rpmflags: Flag bits. * - * If the RPM_GET_PUT flag is set, decrement the device's usage count and - * return immediately if it is larger than zero (if it becomes negative, l= og a - * warning, increment it, and return an error). Then carry out an idle - * notification, either synchronous or asynchronous. + * Carry out an idle check for @dev, either synchronous or asynchronous. + * If %RPM_GET_PUT is set in @rpmflags, decrement the device's usage count + * first, proceeding with idle notification only if the counter drops to z= ero. * * This routine may be called in atomic context if the %RPM_ASYNC flag is = set, * or if pm_runtime_irq_safe() has been called. @@ -1139,14 +1138,13 @@ int __pm_runtime_idle(struct device *dev, int rpmfl= ags) EXPORT_SYMBOL_GPL(__pm_runtime_idle); =20 /** - * __pm_runtime_suspend - Entry point for runtime put/suspend operations. + * __pm_runtime_suspend - Core entry point for runtime put/suspend operati= ons. * @dev: Device to suspend. * @rpmflags: Flag bits. * - * If the RPM_GET_PUT flag is set, decrement the device's usage count and - * return immediately if it is larger than zero (if it becomes negative, l= og a - * warning, increment it, and return an error). Then carry out a suspend, - * either synchronous or asynchronous. + * Carry out a suspend operation for @dev, either synchronous or asynchron= ous. + * If %RPM_GET_PUT is set in @rpmflags, decrement the device's usage count + * first, proceeding with suspend only if the counter drops to zero. * * This routine may be called in atomic context if the %RPM_ASYNC flag is = set, * or if pm_runtime_irq_safe() has been called. @@ -1177,12 +1175,13 @@ int __pm_runtime_suspend(struct device *dev, int rp= mflags) EXPORT_SYMBOL_GPL(__pm_runtime_suspend); =20 /** - * __pm_runtime_resume - Entry point for runtime resume operations. + * __pm_runtime_resume - Core entry point for runtime resume operations. * @dev: Device to resume. * @rpmflags: Flag bits. * - * If the RPM_GET_PUT flag is set, increment the device's usage count. Th= en - * carry out a resume, either synchronous or asynchronous. + * Carry out a runtime resume operation for @dev, either synchronous or + * asynchronous. If %RPM_GET_PUT is set in @rpmflags, increment the device= 's + * usage count first, then bring the device to %RPM_ACTIVE state. * * This routine may be called in atomic context if the %RPM_ASYNC flag is = set, * or if pm_runtime_irq_safe() has been called. @@ -1276,17 +1275,15 @@ EXPORT_SYMBOL_GPL(pm_runtime_get_if_active); * pm_runtime_get_if_in_use - Conditionally bump up runtime PM usage count= er. * @dev: Target device. * - * Increment the runtime PM usage counter of @dev if its runtime PM status= is - * %RPM_ACTIVE and its runtime PM usage counter is greater than 0 or it is= not - * ignoring children and its active child count is nonzero. 1 is returned= in - * this case. - * - * If @dev is in a different state or it is not in use (that is, its usage - * counter is 0, or it is ignoring children, or its active child count is = 0), - * 0 is returned. + * Increment the runtime PM usage counter of @dev if it is "in use." A dev= ice + * is considered in use if its runtime PM status is %RPM_ACTIVE and its ru= ntime + * PM usage counter is greater than 0, or if it is not ignoring children a= nd + * its active child count is nonzero. * - * -EINVAL is returned if runtime PM is disabled for the device, in which = case - * also the usage counter of @dev is not updated. + * Return: + * * %-EINVAL: Runtime PM is disabled for @dev. The usage counter is not i= ncremented. + * * %1: Success; usage counter is incremented. + * * %0: @dev was not in use; usage counter is not incremented. */ int pm_runtime_get_if_in_use(struct device *dev) { @@ -1470,11 +1467,13 @@ static void __pm_runtime_barrier(struct device *dev) * pm_runtime_barrier - Flush pending requests and wait for completions. * @dev: Device to handle. * - * Prevent the device from being suspended by incrementing its usage count= er and - * if there's a pending resume request for the device, wake the device up. - * Next, make sure that all pending requests for the device have been flus= hed - * from pm_wq and wait for all runtime PM operations involving the device = in - * progress to complete. + * If the device has a pending resume request, resume it synchronously. Fo= r all + * other request types, cancel any queued request, and wait for running + * operations to complete. + * + * Note that this is intentionally asymmetric, as it guarantees any queued + * asynchronous resume request will complete, but it may cancel asynchrono= us + * suspend requests. */ void pm_runtime_barrier(struct device *dev) { @@ -1558,8 +1557,16 @@ void __pm_runtime_disable(struct device *dev, bool c= heck_resume) EXPORT_SYMBOL_GPL(__pm_runtime_disable); =20 /** - * pm_runtime_enable - Enable runtime PM of a device. + * pm_runtime_enable - Enable runtime PM for a device. * @dev: Device to handle. + * + * Enable runtime PM transitions for @dev by decrementing its disable coun= ter. + * Once the counter reaches zero, the PM core is permitted to execute runt= ime + * PM callbacks for @dev as power conditions change. + * + * Callers should ensure that the device's runtime PM status accurately re= flects + * its physical hardware state (via pm_runtime_set_active() or + * pm_runtime_set_suspended()) before enabling runtime PM. */ void pm_runtime_enable(struct device *dev) { diff --git a/include/linux/pm_runtime.h b/include/linux/pm_runtime.h index 1ffd9d5c3010..322e3b17f987 100644 --- a/include/linux/pm_runtime.h +++ b/include/linux/pm_runtime.h @@ -352,11 +352,11 @@ static inline int pm_runtime_force_resume(struct devi= ce *dev) { return -ENXIO; } #endif /* CONFIG_PM_SLEEP */ =20 /** - * pm_runtime_idle - Conditionally set up autosuspend of a device or suspe= nd it. + * pm_runtime_idle - Conditionally initiate autosuspend of a device or sus= pend it. * @dev: Target device. * * Invoke the "idle check" callback of @dev and, depending on its return v= alue, - * set up autosuspend of @dev or suspend it (depending on whether or not + * initiate autosuspend of @dev or suspend it (depending on whether or not * autosuspend has been enabled for it). * * Return: @@ -400,13 +400,13 @@ static inline int pm_runtime_suspend(struct device *d= ev) } =20 /** - * pm_runtime_autosuspend - Update the last access time and set up autosus= pend + * pm_runtime_autosuspend - Update the last access time and initiate autos= uspend * of a device. * @dev: Target device. * - * First update the last access time, then set up autosuspend of @dev or s= uspend - * it (depending on whether or not autosuspend is enabled for it) without - * engaging its "idle check" callback. + * First update the last access time, then initiate autosuspend of @dev or + * suspend it (depending on whether or not autosuspend is enabled for it) + * without engaging its "idle check" callback. * * Return: * * %1: Success; device was already suspended. @@ -442,11 +442,11 @@ static inline int pm_runtime_resume(struct device *de= v) } =20 /** - * pm_request_idle - Queue up "idle check" execution for a device. + * pm_request_idle - Request an asynchronous idle check for a device. * @dev: Target device. * - * Queue up a work item to run an equivalent of pm_runtime_idle() for @dev - * asynchronously. + * Asynchronously request the PM core to evaluate whether @dev can be idled + * or suspended, invoking its ->runtime_idle() callback if provided. * * Return: * * %0: Success. @@ -465,9 +465,12 @@ static inline int pm_request_idle(struct device *dev) } =20 /** - * pm_request_resume - Queue up runtime-resume of a device. + * pm_request_resume - Request an asynchronous runtime resume for a device. * @dev: Target device. * + * Asynchronously request the PM core to resume @dev to %RPM_ACTIVE state + * without modifying its usage counter. + * * Return: * * %1: Success; @dev is already %RPM_ACTIVE. * * %0: Success. @@ -479,12 +482,11 @@ static inline int pm_request_resume(struct device *de= v) } =20 /** - * pm_request_autosuspend - Update the last access time and queue up autos= uspend - * of a device. + * pm_request_autosuspend - Update access time and request delayed suspens= ion. * @dev: Target device. * - * Update the last access time of a device and queue up a work item to run= an - * equivalent pm_runtime_autosuspend() for @dev asynchronously. + * Update the last access time of @dev and asynchronously request the PM c= ore + * to suspend it after the autosuspend delay has elapsed. * * Return: * * %1: Success; device was already suspended. @@ -505,11 +507,11 @@ static inline int pm_request_autosuspend(struct devic= e *dev) } =20 /** - * pm_runtime_get - Bump up usage counter and queue up resume of a device. + * pm_runtime_get - Increment usage counter and request asynchronous resum= e. * @dev: Target device. * - * Bump up the runtime PM usage counter of @dev and queue up a work item to - * carry out runtime-resume of it. + * Increment the runtime PM usage counter of @dev and, if the device is + * currently suspended, asynchronously request the PM core to resume it. * * Return: * * %1: Success; @dev is already %RPM_ACTIVE. @@ -528,12 +530,10 @@ static inline int pm_runtime_get(struct device *dev) * Bump up the runtime PM usage counter of @dev and carry out runtime-resu= me of * it synchronously. * - * The possible return values of this function are the same as for - * pm_runtime_resume() and the runtime PM usage counter of @dev remains - * incremented in all cases, even if it returns an error code. - * Consider using pm_runtime_resume_and_get() instead of it, especially - * if its return value is checked by the caller, as this is likely to resu= lt - * in cleaner code. + * Note that the runtime PM usage counter of @dev remains incremented in a= ll + * cases, even if it returns an error code. Consider using + * pm_runtime_resume_and_get() instead, especially if the return value is + * checked by the caller, as this is likely to result in cleaner code. * * Return: * * %1: Success; @dev is already %RPM_ACTIVE. @@ -575,11 +575,12 @@ static inline int pm_runtime_resume_and_get(struct de= vice *dev) } =20 /** - * pm_runtime_put - Drop device usage counter and queue up "idle check" if= 0. + * pm_runtime_put - Drop device usage counter and request asynchronous idl= e check. * @dev: Target device. * - * Decrement the runtime PM usage counter of @dev and if it turns out to be - * equal to 0, queue up a work item for @dev like in pm_request_idle(). + * Decrement the runtime PM usage counter of @dev. If the counter reaches = zero + * and the device has no active child dependencies, asynchronously request= the + * PM core to idle or suspend the device. */ static inline void pm_runtime_put(struct device *dev) { @@ -611,13 +612,13 @@ static inline int __pm_runtime_put_autosuspend(struct= device *dev) } =20 /** - * pm_runtime_put_autosuspend - Update the last access time of a device, d= rop - * its usage counter and queue autosuspend if the usage counter becomes 0. + * pm_runtime_put_autosuspend - Update the last access time, drop usage co= unter + * and request autosuspend. * @dev: Target device. * - * Update the last access time of @dev, decrement runtime PM usage counter= of - * @dev and if it turns out to be equal to 0, queue up a work item for @de= v like - * in pm_request_autosuspend(). + * Update the last access time of @dev and decrement its runtime PM usage + * counter. If the counter drops to zero, asynchronously request the PM co= re to + * suspend the device once its autosuspend delay has elapsed. * * Return: * * %1: Success. Usage counter dropped to zero, but device was already su= spended. @@ -688,10 +689,12 @@ DEFINE_GUARD_COND(pm_runtime_active_auto, _try_enable= d, * pm_runtime_put_sync - Drop device usage counter and run "idle check" if= 0. * @dev: Target device. * - * Decrement the runtime PM usage counter of @dev and if it turns out to be - * equal to 0, invoke the "idle check" callback of @dev and, depending on = its - * return value, set up autosuspend of @dev or suspend it (depending on wh= ether - * or not autosuspend has been enabled for it). + * Decrement the runtime PM usage counter of @dev. If the counter drops to= zero, + * synchronously evaluate and trigger idle/suspend handling. + * + * Note that this does not update the last access time, but it does respect + * existing autosuspend timers. If @dev uses autosuspend, consider using + * pm_runtime_put_sync_autosuspend() or pm_runtime_put_sync_suspend() inst= ead. * * The runtime PM usage counter of @dev remains decremented in all cases, = even * if it returns an error code. @@ -718,8 +721,12 @@ static inline int pm_runtime_put_sync(struct device *d= ev) * pm_runtime_put_sync_suspend - Drop device usage counter and suspend if = 0. * @dev: Target device. * - * Decrement the runtime PM usage counter of @dev and if it turns out to be - * equal to 0, carry out runtime-suspend of @dev synchronously. + * Decrement the runtime PM usage counter of @dev. If the counter drops to= zero, + * suspend the device synchronously. + * + * This API differs from pm_runtime_put_sync() and + * pm_runtime_put_sync_autosuspend() in that it ignores any outstanding + * autosuspend delays. * * The runtime PM usage counter of @dev remains decremented in all cases, = even * if it returns an error code. @@ -747,10 +754,11 @@ static inline int pm_runtime_put_sync_suspend(struct = device *dev) * drop device usage counter and autosuspend if 0. * @dev: Target device. * - * Update the last access time of @dev, decrement the runtime PM usage cou= nter - * of @dev and if it turns out to be equal to 0, set up autosuspend of @de= v or - * suspend it synchronously (depending on whether or not autosuspend has b= een - * enabled for it). + * Update the last access time of @dev and decrement its runtime PM usage + * counter. If the counter drops to zero, synchronously suspend the device= (or + * schedule autosuspend if the delay has not elapsed). + * + * Prefer this API over pm_runtime_put_sync() for devices that use autosus= pend. * * The runtime PM usage counter of @dev remains decremented in all cases, = even * if it returns an error code. @@ -827,9 +835,8 @@ static inline int pm_runtime_set_suspended(struct devic= e *dev) * * If the counter is zero when this function runs and there is a pending r= untime * resume request for @dev, it will be resumed. If the counter is still z= ero at - * that point, all of the pending runtime PM requests for @dev will be can= celed - * and all runtime PM operations in progress involving it will be waited f= or to - * complete. + * that point, this function cancels all pending runtime PM requests for @= dev + * and waits for its runtime PM operations to complete (if any). * * For each invocation of this function for @dev, there must be a matching * pm_runtime_enable() call, so that runtime PM is eventually enabled for = it --=20 2.55.0.979.g7e5102b832-goog From nobody Sat Sep 26 03:12:00 2026 Received: from mail-pg1-f181.google.com (mail-pg1-f181.google.com [209.85.215.181]) (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 73C16366553 for ; Fri, 4 Sep 2026 21:20:30 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.215.181 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788556832; cv=none; b=fxUNi/l4U+kC6+STx8z0i01s1phUVq2eZOow5e351j4l7/bBOnchskzxsneVlsJxrUN7TkDKAYr/CquWonrES8DVWG3zvvpAq1JYH+p07zV/dhkEiS3Vt0uEOpB3NYw+rvwnIDMAAQJsFmaK9hykfWTjq3nc5DrsO1FYGN70bAc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788556832; c=relaxed/simple; bh=wHt8CgT1P0RNc7F6QrmjRIV/zR3o86+dVdAliaBmpiU=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=R8JMPDT1hXbWMORv6NUklAeQOfFyBQy4uAJEwOt0XePmDdXm17afnh4zz5Lu0fUXS1g3in+7BDOvanE56SP86r4Nt0uuBHtEeOkXEEICPSA4y3x8MqA15lvGUEJ2+uyJRy0cRGd+HughJq8F4iLiNHZRSfXNOmsk6qX7sSOVLCk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=chromium.org; spf=pass smtp.mailfrom=chromium.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b=QTgV4X0r; arc=none smtp.client-ip=209.85.215.181 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=chromium.org Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=chromium.org Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b="QTgV4X0r" Received: by mail-pg1-f181.google.com with SMTP id 41be03b00d2f7-cc1c8d4a959so1112541a12.3 for ; Fri, 04 Sep 2026 14:20:30 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; t=1788556830; x=1789161630; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=hiuf8CN7cTb9FarsrDvFqalXR9R3H1JNJ1T35r1Vjm0=; b=QTgV4X0rXy4TbfQpfylR6S7F0sNzzzL71xAGe64dURYRJlY6Pr3R56jJuOMuMKoPvB g7o2T0XWnrumRAXvsmmNZiI0crw8Nz9RzQ+kAJp84IMQvBnkcldXS3FVl5gnO5achc60 omJ23Dcv2H9+B2OsdwJIarRNEeFO8XefSEu70= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1788556830; x=1789161630; h=content-transfer-encoding:mime-version:references:in-reply-to :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=hiuf8CN7cTb9FarsrDvFqalXR9R3H1JNJ1T35r1Vjm0=; b=PvKI36HP4OqrLKAVXcvlx11aKHp17h7Y27MJNAgR+UPgc/EwRxrx31kn4C9ac+S3V4 5u5ZkQrGhFPaC3wUNWjhlGMP9YUpa6n7vBVljJVhKchrQ2QwPwIbSkkGLM6FjhHCjkTH A8l1CJEV33s4OpwfQte7MLoi0diRU+tj8PfcnLEzyQjDsbfXjX1/qnTo0FXE7xgigOsO PB7umKQg3EiuNXCBJin0fIrkD3SiP3R9iw/NIpYFeAld3Nrq1gwLcivC8wwadPFkkA6D Vwmw6vLB4k5odFlb5rPzk295cJL9+yjxd5XihgHkWvQXxFRiODPy7Fm5/jhyIc3gGQkk QVSA== X-Gm-Message-State: AFuF++l0LAIvMquSBKa2xAA6fZmJMO5Ee83dtZ8DaeUYZ0zOM7BJsXWp 4T7L8wRxOkH/ydoMR3oeOc9qgAeihYryoWhBcHT71fH2uoYWXZhycTt3WX2ndPjEdg== X-Gm-Gg: AYBFou1LuYZZ0eaCHTvviIqB2EbZzedhguW+tcBUKP0QvONLT+emkCBj/EJ7gC9gfyL jQyvg2ah9ofWxeO3iHzNgQV9NXcEEXg7Mmm5kRWuakw494BqPGzujeIDsaW4wcaFW7i45bO5+Qt IEO+vVO7jEmybk01d2W8ErYtvYgD7wndA+B+F+4hvQox5fxK41BRdOmQ9ODT20EVysDli2zOom3 0XV5odTPJTlrdXmH05J9p8iCDgf/OOzyDYHSmEaWGeV2FToM9KndazQanQtyg50COhEtR1Aq5xi ZrO0DadRXJLC1NIaSD+qKmpeouMgu0Zb8prLIuwVk3yOfCpjrwWM5Pv/6NB3/5sn6xewrpKkxOA 1N+61smC3k4OrlP+0fyLkeCBxTFJwoAV99pdt5NaMT5/UJv3POy5SqvZyPaEJLpzueCrKqpC5C/ g9siI4LIG6c/LOgYyBLAbZerlLbnD3bgrpSEN/Vsp5N02+JNKlRNgDjSsh9GLUoo5SNo73qh6LT FVCUj3BYxHKAMp7O4f85Lb1NHSLFlVsxd2MA/EV7Ig+QA6UCA== X-Received: by 2002:a17:90b:39a7:b0:398:9bd1:3211 with SMTP id 98e67ed59e1d1-39b262ab182mr12456467a91.18.1788556828297; Fri, 04 Sep 2026 14:20:28 -0700 (PDT) Received: from localhost ([2a00:79e0:2e7c:8:5597:62ab:c321:4a7f]) by smtp.gmail.com with UTF8SMTPSA id a92af1059eb24-143243bfbe3sm8877459c88.11.2026.09.04.14.20.26 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Fri, 04 Sep 2026 14:20:27 -0700 (PDT) From: Brian Norris To: "Rafael J . Wysocki" Cc: linux-kernel@vger.kernel.org, Len Brown , Ulf Hansson , linux-pm@vger.kernel.org, Pavel Machek , Doug Anderson , Brian Norris Subject: [PATCH 04/11] PM: runtime: Pull API docs from kerneldoc Date: Fri, 4 Sep 2026 14:12:09 -0700 Message-ID: <20260904141215.4.I2cb2c43192ef46bd9dfad6699080d8a1d56756d5@changeid> X-Mailer: git-send-email 2.55.0.979.g7e5102b832-goog In-Reply-To: <20260904212000.4167880-1-briannorris@chromium.org> References: <20260904212000.4167880-1-briannorris@chromium.org> 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" This avoids staleness and duplication, as the same APIs were previously documented twice. Signed-off-by: Brian Norris --- Documentation/power/runtime_pm.rst | 280 +---------------------------- 1 file changed, 6 insertions(+), 274 deletions(-) diff --git a/Documentation/power/runtime_pm.rst b/Documentation/power/runti= me_pm.rst index a53ab09c37d5..380dad7590a9 100644 --- a/Documentation/power/runtime_pm.rst +++ b/Documentation/power/runtime_pm.rst @@ -307,219 +307,10 @@ All of the above fields are members of the 'power' m= ember of 'struct device'. The following runtime PM helper functions are defined in drivers/base/power/runtime.c and include/linux/pm_runtime.h: =20 - `void pm_runtime_init(struct device *dev);` - - initialize the device runtime PM fields in 'struct dev_pm_info' - - `void pm_runtime_remove(struct device *dev);` - - make sure that the runtime PM of the device will be disabled after - removing the device from device hierarchy - - `int pm_runtime_idle(struct device *dev);` - - execute the subsystem-level idle callback for the device; returns an - error code on failure, where -EINPROGRESS means that ->runtime_idle(= ) is - already being executed; if there is no callback or the callback retu= rns 0 - then run pm_runtime_autosuspend(dev) and return its result - - `int pm_runtime_suspend(struct device *dev);` - - execute the subsystem-level suspend callback for the device; returns= 0 on - success, 1 if the device's runtime PM status was already 'suspended'= , or - error code on failure, where -EAGAIN or -EBUSY means it is safe to a= ttempt - to suspend the device again in future and -EACCES means that - 'power.disable_depth' is different from 0 - - `int pm_runtime_autosuspend(struct device *dev);` - - same as pm_runtime_suspend() except that a call to - pm_runtime_mark_last_busy() is made and an autosuspend is scheduled = for - the appropriate time and 0 is returned - - `int pm_runtime_resume(struct device *dev);` - - execute the subsystem-level resume callback for the device; returns = 0 on - success, 1 if the device's runtime PM status is already 'active' (al= so if - 'power.disable_depth' is nonzero, but the status was 'active' when i= t was - changing from 0 to 1) or error code on failure, where -EAGAIN means = it may - be safe to attempt to resume the device again in future, but - 'power.runtime_error' should be checked additionally, and -EACCES me= ans - that the callback could not be run, because 'power.disable_depth' was - different from 0 - - `int pm_runtime_resume_and_get(struct device *dev);` - - run pm_runtime_resume(dev) and if successful, increment the device's - usage counter; returns 0 on success (whether or not the device's - runtime PM status was already 'active') or the error code from - pm_runtime_resume() on failure. - - `int pm_request_idle(struct device *dev);` - - submit a request to execute the subsystem-level idle callback for the - device (the request is represented by a work item in pm_wq); returns= 0 on - success or error code if the request has not been queued up - - `int pm_request_autosuspend(struct device *dev);` - - Call pm_runtime_mark_last_busy() and schedule the execution of the - subsystem-level suspend callback for the device when the autosuspend= delay - expires - - `int pm_schedule_suspend(struct device *dev, unsigned int delay);` - - schedule the execution of the subsystem-level suspend callback for t= he - device in future, where 'delay' is the time to wait before queuing u= p a - suspend work item in pm_wq, in milliseconds (if 'delay' is zero, the= work - item is queued up immediately); returns 0 on success, 1 if the devic= e's PM - runtime status was already 'suspended', or error code if the request - hasn't been scheduled (or queued up if 'delay' is 0); if the executi= on of - ->runtime_suspend() is already scheduled and not yet expired, the new - value of 'delay' will be used as the time to wait - - `int pm_request_resume(struct device *dev);` - - submit a request to execute the subsystem-level resume callback for = the - device (the request is represented by a work item in pm_wq); returns= 0 on - success, 1 if the device's runtime PM status was already 'active', or - error code if the request hasn't been queued up - - `void pm_runtime_get_noresume(struct device *dev);` - - increment the device's usage counter - - `int pm_runtime_get(struct device *dev);` - - increment the device's usage counter, run pm_request_resume(dev) and - return its result - - `int pm_runtime_get_sync(struct device *dev);` - - increment the device's usage counter, run pm_runtime_resume(dev) and - return its result; - note that it does not drop the device's usage counter on errors, so - consider using pm_runtime_resume_and_get() instead of it, especially - if its return value is checked by the caller, as this is likely to - result in cleaner code. - - `int pm_runtime_get_if_in_use(struct device *dev);` - - return -EINVAL if 'power.disable_depth' is nonzero; otherwise, if the - runtime PM status is RPM_ACTIVE and the runtime PM usage counter is - nonzero, increment the counter and return 1; otherwise return 0 with= out - changing the counter - - `int pm_runtime_get_if_active(struct device *dev);` - - return -EINVAL if 'power.disable_depth' is nonzero; otherwise, if the - runtime PM status is RPM_ACTIVE, increment the counter and - return 1; otherwise return 0 without changing the counter - - `void pm_runtime_put_noidle(struct device *dev);` - - decrement the device's usage counter - - `int pm_runtime_put(struct device *dev);` - - decrement the device's usage counter; if the result is 0 then run - pm_request_idle(dev) and return its result - - `int pm_runtime_put_autosuspend(struct device *dev);` - - set the power.last_busy field to the current time and decrement the - device's usage counter; if the result is 0 then run - pm_request_autosuspend(dev) and return its result - - `int __pm_runtime_put_autosuspend(struct device *dev);` - - decrement the device's usage counter; if the result is 0 then run - pm_request_autosuspend(dev) and return its result - - `int pm_runtime_put_sync(struct device *dev);` - - decrement the device's usage counter; if the result is 0 then run - pm_runtime_idle(dev) and return its result - - `int pm_runtime_put_sync_suspend(struct device *dev);` - - decrement the device's usage counter; if the result is 0 then run - pm_runtime_suspend(dev) and return its result - - `int pm_runtime_put_sync_autosuspend(struct device *dev);` - - set the power.last_busy field to the current time and decrement the - device's usage counter; if the result is 0 then run - pm_runtime_autosuspend(dev) and return its result - - `void pm_runtime_enable(struct device *dev);` - - decrement the device's 'power.disable_depth' field; if that field is= equal - to zero, the runtime PM helper functions can execute subsystem-level - callbacks described in Section 2 for the device - - `int pm_runtime_disable(struct device *dev);` - - increment the device's 'power.disable_depth' field (if the value of = that - field was previously zero, this prevents subsystem-level runtime PM - callbacks from being run for the device), make sure that all of the - pending runtime PM operations on the device are either completed or - canceled; returns 1 if there was a resume request pending and it was - necessary to execute the subsystem-level resume callback for the dev= ice - to satisfy that request, otherwise 0 is returned - - `void pm_runtime_barrier(struct device *dev);` - - check if there's a resume request pending for the device and resume = it - (synchronously) in that case, cancel any other pending runtime PM re= quests - regarding it and wait for all runtime PM operations on it in progres= s to - complete - - `void pm_suspend_ignore_children(struct device *dev, bool enable);` - - set/unset the power.ignore_children flag of the device - - `int pm_runtime_set_active(struct device *dev);` - - clear the device's 'power.runtime_error' flag, set the device's runt= ime - PM status to 'active' and update its parent's counter of 'active' - children as appropriate (it is only valid to use this function if - 'power.runtime_error' is set or 'power.disable_depth' is greater than - zero); it will fail and return error code if the device has a parent - which is not active and the 'power.ignore_children' flag of which is= unset - - `void pm_runtime_set_suspended(struct device *dev);` - - clear the device's 'power.runtime_error' flag, set the device's runt= ime - PM status to 'suspended' and update its parent's counter of 'active' - children as appropriate (it is only valid to use this function if - 'power.runtime_error' is set or 'power.disable_depth' is greater than - zero) - - `bool pm_runtime_active(struct device *dev);` - - return true if the device's runtime PM status is 'active' or its - 'power.disable_depth' field is not equal to zero, or false otherwise - - `bool pm_runtime_suspended(struct device *dev);` - - return true if the device's runtime PM status is 'suspended' and its - 'power.disable_depth' field is equal to zero, or false otherwise - - `bool pm_runtime_status_suspended(struct device *dev);` - - return true if the device's runtime PM status is 'suspended' - - `void pm_runtime_no_callbacks(struct device *dev);` - - set the power.no_callbacks flag for the device and remove the runtime - PM attributes from /sys/devices/.../power (or prevent them from being - added when the device is registered) - - `void pm_runtime_irq_safe(struct device *dev);` - - set the power.irq_safe flag for the device, causing the runtime-PM - callbacks to be invoked with interrupts off - - `bool pm_runtime_is_irq_safe(struct device *dev);` - - return true if power.irq_safe flag was set for the device, causing - the runtime-PM callbacks to be invoked with interrupts off - - `void pm_runtime_mark_last_busy(struct device *dev);` - - set the power.last_busy field to the current time - - `void pm_runtime_use_autosuspend(struct device *dev);` - - set the power.use_autosuspend flag, enabling autosuspend delays; call - pm_runtime_get_sync if the flag was previously cleared and - power.autosuspend_delay is negative - - `void pm_runtime_dont_use_autosuspend(struct device *dev);` - - clear the power.use_autosuspend flag, disabling autosuspend delays; - decrement the device's usage counter if the flag was previously set = and - power.autosuspend_delay is negative; call pm_runtime_idle - - `void pm_runtime_set_autosuspend_delay(struct device *dev, int delay);` - - set the power.autosuspend_delay value to 'delay' (expressed in - milliseconds); if 'delay' is negative then runtime suspends are - prevented; if power.use_autosuspend is set, pm_runtime_get_sync may = be - called or the device's usage counter may be decremented and - pm_runtime_idle called depending on if power.autosuspend_delay is - changed to or from a negative value; if power.use_autosuspend is cle= ar, - pm_runtime_idle is called - - `unsigned long pm_runtime_autosuspend_expiration(struct device *dev);` - - calculate the time when the current autosuspend delay period will ex= pire, - based on power.last_busy and power.autosuspend_delay; if the delay t= ime - is 1000 ms or larger then the expiration time is rounded up to the - nearest second; returns 0 if the delay period has already expired or - power.use_autosuspend isn't set, otherwise returns the expiration ti= me - in jiffies +.. kernel-doc:: drivers/base/power/runtime.c + :export: + +.. kernel-doc:: include/linux/pm_runtime.h =20 It is safe to execute the following helper functions from interrupt contex= t: =20 @@ -728,67 +519,8 @@ Subsystems may wish to conserve code space by using th= e set of generic power management callbacks provided by the PM core, defined in driver/base/power/generic_ops.c: =20 - `int pm_generic_runtime_suspend(struct device *dev);` - - invoke the ->runtime_suspend() callback provided by the driver of th= is - device and return its result, or return 0 if not defined - - `int pm_generic_runtime_resume(struct device *dev);` - - invoke the ->runtime_resume() callback provided by the driver of this - device and return its result, or return 0 if not defined - - `int pm_generic_suspend(struct device *dev);` - - if the device has not been suspended at run time, invoke the ->suspe= nd() - callback provided by its driver and return its result, or return 0 i= f not - defined - - `int pm_generic_suspend_noirq(struct device *dev);` - - if pm_runtime_suspended(dev) returns "false", invoke the ->suspend_n= oirq() - callback provided by the device's driver and return its result, or r= eturn - 0 if not defined - - `int pm_generic_resume(struct device *dev);` - - invoke the ->resume() callback provided by the driver of this device= and, - if successful, change the device's runtime PM status to 'active' - - `int pm_generic_resume_noirq(struct device *dev);` - - invoke the ->resume_noirq() callback provided by the driver of this = device - - `int pm_generic_freeze(struct device *dev);` - - if the device has not been suspended at run time, invoke the ->freez= e() - callback provided by its driver and return its result, or return 0 i= f not - defined - - `int pm_generic_freeze_noirq(struct device *dev);` - - if pm_runtime_suspended(dev) returns "false", invoke the ->freeze_no= irq() - callback provided by the device's driver and return its result, or r= eturn - 0 if not defined - - `int pm_generic_thaw(struct device *dev);` - - if the device has not been suspended at run time, invoke the ->thaw() - callback provided by its driver and return its result, or return 0 i= f not - defined - - `int pm_generic_thaw_noirq(struct device *dev);` - - if pm_runtime_suspended(dev) returns "false", invoke the ->thaw_noir= q() - callback provided by the device's driver and return its result, or r= eturn - 0 if not defined - - `int pm_generic_poweroff(struct device *dev);` - - if the device has not been suspended at run time, invoke the ->power= off() - callback provided by its driver and return its result, or return 0 i= f not - defined - - `int pm_generic_poweroff_noirq(struct device *dev);` - - if pm_runtime_suspended(dev) returns "false", run the ->poweroff_noi= rq() - callback provided by the device's driver and return its result, or r= eturn - 0 if not defined - - `int pm_generic_restore(struct device *dev);` - - invoke the ->restore() callback provided by the driver of this devic= e and, - if successful, change the device's runtime PM status to 'active' - - `int pm_generic_restore_noirq(struct device *dev);` - - invoke the ->restore_noirq() callback provided by the device's driver +.. kernel-doc:: drivers/base/power/generic_ops.c + :export: =20 These functions are the defaults used by the PM core if a subsystem doesn't provide its own callbacks for ->runtime_idle(), ->runtime_suspend(), --=20 2.55.0.979.g7e5102b832-goog From nobody Sat Sep 26 03:12:00 2026 Received: from mail-pj1-f43.google.com (mail-pj1-f43.google.com [209.85.216.43]) (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 F05623B7B97 for ; Fri, 4 Sep 2026 21:20:31 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.216.43 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788556833; cv=none; b=fsuh1qiTVv67iWrUHoD6RUyaE2q9gT9s9uDdocYIFgKwXqVeBY8Ixr8ghcbOBOuxR1Z0T9w/gOZEtmpAqagWiYe78i7TFSw321N+dScQ7XqQuyW6Imvr7Vo0/NFgPs8rOZDCG60MzM1Z8yiqd/Hy2BtQHfCOwekmdFdII7Loy08= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788556833; c=relaxed/simple; bh=LZEKoVQoRx81lyPvfBjCOIdhqvTqx4i0RZu0XcYnujU=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=ZprSch/QekFjzd+wYOW4M/4600IM8HQt9bUYOeozWxcUtQT7pLHqjheWyli4nSh8MJKTkDCrkNs2Vlp9HPMwfMJsdblmJPeM5+478ketpZO0qN6PAjAOiODbLAD6hmUEl/yy4fLsRhPy2MJpXjwRbRMwb4B+6Fwq5iOAChgqFZ4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=chromium.org; spf=pass smtp.mailfrom=chromium.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b=M5KQG5a3; arc=none smtp.client-ip=209.85.216.43 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=chromium.org Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=chromium.org Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b="M5KQG5a3" Received: by mail-pj1-f43.google.com with SMTP id 98e67ed59e1d1-38e58034d05so1299707a91.2 for ; Fri, 04 Sep 2026 14:20:31 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; t=1788556831; x=1789161631; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=S6HoEZQGU9N+yQkXXBJTBMgHTLQ2Iz13P65ihXGvgEQ=; b=M5KQG5a3kJ0GQhO/QbsBwPa7tsLISkEr9/S1Gu1o3Mw1IUklkbU2Ynj+MfbGePNRee Bz10+hBnigEyYA0TBMWj54IhJz6dxY9NgOZ9oEzcYQocC9vWLGPkjVbMzOiLv+NACFfW DFKwdTTmyQmmA/YnxzpxoWixOQK8o/0cNyMPs= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1788556831; x=1789161631; h=content-transfer-encoding:mime-version:references:in-reply-to :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=S6HoEZQGU9N+yQkXXBJTBMgHTLQ2Iz13P65ihXGvgEQ=; b=oV6s9vAULl3mrB2X11lMNSgNdO/RuR/021PI4PrRIU8/cPZz2Dq2qJPkjeAnSntEhQ jquSj+3ll7z2c5i77yd/O16P+1qrW/CsqAHymeQt/5kJHupFKC88PlKnbsQYLGLrKK// L1e2G4vBkZ6qwf6o+2gNM/iZThsuKO+nA0FveJyDL1FuwmQye4WvMghpJzZLeWHeD+yt JGOkvIOAHPFxAybv9IAOndvl0YtrFesEOMGDGrnkJjHZXoB0zV3YcBd7cCoqgACayvc4 rlXBHn5WMx1oS2+EWiuhg5lBXRqIY3r5cTuZGEplbS/hpQWmGg8QhSuGLmkyP/Qemzvd 5/Tg== X-Gm-Message-State: AFuF++kTwoKTLJWNsGQYb2ZV+StApXBvBZbtLh16NovbmwEPzneDvWiY Gjc8sQ5AFnlGKb0KceNwjTjW9whyDfcGigLPmQH6wcIy+EcDOTluqM48QJ3GGiAESA== X-Gm-Gg: AYBFou0r6jlyk/Tt2Q0XObF+hduQDo1uHuJIXi8ySs4WTwK3sqdumS50sbRmP2W0fMM GgFn4uoc0eXUUbKWyaMnhPvayuGQt5Vgust+7Gvg5JHtDeyJWiudtUZxIx4snlCSigZ7VGfLmga dnZ2o+hhoL5r8Dvh3eTA1Pfqz9msnWNYdPANK8Irtyb0NxfqccyTsqiFJf22RpJkEAt9zXLuU53 3zT5CfA2mgp5I00Y9wB+PEmv+hXGJRHKtm6XAD4hyAjM9ls91L+ohMP0yntYVzoyCt/AgdH5l79 IMPFDoh2/+bQyE6Psys8QgKM9HryNIxEUGdH6Ysq3QkfQx07uuvlWhJxC8RTHg2ik8/tyy40Pge p3uk5S4T3v7J9kbihpBw17rIZbgQlo9et3s1vnocAqfd3rqZzZK+BIOGVeKp/We6k1F9bmN23kZ tD4q1AmQ96RPuLqbq+cHRzYQW/RTz3pD9gTi6gIb7url1dVdL13MGH94WjjdSgSdd5I2sH0qCMa s3frYhgipk9th8VuBRVIIFA7uk= X-Received: by 2002:a17:90b:5705:b0:36d:9e0b:3801 with SMTP id 98e67ed59e1d1-39b2617ed3bmr15450076a91.8.1788556831176; Fri, 04 Sep 2026 14:20:31 -0700 (PDT) Received: from localhost ([2a00:79e0:2e7c:8:5597:62ab:c321:4a7f]) by smtp.gmail.com with UTF8SMTPSA id a92af1059eb24-143243767e1sm7834797c88.6.2026.09.04.14.20.29 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Fri, 04 Sep 2026 14:20:30 -0700 (PDT) From: Brian Norris To: "Rafael J . Wysocki" Cc: linux-kernel@vger.kernel.org, Len Brown , Ulf Hansson , linux-pm@vger.kernel.org, Pavel Machek , Doug Anderson , Brian Norris Subject: [PATCH 05/11] PM: core: Document struct dev_pm_info with kerneldoc Date: Fri, 4 Sep 2026 14:12:10 -0700 Message-ID: <20260904141215.5.Ib0272869f8b1178426106d911441c449ac299048@changeid> X-Mailer: git-send-email 2.55.0.979.g7e5102b832-goog In-Reply-To: <20260904212000.4167880-1-briannorris@chromium.org> References: <20260904212000.4167880-1-briannorris@chromium.org> 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" Documentation/power/runtime_pm.rst includes several descriptions of dev_pm_info fields, but many of them are wrong these days, as the types or behaviors have changed. This is a prime reason for keeping docs closer to the code where possible. Adapt and rewrite some of these descriptions, and add them to include/linux/pm.h directly. Then pull these docs into the generated HTML. Tested with `make htmldocs`. Signed-off-by: Brian Norris --- Documentation/power/runtime_pm.rst | 101 ++--------------------------- include/linux/pm.h | 93 ++++++++++++++++++++++++++ 2 files changed, 98 insertions(+), 96 deletions(-) diff --git a/Documentation/power/runtime_pm.rst b/Documentation/power/runti= me_pm.rst index 380dad7590a9..39fdeeda7a1e 100644 --- a/Documentation/power/runtime_pm.rst +++ b/Documentation/power/runtime_pm.rst @@ -203,103 +203,12 @@ rules: 3. Runtime PM Device Fields =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D =20 -The following device runtime PM fields are present in 'struct dev_pm_info'= , as -defined in include/linux/pm.h: +Device PM fields are found in 'struct dev_pm_info', as defined in +include/linux/pm.h. Many of those fields track runtime PM configuration and +state. =20 - `struct timer_list suspend_timer;` - - timer used for scheduling (delayed) suspend and autosuspend requests - - `unsigned long timer_expires;` - - timer expiration time, in jiffies (if this is different from zero, t= he - timer is running and will expire at that time, otherwise the timer i= s not - running) - - `struct work_struct work;` - - work structure used for queuing up requests (i.e. work items in pm_w= q) - - `wait_queue_head_t wait_queue;` - - wait queue used if any of the helper functions needs to wait for ano= ther - one to complete - - `spinlock_t lock;` - - lock used for synchronization - - `atomic_t usage_count;` - - the usage counter of the device - - `atomic_t child_count;` - - the count of 'active' children of the device - - `unsigned int ignore_children;` - - if set, the value of child_count is ignored (but still updated) - - `unsigned int disable_depth;` - - used for disabling the helper functions (they work normally if this = is - equal to zero); the initial value of it is 1 (i.e. runtime PM is - initially disabled for all devices) - - `int runtime_error;` - - if set, there was a fatal error (one of the callbacks returned error= code - as described in Section 2), so the helper functions will not work un= til - this flag is cleared; this is the error code returned by the failing - callback - - `unsigned int idle_notification;` - - if set, ->runtime_idle() is being executed - - `unsigned int request_pending;` - - if set, there's a pending request (i.e. a work item queued up into p= m_wq) - - `enum rpm_request request;` - - type of request that's pending (valid if request_pending is set) - - `unsigned int deferred_resume;` - - set if ->runtime_resume() is about to be run while ->runtime_suspend= () is - being executed for that device and it is not practical to wait for t= he - suspend to complete; means "start a resume as soon as you've suspend= ed" - - `enum rpm_status runtime_status;` - - the runtime PM status of the device; this field's initial value is - RPM_SUSPENDED, which means that each device is initially regarded by= the - PM core as 'suspended', regardless of its real hardware status - - `enum rpm_status last_status;` - - the last runtime PM status of the device captured before disabling r= untime - PM for it (invalid initially and when disable_depth is 0) - - `unsigned int runtime_auto;` - - if set, indicates that the user space has allowed the device driver = to - power manage the device at run time via the /sys/devices/.../power/c= ontrol - `interface;` it may only be modified with the help of the - pm_runtime_allow() and pm_runtime_forbid() helper functions - - `unsigned int no_callbacks;` - - indicates that the device does not use the runtime PM callbacks (see - Section 8); it may be modified only by the pm_runtime_no_callbacks() - helper function - - `unsigned int irq_safe;` - - indicates that the ->runtime_suspend() and ->runtime_resume() callba= cks - will be invoked with the spinlock held and interrupts disabled - - `unsigned int use_autosuspend;` - - indicates that the device's driver supports delayed autosuspend (see - Section 9); it may be modified only by the - pm_runtime{_dont}_use_autosuspend() helper functions - - `unsigned int timer_autosuspends;` - - indicates that the PM core should attempt to carry out an autosuspend - when the timer expires rather than a normal suspend - - `int autosuspend_delay;` - - the delay time (in milliseconds) to be used for autosuspend - - `unsigned long last_busy;` - - the time (in jiffies) when the pm_runtime_mark_last_busy() helper - function was last called for this device; used in calculating inacti= vity - periods for autosuspend - -All of the above fields are members of the 'power' member of 'struct devic= e'. +.. kernel-doc:: include/linux/pm.h + :identifiers: dev_pm_info =20 4. Runtime PM Device Helper Functions =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D diff --git a/include/linux/pm.h b/include/linux/pm.h index afcaaa37a812..ef3f1310e749 100644 --- a/include/linux/pm.h +++ b/include/linux/pm.h @@ -663,6 +663,99 @@ struct pm_subsys_data { #define DPM_FLAG_SMART_SUSPEND BIT(2) #define DPM_FLAG_MAY_SKIP_RESUME BIT(3) =20 +/** + * struct dev_pm_info - Device power management information. + * + * @power_state: Legacy power state (mostly unused in modern kernels). + * @can_wakeup: Device is capable of generating wakeup signals. + * @async_suspend: Device can be suspended and resumed asynchronously. + * @in_dpm_list: Device is on the dpm_list. + * @is_prepared: Device's ->prepare() callback has run successfully. + * @is_suspended: Device is suspended during a system sleep transition. + * @is_noirq_suspended: Device's noirq suspend callback has run successful= ly. + * @is_late_suspended: Device's late suspend callback has run successfully. + * @no_pm: Device does not participate in power management transitions. + * @early_init: Device was initialized before standard PM initialization. + * @direct_complete: Device can skip suspend/resume callbacks and remain + * runtime-suspended during system sleep. + * @driver_flags: Driver flags (e.g. %DPM_FLAG_SMART_SUSPEND) set at probe= time. + * @lock: Spinlock used for synchronizing PM state transitions and runtime= PM + * operations. + * @entry: List head for device power management lists. + * @completion: Completion for synchronization during asynchronous system + * suspend/resume. + * @wakeup: Wakeup source object associated with the device. + * @work_in_progress: Asynchronous PM operation in progress. + * @wakeup_path: Device is in the wakeup path or can wake the system up. + * @syscore: Device participates in syscore power management operations. + * @no_pm_callbacks: Device has no PM callbacks; handled by parent or subs= ystem. + * @smart_suspend: Driver requested smart-suspend behavior. + * @must_resume: Device must be resumed during system resume. + * @may_skip_resume: Set by subsystems to indicate driver resume callbacks= may + * be skipped. + * @out_band_wakeup: Out-of-band wakeup is supported. + * @strict_midlayer: Middle layer code does not want callbacks invoked via + * pm_runtime_force_suspend() / pm_runtime_force_resume(). + * @should_wakeup: Wakeup flag when system sleep is not enabled. + * @suspend_timer: High-resolution timer used for scheduling delayed runti= me + * suspend and autosuspend requests. + * @timer_expires: Timer expiration time in nanoseconds monotonic time + * (runtime PM). + * @work: Work structure used for queuing up requests into pm_wq (runtime = PM). + * @wait_queue: Wait queue used if any helper functions need to wait for a= nother + * state change to complete (runtime PM). + * @wakeirq: Dedicated wakeup interrupt for the device. + * @usage_count: Device runtime PM usage counter. + * @child_count: Count of active children of the device (runtime PM). + * @disable_depth: Disable counter for runtime PM (runtime PM is enabled w= hen + * this is 0; initial value is 1). + * @idle_notification: Set if ->runtime_idle() is being executed. + * @request_pending: Set if a work item is queued into pm_wq (runtime PM). + * @deferred_resume: Set if ->runtime_resume() should run as soon as + * ->runtime_suspend() completes. + * @needs_force_resume: Indicates the device was forced into suspend by + * pm_runtime_force_suspend() and must be resumed by + * pm_runtime_force_resume(). + * @runtime_auto: User space has allowed the driver to power manage the de= vice + * at runtime via sysfs control attribute; also can be set by + * pm_runtime_allow() or pm_runtime_forbid(). + * @ignore_children: If set, the value of child_count is ignored for runti= me + * suspend and idle decisions. + * @no_callbacks: Indicates the device does not use runtime PM callbacks. + * @irq_safe: Indicates runtime PM callbacks will be invoked with the spin= lock + * held and interrupts disabled. + * @use_autosuspend: Indicates the device driver supports delayed runtime + * autosuspend. + * @timer_autosuspends: Indicates the runtime PM core should attempt an + * autosuspend rather than a normal suspend when the timer expires. + * @memalloc_noio: Indicates memory allocation during runtime PM transitio= ns + * must avoid I/O (GFP_NOIO). + * @links_count: Number of device links that require runtime PM coordinati= on. + * @request: Type of pending runtime PM request (valid if request_pending = is + * set). + * @runtime_status: Runtime PM status of the device. + * @last_status: Last status captured before disabling runtime PM, or + * %RPM_BLOCKED / %RPM_INVALID. + * @runtime_error: Fatal error code returned by a failing callback, blocki= ng + * helpers until cleared. + * @autosuspend_delay: Delay time in milliseconds to be used for runtime + * autosuspend. + * @last_busy: Timestamp in nanoseconds when pm_runtime_mark_last_busy() w= as + * last called. Used in calculating inactivity periods for autosuspend. + * @active_time: Accumulated time in nanoseconds spent in %RPM_ACTIVE stat= e. + * @suspended_time: Accumulated time in nanoseconds spent in %RPM_SUSPENDED + * state. + * @accounting_timestamp: Timestamp in nanoseconds of the last runtime PM = state + * accounting update. + * @subsys_data: Subsystem-specific power management data. + * @set_latency_tolerance: Callback for setting latency tolerance. + * @qos: Per-device PM Quality of Service (QoS) constraints. + * @detach_power_off: Indicates device should be detached from PM domain on + * power off. + * + * Device power management information stored in the "power" member of str= uct + * device. + */ struct dev_pm_info { pm_message_t power_state; bool can_wakeup:1; --=20 2.55.0.979.g7e5102b832-goog From nobody Sat Sep 26 03:12:00 2026 Received: from mail-pl1-f182.google.com (mail-pl1-f182.google.com [209.85.214.182]) (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 086B152E07C for ; Fri, 4 Sep 2026 21:20:35 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.182 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788556837; cv=none; b=D62SkVVED3vNWwatQCMZhtEhM5MW2fDIJh2DxAV79jhJ3gnOnBZ8MTB/J085VZCSKP8bZDTzzlzdgBTkYKuyTQRkyjpychxGYvHEMnufMid/rvsqi3daV6lHZSy8ongA9xx3EbIfrX48snvyzfjtaIgGcrTkWOzCrCZ62WlvOyg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788556837; c=relaxed/simple; bh=k1NUZekdNvDVAxHEPDyOpNgDCTC3QF+OU9gpLFLNa1w=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=t7wNacDyUP5AKVV0XiiJI8xm2bDVwdFLW/fJlY3EIdz+dS6p01tPyFpma6zssL++ykgXnjdNENpU1OYLXh6vqkFtHJr7F7cn39UlKflR395e0Peo2glQ+txip9q2JI+0kvbe4piuDbBMuSxIcKfQY7IG91aSaDjeMEO7izBq/sU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=chromium.org; spf=pass smtp.mailfrom=chromium.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b=FECcrIdF; arc=none smtp.client-ip=209.85.214.182 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=chromium.org Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=chromium.org Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b="FECcrIdF" Received: by mail-pl1-f182.google.com with SMTP id d9443c01a7336-2d53197d8b5so13131805ad.3 for ; Fri, 04 Sep 2026 14:20:35 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; t=1788556835; x=1789161635; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=Pyu7EKLYDGgyMZngozm5HGHi5hOMpAogxMMPdrlXlPo=; b=FECcrIdFjeqJ5gjf8vcMqteFHE2gUU7I45RoNVso7MyLsFWbg+wQqEviKMgTSe3yJd WpbkngB+Wwz57SGi3AoCg17bf3/mxT5CuB1x5YS3OCWXm09kHJkFwiqS1QMiMmgmHyC5 BM/ne1o/umTpgou0JnHlPvDOGqFfznmp3/i7s= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1788556835; x=1789161635; h=content-transfer-encoding:mime-version:references:in-reply-to :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=Pyu7EKLYDGgyMZngozm5HGHi5hOMpAogxMMPdrlXlPo=; b=c1iujO7dgxTcAbtRYIqcxUyTkoKqwMgiKzkWIdlQNBfqeZfAin+ScwPhyvkROnGDpv tahssNEsqMYy4x+PQcTPFTRYkKwPDz7/Ezs3SucMm9ADEdKCCCVEn8IEHEZLCkDTs1YV l+48k/+3NrYRFNoewwWn8NpzRkgo0NHHC2ItUSGu5U9/6/f2vXr/TYMgU5j2so8EvbIv QK2an/5TWVDss5em40KfCRuDnQ93CHHOWRPFZ3e6ql6vVJ436rbDOFjdoYMuzcPapxv6 DJSjpa1KJsfhTIFNcelP4zwTMRX/Y/jWr02rwY88bDF4IWVxzidAleI7G5FCNyZGmaJV 4Y2A== X-Gm-Message-State: AFuF++m/+0AJtshteQfxYLsXdVtw66SwRNxTsZ/45OFgtb0vS16GlLs8 vhliGC8SxsNZSbpCi32Tkg4fEKru91wf3mxQrm3zu4KdRrG+TYHt7meVI86vjlFfgw== X-Gm-Gg: AYBFou3cjVmz+/Qla+IEwHTu25xo3uF21byIudtG6Ze5QXOCvuayLvvAMuzxi72nS3y HPK4sgMLjNs+CSqGSS2jMbJMNkS9ADTezpE8kPWozQzpENvWMWmnkhko/b4GHwrI3lR8lYhRgig ySk/fuk0V09Ny4eNsoP1/cfp6nx9NeBaK3la67bHuNbb9tRIze75PPyRWNIe3FijtRs6ogneseU afA8Vx0lBF9ObKUxZetiaOG3NNMiJ9oVVi3w/I/wVn3DpocUjvTKdOo8+9y+Ih2KIVqL7aABpDD +zj6ncaoxJ1HmEUDxHoAsG1A4UwIpDywHSCw8DOnS6aPWIoEEpdC44ajN5Y59J2484qPjxkC+Ia UZZHlu7iU7zQuhmp5wIMYqnXCjccaqCvEvCv9lFprtrg2o0IcXWZD6XdUqc46NZB2g0vcR9DJQd FCPb7EuO4lixTc4TLQdZeSPdf/C086F1t8DWWpkVs4MOLZULGPlEad3UPpP+93Shlh6uF/chQan KxehkU3fjOwuUtrTqkfKCxQkEo= X-Received: by 2002:a17:903:32cb:b0:2c9:bf82:dd11 with SMTP id d9443c01a7336-2db1248c3f4mr108329295ad.7.1788556834000; Fri, 04 Sep 2026 14:20:34 -0700 (PDT) Received: from localhost ([2a00:79e0:2e7c:8:5597:62ab:c321:4a7f]) by smtp.gmail.com with UTF8SMTPSA id 5a478bee46e88-3346ea43377sm5484633eec.3.2026.09.04.14.20.32 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Fri, 04 Sep 2026 14:20:33 -0700 (PDT) From: Brian Norris To: "Rafael J . Wysocki" Cc: linux-kernel@vger.kernel.org, Len Brown , Ulf Hansson , linux-pm@vger.kernel.org, Pavel Machek , Doug Anderson , Brian Norris Subject: [PATCH 06/11] PM: runtime: Expand introduction with core concepts and structure Date: Fri, 4 Sep 2026 14:12:11 -0700 Message-ID: <20260904141215.6.I45a794e4452e3df22419acdd8f11e2b788b3413f@changeid> X-Mailer: git-send-email 2.55.0.979.g7e5102b832-goog In-Reply-To: <20260904212000.4167880-1-briannorris@chromium.org> References: <20260904212000.4167880-1-briannorris@chromium.org> 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" I commonly see people have difficulty learning how runtime PM works because of the following key points [*]: 1) there are several boolean concepts in runtime PM, with somewhat similar meanings: enabled / disabled active / suspended allowed / forbidden 2) if these concepts are documented at all, they're scattered across the kerneldoc or Documentation/ 3) the runtime_pm.rst docs don't make any attempt to ease a reader into understanding the concepts, and instead jump straight into how it's implemented (queues, 'struct device' fields, helpers). Let's try to remedy this a bit by discussing the core concepts and highlights at the top of the introduction, and introduce a few sub-headings, so it's easier to navigate different aspects of the introduction. While shuffling the intro around, I also see that the existing text largely mirrors the layout of the following sections (2, 3, and 4), but does so out of order. Reorder those, and point to section numbers. [*] In addition to API complexity. I count 61 pm_*() helpers, 7 of which are variations of put() and 8 of which are variations of get(). Signed-off-by: Brian Norris --- Documentation/power/runtime_pm.rst | 87 +++++++++++++++++++++++------- 1 file changed, 68 insertions(+), 19 deletions(-) diff --git a/Documentation/power/runtime_pm.rst b/Documentation/power/runti= me_pm.rst index 39fdeeda7a1e..620b6988deca 100644 --- a/Documentation/power/runtime_pm.rst +++ b/Documentation/power/runtime_pm.rst @@ -11,31 +11,80 @@ Runtime Power Management Framework for I/O Devices 1. Introduction =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =20 -Support for runtime power management (runtime PM) of I/O devices is provid= ed -at the power management core (PM core) level by means of: - -* The power management workqueue pm_wq in which bus types and device drive= rs can - put their PM-related work items. It is strongly recommended that pm_wq = be - used for queuing all work items related to runtime PM, because this allo= ws - them to be synchronized with system-wide power transitions (suspend to R= AM, - hibernation and resume from system sleep states). pm_wq is declared in - include/linux/pm_runtime.h and defined in kernel/power/main.c. - -* A number of runtime PM fields in the 'power' member of 'struct device' (= which - is of the type 'struct dev_pm_info', defined in include/linux/pm.h) that= can - be used for synchronizing runtime PM operations with one another. +Runtime power management (or runtime PM, sometimes shortened to RPM) allows +individual I/O devices to transition between high and low-power states +dynamically while the system is running, conserving power without waiting = for a +system-wide sleep state. + +Core Concepts +------------- + +Understanding runtime PM requires distinguishing between several pairs of +complementary states that operate orthogonally: **active** / **suspended**, +**enabled** / **disabled**, and **allowed** / **forbidden**. + +* **Active**: The PM core tracks a device's runtime status as either **act= ive** + (the device is operational, having completed its resume callback) or + **suspended** (the device is idle or in a low-power state, having + completed its suspend callback), along with transitional **suspending** + and **resuming** phases. State transitions are primarily driven by + reference counting: drivers call pm_runtime_get() (or related variants) + when the hardware is needed (ensuring the device is active) and + pm_runtime_put() when work completes, allowing the PM core to initiate + suspension (immediately or after an autosuspend delay) once the usage + counter and any active child dependencies reach zero. + +* **Enabled**: Orthogonal to whether a device is currently active or suspe= nded + is whether runtime PM is **enabled** or **disabled**. This is governed b= y an + internal disable counter (``disable_depth``). All devices are initialized + with runtime PM disabled (``disable_depth =3D=3D 1``) and can also be di= sabled + during system sleep transitions or explicitly via pm_runtime_disable(). = In + the disabled state, the PM core ignores idle and suspend requests and wi= ll + not execute runtime PM callbacks (->runtime_suspend(), ->runtime_resume(= ), + ->runtime_idle()). A driver activates runtime PM processing during + initialization or probe by calling pm_runtime_enable(), decrementing + ``disable_depth`` to zero. + +* **Allowed**: System policy and user space govern whether dynamic suspens= ion + is permitted through the concepts of **allowed** and **forbidden**, + manipulated in-kernel via pm_runtime_allow() and pm_runtime_forbid() and + exposed to user space through the ``/sys/devices/.../power/control`` + attribute. When runtime PM is forbidden (``control`` set to ``on``), the= PM + core increments the device's usage counter, forcing the device to remain + active regardless of whether the driver is idle. When runtime PM is allo= wed + (``control`` set to ``auto``), this reference is dropped, permitting the= PM + core to automatically suspend the device whenever its driver and child + devices are no longer using it. + +Notably, runtime PM also has a feature called "autosuspend." This is diffe= rent +than the ``control`` notion of "auto" (i.e., "allowed"). Autosuspend is +described in more detail in Section 9. + +Implementation Structure +------------------------ + +Support for runtime power management is provided at the power management c= ore +(PM core) level by means of: =20 * Three device runtime PM callbacks in 'struct dev_pm_ops' (defined in - include/linux/pm.h). + include/linux/pm.h). See Section 2. + +* A number of runtime PM fields in the 'power' member of 'struct device' t= hat + can be used for synchronizing runtime PM operations with one another. Th= ese + are covered in Section 3. =20 * A set of helper functions defined in drivers/base/power/runtime.c that c= an be used for carrying out runtime PM operations in such a way that the - synchronization between them is taken care of by the PM core. Bus types= and - device drivers are encouraged to use these functions. + synchronization between them is taken care of by the PM core. Bus types = and + device drivers are encouraged to use these functions. They are covered in + Section 4. =20 -The runtime PM callbacks present in 'struct dev_pm_ops', the device runtim= e PM -fields of 'struct dev_pm_info' and the core helper functions provided for -runtime PM are described below. +* The power management workqueue pm_wq in which bus types and device drive= rs can + put their PM-related work items. It is strongly recommended that pm_wq be + used for queuing all work items related to runtime PM, because this allo= ws + them to be synchronized with system-wide power transitions (suspend to R= AM, + hibernation and resume from system sleep states). pm_wq is declared in + include/linux/pm_runtime.h and defined in kernel/power/main.c. =20 2. Device Runtime PM Callbacks =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D --=20 2.55.0.979.g7e5102b832-goog From nobody Sat Sep 26 03:12:00 2026 Received: from mail-pl1-f176.google.com (mail-pl1-f176.google.com [209.85.214.176]) (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 1E60852ED27 for ; Fri, 4 Sep 2026 21:20:37 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.176 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788556838; cv=none; b=FoKog+tNUrTOWETlVjQ2QvbkuIRIIdRwg8yVLHQ5mo1RwTAdfJ3rJYrIIPJ6ImxKBrRFN/yRieQXJXr7fceLQ4At/BrgbmzaBHpVm/5vlzpG85rOODrFisklVen8Un5ym3Gc2XhU5Kkj+FWojtnFm2APRfGHeuIQySeBh9j+wDU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788556838; c=relaxed/simple; bh=P0eQcHYcmOWKVxWCx0wymuD9OObSAIkm60t94YUG3AU=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=GqJzANfV5YR7C3GhbgvjAivNO85CnLRLFjiYg9U64yyNqHBp74onIlJBARmB26UsvBTwEda46P0rFBqsK+7cQNPO3rnJwfBebQkS56Zlay08kRaFLPVKKIzX4uClw1+bwHW58D5xWwObWf3YqQd8pJKpeUmNzFjYrcdAMJ7v/E8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=chromium.org; spf=pass smtp.mailfrom=chromium.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b=gFbb4FyN; arc=none smtp.client-ip=209.85.214.176 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=chromium.org Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=chromium.org Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b="gFbb4FyN" Received: by mail-pl1-f176.google.com with SMTP id d9443c01a7336-2d72ae08fa1so14390485ad.2 for ; Fri, 04 Sep 2026 14:20:37 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; t=1788556836; x=1789161636; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=CgbXePwlXIIaNUXfDEVIwWo//QzJGVGkingWQIsticc=; b=gFbb4FyN6xOvtQIsGa8E1N3FXjfhAZ74Wgvx2lqS8rrlRGRFr/nYvtLyaPvnogTzfw IHw6v41lruPymauvRZuhuVfSAGD3L9vhgvQxjj45/p5kTSoeRK4kmJTQusWNYVEaVjSv vyH1f7xbKWF+piqOwRVTK0y87O33SNRd+hAgc= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1788556836; x=1789161636; h=content-transfer-encoding:mime-version:references:in-reply-to :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=CgbXePwlXIIaNUXfDEVIwWo//QzJGVGkingWQIsticc=; b=ZcpvqJ8gF9j1EfO7P1ICh+xg5TfgaxWbTUtRrK59RQgD4f17CevkmIWOkbzEOvvsV6 +o4lUg9z2U9lxeeZCbvBP1fFoIIntD1De2mdd8XnzZQdlIsig2bfCWYUbkkvL1ev92oi y32WEpmz7Psqk/FT5/WPXRZtT/mEPo2seRq97jaxiRFH71b2FgMKpJ7GDId2LHKE7I35 c4LouY1Erp4WS2LIjYT5hX4IDJ5gnuYK0GvAfDMwqGt6SZxZDeDE92X98VmNA4r8M+AE bD4lQmCFZo46A/EEQpoIQ2MjT/xu6+S1va5OtcoZktjAMC7tSLAnrveP9AB5d0M9IOOj UN3A== X-Gm-Message-State: AFuF++ncwzCX8vC0lDJdFWDv+nBXtqPq6EyxauccLIwwZqbX7W0nKF1+ j7/rDApYd7AeyhJvuBlg7LQ+s8edr9Zc88lTTwm9MWetApV7DI5m3Ysi4NlPriop8Q== X-Gm-Gg: AYBFou0VLDVIGiXPzp6cMOQmmz0jjcBK/9/qXMOqaypkum+EDkblzfDtd4ZwGdtzAav sTsl7Ruogrhb8bwam346DTr4BvQs5a8HABjVdZq9tjqbxZ/5K0O3srO5NyJqhUIag0yHOT5QaTo QFqeAuOvPv79qgdC/kU+8ug2WQmUCGAUdcVzWMvC5wUAS+YF2TFyzJO0ioBR1Gh0ZPMFYR84EfQ R2r7+POn1ECpdHqZXDud8ReJVUjEZLbYGL5hMGl1CGgch9XffbZV6eCaLx8nxL/XzlBz0u3gcih t2FkDyDSb8CYYlfhp6fAK8X7y3ADfdvYzi2g32o+RuL4hL4A89x52HDP2Az05gXFgJRiXou8ioq mv0AvzXFHK07qrT0VwGSALQXL7oWYs+tvjFiIko37XoHSaHyUyRlhIb8ABtyzRCZ3gbon2+R4an xSPgATld2RJ39X61Pw4gyjbmuLNpKzLcHUushrybFRpjnUBl/cIzE8V9mROHeAn3Sd7hnnQUYE6 VVyB6MY3oqZdkGgI7abMLPlmDI= X-Received: by 2002:a17:90b:56cf:b0:398:dcf6:d40e with SMTP id 98e67ed59e1d1-39b262aa580mr14262560a91.17.1788556836441; Fri, 04 Sep 2026 14:20:36 -0700 (PDT) Received: from localhost ([2a00:79e0:2e7c:8:5597:62ab:c321:4a7f]) by smtp.gmail.com with UTF8SMTPSA id a92af1059eb24-143243bfbe3sm8877936c88.11.2026.09.04.14.20.34 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Fri, 04 Sep 2026 14:20:35 -0700 (PDT) From: Brian Norris To: "Rafael J . Wysocki" Cc: linux-kernel@vger.kernel.org, Len Brown , Ulf Hansson , linux-pm@vger.kernel.org, Pavel Machek , Doug Anderson , Brian Norris Subject: [PATCH 07/11] PM: runtime: Clarify ->runtime_idle() callback return value handling Date: Fri, 4 Sep 2026 14:12:12 -0700 Message-ID: <20260904141215.7.If6e26acac7770c65446dd0b81f891948abb38973@changeid> X-Mailer: git-send-email 2.55.0.979.g7e5102b832-goog In-Reply-To: <20260904212000.4167880-1-briannorris@chromium.org> References: <20260904212000.4167880-1-briannorris@chromium.org> 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" This doc says "Negative error return codes are ignored by the PM core" for ->runtime_idle(). This is misleading: any non-zero return value (including negative error codes such as -EBUSY or -EAGAIN) tells the PM core to abort automatic suspension of the device, which is commonly used by subsystems to prevent immediate runtime suspend. Clarify that unlike ->runtime_suspend() and ->runtime_resume(), the PM core does not treat negative return values from ->runtime_idle() as a fatal device error, and that any non-zero value stops the PM core from suspending the device. Signed-off-by: Brian Norris --- Documentation/power/runtime_pm.rst | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/Documentation/power/runtime_pm.rst b/Documentation/power/runti= me_pm.rst index 620b6988deca..334fbdcd8fd6 100644 --- a/Documentation/power/runtime_pm.rst +++ b/Documentation/power/runtime_pm.rst @@ -203,9 +203,14 @@ suspending the device are satisfied) and to queue up a= suspend request for the device in that case. If there is no idle callback, or if the callback ret= urns 0, then the PM core will attempt to carry out a runtime suspend of the dev= ice, also respecting devices configured for autosuspend. In essence this means= a -call to pm_runtime_autosuspend(). To prevent this (for example, if the cal= lback -routine has started a delayed suspend), the routine must return a non-zero -value. Negative error return codes are ignored by the PM core. +call to pm_runtime_autosuspend(). + +To prevent this suspension (for example, if the callback routine has sched= uled +a delayed suspend or determined the device cannot be idle), the routine mu= st +return a non-zero value (typically -EBUSY or -EAGAIN). Unlike +->runtime_suspend() and ->runtime_resume(), the PM core does not treat neg= ative +return codes from ->runtime_idle() as a fatal device error; any non-zero v= alue +simply stops the PM core from suspending the device. =20 The helper functions provided by the PM core, described in Section 4, guar= antee that the following constraints are met with respect to runtime PM callback= s for --=20 2.55.0.979.g7e5102b832-goog From nobody Sat Sep 26 03:12:00 2026 Received: from mail-pl1-f177.google.com (mail-pl1-f177.google.com [209.85.214.177]) (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 16C8D52ED4E for ; Fri, 4 Sep 2026 21:20:39 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.177 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788556841; cv=none; b=pV3nmagXJ8USZcOPAvA2G38CYcGCr9DW9KviR74FhG1Kr8YN4bfNNmIh5Bo3t5IibdIfiIodOmtx2F5yhwGd5pMnf/EUGiICY7dg6+BR94L0ug5u9mmLFeJDBcwxNS9iXG+ZDExh0vQrFubqFiclA/lGTWsScjFGUbobETxsSY4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788556841; c=relaxed/simple; bh=xKaYW9zJkwwWXZEkPBsIv9x7Ds5D3bG/QUriwzNmc74=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=AM0v88BKYW7816YX7zZdgGw4uOwRqv5sOS6kFJHzRc2L+QOAvQKo3XiPwzj/s6GRDpKqcWTD22KqGZZVkCNUKoR76NuQnVLppMGACsodNNQqe67ACNVvUZMGvMeqXRJw8KsxqKcH/dsEIRlKszsl+qy4pvP3QtndEHxUIl14p50= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=chromium.org; spf=pass smtp.mailfrom=chromium.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b=O1OcNwS/; arc=none smtp.client-ip=209.85.214.177 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=chromium.org Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=chromium.org Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b="O1OcNwS/" Received: by mail-pl1-f177.google.com with SMTP id d9443c01a7336-2d8f265cbe6so11644145ad.0 for ; Fri, 04 Sep 2026 14:20:39 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; t=1788556839; x=1789161639; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=4PRA1MiHjBTxffZGUtkRwz7pDd3V4cniEc57f6JxKLc=; b=O1OcNwS/YU+yW4zoye8fy+n013Mcn1hK/4LbgxyJUnbG2149KWz8rkWCntnlxDtuia IggSE2vDIPM/rXbaPhK0sa/3SZJmIFDTnTbWGlVyPuq8OxbZMc0EGJ1v3B8Yd0eWg8hj Obj1XCqTZQLamwZlEIIqOVZpdOoQ26syq3KXg= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1788556839; x=1789161639; h=content-transfer-encoding:mime-version:references:in-reply-to :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=4PRA1MiHjBTxffZGUtkRwz7pDd3V4cniEc57f6JxKLc=; b=FTAPto2qYYEnEkGlA1LICtTHhg9dhDDQfVaxqTW81BV7roWXn9Z5UgPDsNY/8faHE1 9U54vPcaPl+PHQrg5GhdLGz93WnQl5SFYvi3Sh/cl06eKtvrO6yG6RsM7s+rR9jIfTER zLvxLHCBZY3E5J0DsAS8y41KV2VJAkacfvqjlPlt4U88x66Wugd2cpqoV/eniXsJNnaP VNrsuWfy7pUPR+VJ3i3lJzalL1Fmz81IpuK2T5HRTaoTTwALwa46bYh430QIVPU4lMEg XyVu0xfNYwY3OlebRD5Xti00+wfP18hFc5Bzu/XPtTlKRfmK1mQMDztNmFRxEo/cWDET WjVw== X-Gm-Message-State: AFuF++keq0InNhKqExwV9X2Eqg4cEaH72Lqd6xir8N7edXkVDYCDxzSy /A3RYjwWX80qgjIdeCQ7DmmomRohEkGgBylF6Hvjs08gp/LHdwQVUBK95tdcrycK2A== X-Gm-Gg: AYBFou390Mg7h+ErLYHATbD+6wkjafiwx6sQmekw33hzgbH1s8Hp1fsov3nxHqrFNMD dhBxc9IJc+7fUw4AkTJ2EorbzIsq2FufXU0j0gxJRKyu8KOQuCmpiwVnRTJEhANvN2AiE+IplI1 Of0d6NRynL+DdJcEGfgi172HwPldBkUWBgwF4Xhs08iTybFXhSIbbqbBV7HJlpyDRcwtrXvHUCp wKQHR/rI2OaZ1Z5vDosJCc8fc+LhQDva2mn0g7bRzkRDuEzIQM6EjMUB9sSIgsgPgH8ixEwdJ8e L4zqyr+B9xkwjigQVCYIuAB+FDzZnlJgvUKBQ/HRQkyFPts7rAW4751ynTIknxhwFv+p3vfOgwG epKmsL9ESqVYQVf5v9DukbDYmHBl6xTndRdk+Oqcary/FlWkRjBWTtALRqSY2dk00FewQIiVEYO h8DiGPyGHRnGGBks39hN80BA3U7rwTs8RySVBWmdFci6JLn/0q65ckMa9GL1QlHTCIfJ/Z3JiDI AxHd7yx9z/U8fxE03Pzd80fNf3/4E46/q7xnw== X-Received: by 2002:a17:903:3804:b0:2cf:9347:f445 with SMTP id d9443c01a7336-2db126d8a54mr132748865ad.10.1788556839162; Fri, 04 Sep 2026 14:20:39 -0700 (PDT) Received: from localhost ([2a00:79e0:2e7c:8:5597:62ab:c321:4a7f]) by smtp.gmail.com with UTF8SMTPSA id 5a478bee46e88-3339ac24d7esm14125746eec.15.2026.09.04.14.20.37 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Fri, 04 Sep 2026 14:20:38 -0700 (PDT) From: Brian Norris To: "Rafael J . Wysocki" Cc: linux-kernel@vger.kernel.org, Len Brown , Ulf Hansson , linux-pm@vger.kernel.org, Pavel Machek , Doug Anderson , Brian Norris Subject: [PATCH 08/11] PM: runtime: Clarify driver callback expectations and structure Section 2 Date: Fri, 4 Sep 2026 14:12:13 -0700 Message-ID: <20260904141215.8.If19ee35d3b80d115f264484b21fb003a962762fa@changeid> X-Mailer: git-send-email 2.55.0.979.g7e5102b832-goog In-Reply-To: <20260904212000.4167880-1-briannorris@chromium.org> References: <20260904212000.4167880-1-briannorris@chromium.org> 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" Section 2 describes the three runtime callbacks, but: 1) it's fairly dense to read (150+ lines); and 2) it glosses over a big point -- that it's uncommon for drivers to implement ->runtime_idle() Add a note up-front to help direct the reader about #2, and add headings to try to break up the text a bit. Signed-off-by: Brian Norris --- Documentation/power/runtime_pm.rst | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/Documentation/power/runtime_pm.rst b/Documentation/power/runti= me_pm.rst index 334fbdcd8fd6..571a2f29851b 100644 --- a/Documentation/power/runtime_pm.rst +++ b/Documentation/power/runtime_pm.rst @@ -99,6 +99,14 @@ There are three device runtime PM callbacks defined in '= struct dev_pm_ops':: ... }; =20 +Most device drivers only need to implement ->runtime_suspend() and +->runtime_resume(). The ->runtime_idle() callback is optional and rarely +implemented by peripheral device drivers, as the PM core automatically han= dles +suspension and autosuspend when ->runtime_idle() is omitted (or returns 0). + +Subsystem and Driver Callbacks +------------------------------ + The ->runtime_suspend(), ->runtime_resume() and ->runtime_idle() callbacks are executed by the PM core for the device's subsystem that may be either = of the following: @@ -132,6 +140,9 @@ not block or sleep, but it also means that the synchron= ous helper functions listed at the end of Section 4 may be used for that device within an inter= rupt handler or generally in an atomic context. =20 +Callback Semantics +------------------ + The subsystem-level suspend callback, if present, is _entirely_ _responsib= le_ for handling the suspend of the device as appropriate, which may, but need= not include executing the device driver's own ->runtime_suspend() callback (fr= om the @@ -212,6 +223,9 @@ return a non-zero value (typically -EBUSY or -EAGAIN). = Unlike return codes from ->runtime_idle() as a fatal device error; any non-zero v= alue simply stops the PM core from suspending the device. =20 +Core Guarantees and Synchronization Rules +----------------------------------------- + The helper functions provided by the PM core, described in Section 4, guar= antee that the following constraints are met with respect to runtime PM callback= s for one device: --=20 2.55.0.979.g7e5102b832-goog From nobody Sat Sep 26 03:12:00 2026 Received: from mail-pj1-f54.google.com (mail-pj1-f54.google.com [209.85.216.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 E58BC4EE85C for ; Fri, 4 Sep 2026 21:20:45 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.216.54 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788556847; cv=none; b=r2u5HFJBN4nR8ZaZ5U/UW/5aW2hWMhTtjVfzhjQfj/5IJDvjNp6tGO83BZDkUVPJRvKWWiMYX0kftcRuXcf+zcfFGHFSz48WS6VBO02OpZbtBNBjHhPf8WCblnXmdywlbnJunHS9QslNPavlde3TjfkQOyscaRUtZJpN00nvaU4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788556847; c=relaxed/simple; bh=an4306lbd9gYljGt3gjoP2fU6r9hl/qCRg/3E2XP8aM=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=mYEyZ9RYt2Dw6BCZWCfvbuYbGM/18aWIFZ2/J6rn5yamEdNyTfAcmLBSY99U2qIroVG0FrAskmfuHdpC/H0YXVRUKd5f2sCjuAd3UsyRKkv555gCAxbI9z+A+1S+aWOYLkmx6lJhnGoxF8JPD2sjdSVjgQSvMEhh9Lq7gSKULBE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=chromium.org; spf=pass smtp.mailfrom=chromium.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b=lEX7ZYam; arc=none smtp.client-ip=209.85.216.54 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=chromium.org Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=chromium.org Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b="lEX7ZYam" Received: by mail-pj1-f54.google.com with SMTP id 98e67ed59e1d1-382ef647e20so1465209a91.1 for ; Fri, 04 Sep 2026 14:20:45 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; t=1788556845; x=1789161645; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=bwLinra99aXycX9ldNYRzirNUG5NNrsETkODdowC3mE=; b=lEX7ZYam2EsQ3V+c8EAQCGlAj5aq9Dacm9zIYyPSv/yIKIeKMYUTcqx42AQMurbU3t odb7F26Cxjx50EEyinwFeuQr30SslbCd49p6wkrS5lOTz25GpMhJzKLgMk3isgtdU5BJ GBxJkMDwPTXjqilV6HXb0t0xe2ef7IcPGsmYI= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1788556845; x=1789161645; h=content-transfer-encoding:mime-version:references:in-reply-to :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=bwLinra99aXycX9ldNYRzirNUG5NNrsETkODdowC3mE=; b=CsV9IQatdZLpXvJpZc+eLgOt3Dr8NYGPgHrtvsruCfzywPBHQZpy4lnoq57asglCdM n7aN7DLo1a84hz7xjlWLEK2HwSVxWPEe2Dg4pc52JpZ+xt3iOXufPQzhIacnx7aAaKCz He3JbfauWc9/GJpocAdcFJ3TfPd3EPPCiHsIvDeBSr0h8YRZCytm3qsSBMPmpHd1g0y8 KxC9Y+ecBx2VJF/RJacymSA3g8qYqZUOMptYjAFju9x34AyxtbRo6urAyoAjSFCkQvRQ I7+v0dIYPWVsbdJDb4CSOF8goUX/XWLJ1ToKWET0N68UKJJNypT2nE/ay7+O8B2kDIWL 22Wg== X-Gm-Message-State: AFuF++ndCAtM7GaEeqY/h3j0oSHxInVhDcnQGQMSl2CD+72fVB8I91IA JsydtqXVOMej68RM9ZTgEQcJFDbhzhsEnbaitVhNSg3bKdS3Z7ooutAKCnUwuhjdFA== X-Gm-Gg: AYBFou3RW15eVg+AEIq77ntOA04abSI/i0KOVLedmVT3I438fDCCzp2zlTqAgYLp8D5 T5ansMONf8H7tJhYsynAnNef4X4yyysMnHp/MEfOus4qBlqws0FZF6enYLrwXLcnpTeCa84EWhR 8tRgEu9ni+v8YBiBr4QpOu5X+dSqVl989G7Bg+H+Av/kjL9HQL6CCfgMC7i7uq1x69Rx/qZgYpH XsNpbXrZSB7mURpf7BaSCmpzlfnlTnwcFRRnmtUxL7KAbwYg8igTtZNGYAbyPSfBxf63pYpw1+d I6itrHz3OI5FXpiooHvGaW1/aFtF5Ost+wLHQ+Kzc7VdfeLJEozKWAKLgdeVCcLPRGpIQ6gU2VX K2gNCZm4v8e+IAQKkoKiSAXdyjS/j3dfGHia+Z9g8SnaWsDsFRKNiHcoWQ9c48NLxoC+93ztzKJ 8HkOA6OP+HN+7y4lTC6tX/zVbwN1Gke0mq6fdG1AOfi8/Py4GJaodXaSlF8tFT9wOtR5NzBecUE syhk5N7a7a6mbwFjlFisBg7lQteZF1iKTO/ww== X-Received: by 2002:a17:90b:280b:b0:398:c315:fa6f with SMTP id 98e67ed59e1d1-39b261cfebdmr11555869a91.14.1788556841868; Fri, 04 Sep 2026 14:20:41 -0700 (PDT) Received: from localhost ([2a00:79e0:2e7c:8:5597:62ab:c321:4a7f]) by smtp.gmail.com with UTF8SMTPSA id 5a478bee46e88-3339bdf26c5sm8398706eec.27.2026.09.04.14.20.40 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Fri, 04 Sep 2026 14:20:41 -0700 (PDT) From: Brian Norris To: "Rafael J . Wysocki" Cc: linux-kernel@vger.kernel.org, Len Brown , Ulf Hansson , linux-pm@vger.kernel.org, Pavel Machek , Doug Anderson , Brian Norris Subject: [PATCH 09/11] PM: runtime: Misc improvements to runtime_pm.rst Date: Fri, 4 Sep 2026 14:12:14 -0700 Message-ID: <20260904141215.9.I383681b22c12d7caee976cb91aa90d1a94d4a591@changeid> X-Mailer: git-send-email 2.55.0.979.g7e5102b832-goog In-Reply-To: <20260904212000.4167880-1-briannorris@chromium.org> References: <20260904212000.4167880-1-briannorris@chromium.org> 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" There are several small errors and omissions, as well as new updates (pm_runtime_resume_and_get(), devm_pm_runtime_enable()) we should incorporate. Signed-off-by: Brian Norris --- Documentation/power/runtime_pm.rst | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/Documentation/power/runtime_pm.rst b/Documentation/power/runti= me_pm.rst index 571a2f29851b..8e4e03b7dbfe 100644 --- a/Documentation/power/runtime_pm.rst +++ b/Documentation/power/runtime_pm.rst @@ -306,6 +306,9 @@ It is safe to execute the following helper functions fr= om interrupt context: - pm_runtime_set_active() - pm_runtime_set_suspended() - pm_runtime_suspended() +- pm_runtime_active() +- pm_runtime_status_suspended() +- pm_runtime_enabled() - pm_runtime_mark_last_busy() - pm_runtime_autosuspend_expiration() =20 @@ -317,6 +320,7 @@ functions may also be used in interrupt context: - pm_runtime_autosuspend() - pm_runtime_resume() - pm_runtime_get_sync() +- pm_runtime_resume_and_get() - pm_runtime_put_sync() - pm_runtime_put_sync_suspend() - pm_runtime_put_sync_autosuspend() @@ -326,7 +330,7 @@ functions may also be used in interrupt context: =20 Initially, the runtime PM is disabled for all devices, which means that the majority of the runtime PM helper functions described in Section 4 will re= turn --EAGAIN until pm_runtime_enable() is called for the device. +-EACCES until pm_runtime_enable() is called for the device. =20 In addition to that, the initial runtime PM status of all devices is 'suspended', but it need not reflect the actual physical state of the devi= ce. @@ -355,7 +359,7 @@ enabled earlier by calling pm_runtime_enable(). =20 Note, if the device may execute pm_runtime calls during the probe (such as if it is registered with a subsystem that may call back in) then the -pm_runtime_get_sync() call paired with a pm_runtime_put() call will be +pm_runtime_resume_and_get() call paired with a pm_runtime_put() call will = be appropriate to ensure that the device is not put back to sleep during the probe. This can happen with systems such as the network device layer. =20 @@ -383,7 +387,10 @@ removal of their drivers. =20 Drivers in ->remove() callback should undo the runtime PM changes done in ->probe(). Usually this means calling pm_runtime_disable(), -pm_runtime_dont_use_autosuspend() etc. +pm_runtime_dont_use_autosuspend() etc. Alternatively, drivers can use +devm_pm_runtime_enable() during probe, which automatically takes care of +calling pm_runtime_disable() and pm_runtime_dont_use_autosuspend() upon dr= iver +detachment. =20 The user space can effectively disallow the driver of the device to power = manage it at run time by changing the value of its /sys/devices/.../power/control @@ -494,7 +501,7 @@ out the following operations: =20 Subsystems may wish to conserve code space by using the set of generic pow= er management callbacks provided by the PM core, defined in -driver/base/power/generic_ops.c: +drivers/base/power/generic_ops.c: =20 .. kernel-doc:: drivers/base/power/generic_ops.c :export: @@ -509,8 +516,8 @@ subsystem-level dev_pm_ops structure. Device drivers that wish to use the same function as a system suspend, fre= eze, poweroff and runtime suspend callback, and similarly for system resume, th= aw, restore, and runtime resume, can achieve similar behaviour with the help o= f the -DEFINE_RUNTIME_DEV_PM_OPS() defined in include/linux/pm_runtime.h (possibl= y setting its -last argument to NULL). +DEFINE_RUNTIME_DEV_PM_OPS() macro defined in include/linux/pm_runtime.h +(possibly setting its last argument to NULL). =20 8. "No-Callback" Devices =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D @@ -573,7 +580,7 @@ registration the length should be controlled by user sp= ace, using the =20 In order to use autosuspend, subsystems or drivers must call pm_runtime_use_autosuspend() (preferably before registering the device), a= nd -thereafter they should use the various `*_autosuspend()` helper functions +thereafter they should use the various \*_autosuspend() helper functions instead of the non-autosuspend counterparts:: =20 Instead of: pm_runtime_suspend use: pm_runtime_autosuspend; @@ -583,7 +590,7 @@ instead of the non-autosuspend counterparts:: =20 Drivers may also continue to use the non-autosuspend helper functions; they will behave normally, which means sometimes taking the autosuspend delay i= nto -account (see pm_runtime_idle). The autosuspend variants of the functions a= lso +account (see pm_runtime_idle()). The autosuspend variants of the functions= also call pm_runtime_mark_last_busy(). =20 Under some circumstances a driver or subsystem may want to prevent a device @@ -626,7 +633,7 @@ Here is a schematic pseudo-code example:: =20 int foo_runtime_suspend(struct device *dev) { - struct foo_priv foo =3D container_of(dev, ...); + struct foo_priv *foo =3D container_of(dev, ...); int ret =3D 0; =20 lock(&foo->private_lock); @@ -642,7 +649,7 @@ Here is a schematic pseudo-code example:: =20 int foo_runtime_resume(struct device *dev) { - struct foo_priv foo =3D container_of(dev, ...); + struct foo_priv *foo =3D container_of(dev, ...); =20 lock(&foo->private_lock); /* ... resume the device ... */ --=20 2.55.0.979.g7e5102b832-goog From nobody Sat Sep 26 03:12:00 2026 Received: from mail-pg1-f171.google.com (mail-pg1-f171.google.com [209.85.215.171]) (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 6D50C426438 for ; Fri, 4 Sep 2026 21:20:45 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.215.171 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788556847; cv=none; b=kpgW8qSGXhVsJckbZyHRcHv9AscxC7mQGZIN+jqnYvtS0eFtozWTJoaOAGo6LrKGQ2X96ZlOxAMO0MIvC6zNwEJup+5/azugWvRxc5D1Tyh4nm1AZTsGk3ijcOylumQHJhW5iMHkQ7jjbjNU/wSdpoHmt+iM60gOALd/Z0+MXyU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788556847; c=relaxed/simple; bh=zpAgL8P6FNbE1LYBSegFO2+80rMWZv3GX4lFHBkUF3E=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=MTUL1i+fqWB6fMUujlmpJGg93E4jkEPQbt+NKmEYWhcANaV2jwoYGap4DEJRZfjxJ6xDB9bXsZP5te0k0PcuYo7gWtlOl0PnnztecGnh2Ao4osFulnB3Nz6BVXDdhGAOz0TJBKsk0EgcL/hPV4yhj2KiD7vFtFMx6koZ5cic0P0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=chromium.org; spf=pass smtp.mailfrom=chromium.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b=Ys87HF7D; arc=none smtp.client-ip=209.85.215.171 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=chromium.org Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=chromium.org Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b="Ys87HF7D" Received: by mail-pg1-f171.google.com with SMTP id 41be03b00d2f7-cc439bfb2d8so1046941a12.2 for ; Fri, 04 Sep 2026 14:20:45 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; t=1788556845; x=1789161645; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=STORd2EPPp/b+HJxfGtKajHr5QfBJeb7BJYUKdgcjIA=; b=Ys87HF7DoKzuC/yX9wkCp8BCD/RcuesWa6/ONUAVI9nQBtbC3mBoK41/5QB9YKvLGn FKk6rgc3D1lKiQzR7jRfiuDXhHh+wvMS3H4wj5TxwCIzC8bLxB912DtBCT4U2vKjvJI/ r5X67pdS+vBw+sD1xBAgstEckAIdK9v3SWqbM= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1788556845; x=1789161645; h=content-transfer-encoding:mime-version:references:in-reply-to :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=STORd2EPPp/b+HJxfGtKajHr5QfBJeb7BJYUKdgcjIA=; b=JBT5G38tDXNhTNNP8aoLebRIfzutK+y//iPqe6v2XXHFbbuq4gQda8DLeD/hIqf4D5 jHoghhYxHMXdzH/Q2odQbb9j/LipAWoEeOXsxzNKfZ/rMqk6WdD2nhJ66FhkVMKPlvFx I5iLWcUeWcXkHd9ztCukXP3tJUmbdp7hHOxGt3IIAyq1Fb2LV8ggPkDBU5x2sKz+uX+t RbrZpFYP4CM6iyVHfgieJa39BBHVqA20ToXvuCqfhaJffPV4sOdgdecTcm4ZbQhJqo7U 9Z1a5gE1W7mvKS+w6xH3ZZKMCNYdvAyPHOANBOpXC4vc6h1WAFcNTl4YdEtaaFWk7l4A 1ZOw== X-Gm-Message-State: AFuF++kuWmRp8eV810B/cc+CPKzdHHlPqtY3YJ7e8JhfKvR4FpqT1LYz TokIhYIxZS4n+AQ3No8xtCGJY8n2iH0La34SyS6UUeXvR29D3WoGTS7jawwVD0zKIA== X-Gm-Gg: AYBFou3K9IPORKkShtFRC7FIwcEcWDTWO/bjmqZ3INVz+b6dltlPtdbeZ/fYwkU/rf5 RukpaGJQ2wpN2auuiCpykjGKMN5lfPcP4M7jWyHAy6aNLuRJOnoVn+jSyYhrBa6BC2VlOUWOnOr 4NkXtG7X1x/z6fzx4eE8fIZ7cy9GbqwhbtQHvZLq1iva1A3XX0LnRYYtWTNEOM84CWY0TY+IN0E q/AOA6VHUsFZNnI6XQuIlJJCBGJMhTVsPMCzqWKimarvclg8zcIG5RZ5ZdHS/IrMcnLSLcftoaF wG3LNgiJw9VLrFIAdEzs835YpAaH4Ez6CrvpldtWoFQwm/Z3GngQgxxiSUyoQpP2D1epRu9OCtR 5KVpW/ZVNrju8ycJ+Go5nQWri4q4n1OruFQyTlIVftvQb+Ssh/rsqba65A79U+7mm2rGlb/kKHj lezT1w6TTT8/VPPrGEpLm7EZmMRF4CIaF9SSTC9PTufgnqUuMu9AaL8vQOwyRlxpb54Sv0ZlRuD hkQ4uAIGb3wV0lLoHAbYclZtzg= X-Received: by 2002:a05:6a21:6487:b0:3d4:52bd:b89d with SMTP id adf61e73a8af0-3da3a0b2671mr11819689637.23.1788556844604; Fri, 04 Sep 2026 14:20:44 -0700 (PDT) Received: from localhost ([2a00:79e0:2e7c:8:5597:62ab:c321:4a7f]) by smtp.gmail.com with UTF8SMTPSA id 5a478bee46e88-3339a62be87sm8127527eec.6.2026.09.04.14.20.43 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Fri, 04 Sep 2026 14:20:43 -0700 (PDT) From: Brian Norris To: "Rafael J . Wysocki" Cc: linux-kernel@vger.kernel.org, Len Brown , Ulf Hansson , linux-pm@vger.kernel.org, Pavel Machek , Doug Anderson , Brian Norris Subject: [PATCH 10/11] PM: runtime: Add "Section" hyperlinks Date: Fri, 4 Sep 2026 14:12:15 -0700 Message-ID: <20260904141215.10.I7666a5802ea59359afce4ff7d0b1af668e5f5292@changeid> X-Mailer: git-send-email 2.55.0.979.g7e5102b832-goog In-Reply-To: <20260904212000.4167880-1-briannorris@chromium.org> References: <20260904212000.4167880-1-briannorris@chromium.org> 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" Add reStructuredText targets for each section, and use them throughout to make the generated HTML more navigable. Signed-off-by: Brian Norris --- Documentation/power/runtime_pm.rst | 56 ++++++++++++++++++++---------- 1 file changed, 37 insertions(+), 19 deletions(-) diff --git a/Documentation/power/runtime_pm.rst b/Documentation/power/runti= me_pm.rst index 8e4e03b7dbfe..d34f846ec822 100644 --- a/Documentation/power/runtime_pm.rst +++ b/Documentation/power/runtime_pm.rst @@ -8,6 +8,8 @@ Runtime Power Management Framework for I/O Devices =20 (C) 2014 Intel Corp., Rafael J. Wysocki =20 +.. _Section 1: + 1. Introduction =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =20 @@ -58,7 +60,7 @@ complementary states that operate orthogonally: **active*= * / **suspended**, =20 Notably, runtime PM also has a feature called "autosuspend." This is diffe= rent than the ``control`` notion of "auto" (i.e., "allowed"). Autosuspend is -described in more detail in Section 9. +described in more detail in `Section 9`_. =20 Implementation Structure ------------------------ @@ -67,17 +69,17 @@ Support for runtime power management is provided at the= power management core (PM core) level by means of: =20 * Three device runtime PM callbacks in 'struct dev_pm_ops' (defined in - include/linux/pm.h). See Section 2. + include/linux/pm.h). See `Section 2`_. =20 * A number of runtime PM fields in the 'power' member of 'struct device' t= hat can be used for synchronizing runtime PM operations with one another. Th= ese - are covered in Section 3. + are covered in `Section 3`_. =20 * A set of helper functions defined in drivers/base/power/runtime.c that c= an be used for carrying out runtime PM operations in such a way that the synchronization between them is taken care of by the PM core. Bus types = and device drivers are encouraged to use these functions. They are covered in - Section 4. + `Section 4`_. =20 * The power management workqueue pm_wq in which bus types and device drive= rs can put their PM-related work items. It is strongly recommended that pm_wq be @@ -86,6 +88,8 @@ Support for runtime power management is provided at the p= ower management core hibernation and resume from system sleep states). pm_wq is declared in include/linux/pm_runtime.h and defined in kernel/power/main.c. =20 +.. _Section 2: + 2. Device Runtime PM Callbacks =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D =20 @@ -137,8 +141,8 @@ the PM core that it is safe to run the ->runtime_suspen= d(), ->runtime_resume() and ->runtime_idle() callbacks for the given device in atomic context with interrupts disabled. This implies that the callback routines in question = must not block or sleep, but it also means that the synchronous helper functions -listed at the end of Section 4 may be used for that device within an inter= rupt -handler or generally in an atomic context. +listed at the end of `Section 4`_ may be used for that device within an +interrupt handler or generally in an atomic context. =20 Callback Semantics ------------------ @@ -165,9 +169,9 @@ knows what to do to handle the device). =20 * If the suspend callback returns an error code different from -EBUSY and -EAGAIN, the PM core regards this as a fatal error and will refuse to = run - the helper functions described in Section 4 for the device until its s= tatus - is directly set to either 'active', or 'suspended' (the PM core provi= des - special helper functions for this purpose). + the helper functions described in `Section 4`_ for the device until its + status is directly set to either 'active', or 'suspended' (the PM core + provides special helper functions for this purpose). =20 In particular, if the driver requires remote wakeup capability (i.e. hardw= are mechanism allowing the device to request a change of its power state, such= as @@ -192,10 +196,10 @@ what to do to handle the device). 'active'. =20 * If the resume callback returns an error code, the PM core regards this= as a - fatal error and will refuse to run the helper functions described in S= ection - 4 for the device, until its status is directly set to either 'active',= or - 'suspended' (by means of special helper functions provided by the PM c= ore - for this purpose). + fatal error and will refuse to run the helper functions described in + `Section 4`_ for the device, until its status is directly set to either + 'active', or 'suspended' (by means of special helper functions provide= d by + the PM core for this purpose). =20 The idle callback (a subsystem-level one, if present, or the driver one) is executed by the PM core whenever the device appears to be idle, which is @@ -226,9 +230,9 @@ simply stops the PM core from suspending the device. Core Guarantees and Synchronization Rules ----------------------------------------- =20 -The helper functions provided by the PM core, described in Section 4, guar= antee -that the following constraints are met with respect to runtime PM callback= s for -one device: +The helper functions provided by the PM core, described in `Section 4`_, +guarantee that the following constraints are met with respect to runtime PM +callbacks for one device: =20 (1) The callbacks are mutually exclusive (e.g. it is forbidden to execute ->runtime_suspend() in parallel with ->runtime_resume() or with another @@ -268,6 +272,8 @@ rules: scheduled requests to execute the other callbacks for the same device, except for scheduled autosuspends. =20 +.. _Section 3: + 3. Runtime PM Device Fields =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D =20 @@ -278,6 +284,8 @@ state. .. kernel-doc:: include/linux/pm.h :identifiers: dev_pm_info =20 +.. _Section 4: + 4. Runtime PM Device Helper Functions =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =20 @@ -325,12 +333,14 @@ functions may also be used in interrupt context: - pm_runtime_put_sync_suspend() - pm_runtime_put_sync_autosuspend() =20 +.. _Section 5: + 5. Runtime PM Initialization, Device Probing and Removal =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D =20 Initially, the runtime PM is disabled for all devices, which means that the -majority of the runtime PM helper functions described in Section 4 will re= turn --EACCES until pm_runtime_enable() is called for the device. +majority of the runtime PM helper functions described in `Section 4`_ will +return -EACCES until pm_runtime_enable() is called for the device. =20 In addition to that, the initial runtime PM status of all devices is 'suspended', but it need not reflect the actual physical state of the devi= ce. @@ -353,7 +363,7 @@ pm_runtime_set_suspended(). If the default initial runtime PM status of the device (i.e. 'suspended') reflects the actual state of the device, its bus type's or its driver's ->probe() callback will likely need to wake it up using one of the PM core= 's -helper functions described in Section 4. In that case, pm_runtime_resume() +helper functions described in `Section 4`_. In that case, pm_runtime_resu= me() should be used. Of course, for this purpose the device's runtime PM has t= o be enabled earlier by calling pm_runtime_enable(). =20 @@ -404,6 +414,8 @@ value of /sys/devices/.../power/control to "auto" to al= low the driver to power manage the device at run time, the driver may confuse it by using pm_runtime_forbid() this way. =20 +.. _Section 6: + 6. Runtime PM and System Sleep =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D =20 @@ -496,6 +508,8 @@ out the following operations: callback and right after executing the subsystem-level .complete() cal= lback for it, respectively. =20 +.. _Section 7: + 7. Generic subsystem callbacks =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D =20 @@ -519,6 +533,8 @@ restore, and runtime resume, can achieve similar behavi= our with the help of the DEFINE_RUNTIME_DEV_PM_OPS() macro defined in include/linux/pm_runtime.h (possibly setting its last argument to NULL). =20 +.. _Section 8: + 8. "No-Callback" Devices =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =20 @@ -555,6 +571,8 @@ in subsystems/drivers, the PM core allows runtime PM ca= llbacks to be unassigned. More precisely, if a callback pointer is NULL, the PM core wil= l act as though there was a callback and it returned 0. =20 +.. _Section 9: + 9. Autosuspend, or automatically-delayed suspends =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =20 --=20 2.55.0.979.g7e5102b832-goog From nobody Sat Sep 26 03:12:00 2026 Received: from mail-pl1-f170.google.com (mail-pl1-f170.google.com [209.85.214.170]) (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 2F66E3ECBE5 for ; Fri, 4 Sep 2026 21:20:47 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.170 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788556850; cv=none; b=RcvfKC1hQSVgjlOxs70R57Vqz91LYrqGCfYj3SwBsbnI2cBl/zVvRCvfg9DQgKEOBJ37diayGDjxjCoIhqOJMVYczD3wO/LqTW9SLCfImMiIK11IZ3zrIMZJye4Z4fESzDBv8xsMZNnWXnPvetPftKTRulIc3fAaWV5AdMZg+dk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788556850; c=relaxed/simple; bh=CTBW+rRmQcm5bB1KtVDvqWjtyepi/uHCJQSXb0G8Lyk=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=iub2QWJ+CgAYLCHARke1PfxSSVlityg/JmGq7rWDV2KEOroTowkF8AFKsKHN8IcfYhqqRI7fg56PP67v4gVBaKakWrG1uK8lxLqG8QWKhXGLTFwv2FLH/unkkA4mZWj7X0NXTzwsWmBHWFpsClt8+/nyyRz5Twi+jxyvxTB5mc0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=chromium.org; spf=pass smtp.mailfrom=chromium.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b=lN3yj35j; arc=none smtp.client-ip=209.85.214.170 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=chromium.org Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=chromium.org Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b="lN3yj35j" Received: by mail-pl1-f170.google.com with SMTP id d9443c01a7336-2d9004f39d3so17609475ad.2 for ; Fri, 04 Sep 2026 14:20:47 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; t=1788556847; x=1789161647; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=SXxcP1aknWmW9ffXwSgdl9e8UEUswVdhRKWAevupZwU=; b=lN3yj35jEiObgDEPx2K4IsaFVHN1uokVRQFg9de53E7N4+PLZA6qhmfMvvJOKDHXbl c1lvydqIbFtNENXRjjThSmxiZ+LRMVDGopgkPadei/WnLyEc7UF/SBVePAECCAgwUkXL OB9D6W0nVGCCkaIeW1rK+Ic97yBBSxol1giTQ= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1788556847; x=1789161647; h=content-transfer-encoding:mime-version:references:in-reply-to :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=SXxcP1aknWmW9ffXwSgdl9e8UEUswVdhRKWAevupZwU=; b=QnsjJ3+aG0X4l/lCxlhLL1hQjehCEsbpJjvXU9UulT2R4nWKFsRxqK70dEn80r5D7Z b1VlE0nwUMYurA0xx5BfC5Cco5iN9/34HPnTrpXpgBnizpnbZezuln1/aq5kptU7v/b9 MQiXdBTxAdOKrgQCDzNyB3dRD8Ix251zWdlDyYN/0jKCKhr3y+5VHm8fqyaYGcQVegVB gc8rtIIIYw5+FS9vCQ6LndDNmop4JAvjKT3EakVWwm7476iQ/tKpO468siYqPqzQWqgF fBlZOLAZz7TSKdXTypnNshvnKzboIOOweBuXZoBJL8jXjPPPXtDHdR5IVaLnZq77O/oa 5OZQ== X-Gm-Message-State: AFuF++kdMtoq0gZbB8J0r+Ib+U6ozMqgHwBKnEJIiAXWZjCiXfHkzSY1 52V6MQ6N/+w+VdwRIUpC8LyoL/rSunmNFeYDV+b6cHsyv7uyhQHcBNWjmVx497nbvSBhwICAsBC asrg= X-Gm-Gg: AYBFou00ieaG5j9CBlJ//xqZGPfREuIfvGu/aR33xpkd0uX/IaopEKLP11ESssUdR2a dcM3Gnlt/a8P6GbbweX2ZanZq72I0S7OuRRFHox+70+c9d+1tO3oNUy+Fsly7h05lJOZPxdSGPH dgw8HeS2dFrEDC7/rFUmDSjAQ3YyvcXbdrec5/0JcRevCtwFGekPjj4T7fUmDfmlshOPwUjIoA4 vaC4pJsSrM/TJNEfmkTRtccgqW0XDD5thAqjSqxPbcPC9n3hUZ7K8i4xsoNLc3jlIJ7uP1aBj7F f56oHPuQM9Tgak83Ead8DdAjrW0fsXvhziihFaioLQd9dGOO88SpujC9mujMtneZuJbu56L08Cl n8YcxsX8in900mlXT63Xv6SW9m7bDLyIYaC5Shsc1Ye9xK7h6ap5hnmWpZNK4bhswH3nX3lLKVX 6AWldQXSRkWPc+mIx8WiNdCDO9F9iCwCYKrtaGM8Uv+2rT/qGxcyYaP9iFh4GdAbDIvoyUKWJXD k1f8dAlUogaIYkWqFN/AYPrF/k= X-Received: by 2002:a17:902:c40f:b0:2d7:107c:917b with SMTP id d9443c01a7336-2db1212ee51mr113486185ad.0.1788556847215; Fri, 04 Sep 2026 14:20:47 -0700 (PDT) Received: from localhost ([2a00:79e0:2e7c:8:5597:62ab:c321:4a7f]) by smtp.gmail.com with UTF8SMTPSA id 5a478bee46e88-3339b8f44d7sm8949830eec.22.2026.09.04.14.20.45 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Fri, 04 Sep 2026 14:20:46 -0700 (PDT) From: Brian Norris To: "Rafael J . Wysocki" Cc: linux-kernel@vger.kernel.org, Len Brown , Ulf Hansson , linux-pm@vger.kernel.org, Pavel Machek , Doug Anderson , Brian Norris Subject: [PATCH 11/11] PM: runtime: Add Example Driver Patterns section Date: Fri, 4 Sep 2026 14:12:16 -0700 Message-ID: <20260904141215.11.I75ceea7b1afd016e08922e47b82e6eb36de144fe@changeid> X-Mailer: git-send-email 2.55.0.979.g7e5102b832-goog In-Reply-To: <20260904212000.4167880-1-briannorris@chromium.org> References: <20260904212000.4167880-1-briannorris@chromium.org> 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" The runtime PM API surface is pretty large, but there are a few common patterns that many drivers should follow. Add some illustrative examples, to help guide the most common audience for runtime PM docs -- driver writers. Signed-off-by: Brian Norris --- Documentation/power/runtime_pm.rst | 349 ++++++++++++++++++++++++++++- 1 file changed, 348 insertions(+), 1 deletion(-) diff --git a/Documentation/power/runtime_pm.rst b/Documentation/power/runti= me_pm.rst index d34f846ec822..74df4e822fb3 100644 --- a/Documentation/power/runtime_pm.rst +++ b/Documentation/power/runtime_pm.rst @@ -625,7 +625,9 @@ The implementation is well suited for asynchronous use = in interrupt contexts. However such use inevitably involves races, because the PM core can't synchronize ->runtime_suspend() callbacks with the arrival of I/O requests. This synchronization must be handled by the driver, using its private lock. -Here is a schematic pseudo-code example:: +Here is a schematic pseudo-code example: + +.. code-block:: c =20 foo_read_or_write(struct foo_priv *foo, void *data) { @@ -691,3 +693,348 @@ pm_runtime_autosuspend_expiration() from within the -= >runtime_suspend() callback while holding its private lock. If the function returns a nonzero value then the delay has not yet expired and the callback should return -EAGAIN. + +.. _Section 10: + +10. Example Driver Patterns +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D + +The runtime PM API is large and complex, but most device drivers follow a = small +set of canonical patterns when interacting with runtime PM. This section +illustrates standard patterns for device probing, performing I/O, and hand= ling +interrupts. + +Probe and Initialization +------------------------ + +Basic Probe +~~~~~~~~~~~ + +A driver that powers on its hardware during probe and does not use autosus= pend +can initialize runtime PM using device-managed helpers: + +.. code-block:: c + + static int foo_probe(struct platform_device *pdev) + { + struct device *dev =3D &pdev->dev; + struct foo_priv *priv; + int ret; + + priv =3D devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + /* Power on and initialize hardware registers... */ + + /* + * The code above left hardware powered on and operational, so + * tell the PM core that the device is active before enabling + * runtime PM. + */ + pm_runtime_set_active(dev); + + ret =3D devm_pm_runtime_enable(dev); + if (ret) + return ret; + + /* + * Alternatively, the above two calls can be combined into: + * ret =3D devm_pm_runtime_set_active_enabled(dev); + * if (ret) + * return ret; + */ + + /* + * Upon successful return from ->probe(), the driver core + * automatically executes pm_request_idle(dev), allowing the + * device to suspend asynchronously if its usage counter is zero. + */ + return 0; + } + +Probe with Hardware Powered Off +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Many drivers prefer to keep hardware powered off or in low power until +actually needed, avoiding duplicate power sequencing logic between ->probe= () +and ->runtime_resume(). Because the initial runtime PM state of a device is +suspended by default, the driver can enable runtime PM directly and rely on +pm_runtime_resume_and_get() to trigger the ->runtime_resume() callback when +probe needs to access hardware: + +.. code-block:: c + + static int foo_runtime_suspend(struct device *dev) + { + struct foo_priv *priv =3D dev_get_drvdata(dev); + + clk_disable_unprepare(priv->clk); + regulator_disable(priv->supply); + + return 0; + } + + static int foo_runtime_resume(struct device *dev) + { + struct foo_priv *priv =3D dev_get_drvdata(dev); + int ret; + + ret =3D regulator_enable(priv->supply); + if (ret) + return ret; + + ret =3D clk_prepare_enable(priv->clk); + if (ret) { + regulator_disable(priv->supply); + return ret; + } + + return 0; + } + + static int foo_probe(struct platform_device *pdev) + { + struct device *dev =3D &pdev->dev; + struct foo_priv *priv; + int ret; + + priv =3D devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + platform_set_drvdata(pdev, priv); + + /* Acquire regulators, clocks, GPIOs, and register map... */ + + /* + * Hardware starts powered off. The default state is + * RPM_SUSPENDED, so no need for: + * pm_runtime_set_suspended(dev); + */ + + ret =3D devm_pm_runtime_enable(dev); + if (ret) + return ret; + + /* + * Power on the device via ->runtime_resume() to verify device + * ID or perform initial hardware configuration. + */ + ret =3D pm_runtime_resume_and_get(dev); + if (ret < 0) + return ret; + + ret =3D foo_verify_hardware_id(priv); + if (ret) { + pm_runtime_put(dev); + return ret; + } + + /* + * Drop the usage counter, allowing ->runtime_suspend() to + * power off the device until an I/O request arrives. + */ + pm_runtime_put(dev); + + return 0; + } + +Note that this pattern requires ``CONFIG_PM``. When ``CONFIG_PM`` is +disabled, pm_runtime_resume_and_get() returns 0 without calling +->runtime_resume(), leaving hardware unpowered. Drivers using this pattern +should typically depend on ``CONFIG_PM``. + +Autosuspend Probe +~~~~~~~~~~~~~~~~~ + +If the driver uses autosuspend, it configures the autosuspend delay and en= ables +autosuspend before enabling runtime PM: + +.. code-block:: c + + static int foo_probe(struct platform_device *pdev) + { + struct device *dev =3D &pdev->dev; + struct foo_priv *priv; + int ret; + + priv =3D devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + /* Power on and initialize hardware registers... */ + + /* Set autosuspend delay (e.g. 2000 ms) and enable autosuspend */ + pm_runtime_set_autosuspend_delay(dev, 2000); + pm_runtime_use_autosuspend(dev); + + pm_runtime_set_active(dev); + + /* + * devm_pm_runtime_enable() ensures that pm_runtime_disable() + * and pm_runtime_dont_use_autosuspend() are called upon driver + * unbind. + */ + ret =3D devm_pm_runtime_enable(dev); + if (ret) + return ret; + + /* + * Update last busy timestamp so the driver core's post-probe + * pm_request_idle() respects the autosuspend delay. + */ + pm_runtime_mark_last_busy(dev); + + return 0; + } + +Performing I/O Operations +------------------------- + +Before accessing hardware registers or initiating I/O transfers, drivers m= ust +ensure the device is active by calling pm_runtime_resume_and_get() or simi= lar. + +Basic I/O +~~~~~~~~~ + +For devices without autosuspend, work completion is signaled with +pm_runtime_put(), which drops the usage counter and queues an asynchronous= idle +check once the counter reaches zero: + +.. code-block:: c + + int foo_do_transfer(struct foo_priv *priv, void *buf, size_t count) + { + int ret; + + ret =3D pm_runtime_resume_and_get(priv->dev); + if (ret < 0) + return ret; + + /* Access hardware registers or perform data transfer... */ + ret =3D foo_hardware_transfer(priv, buf, count); + + /* + * Drop usage counter and request asynchronous idle check (and + * suspend, if possible). + */ + pm_runtime_put(priv->dev); + + return ret; + } + +Autosuspend I/O +~~~~~~~~~~~~~~~ + +For devices using autosuspend, work completion is signaled with +pm_runtime_put_autosuspend(), which drops the usage counter and defers +suspension until the autosuspend delay expires: + +.. code-block:: c + + int foo_do_transfer(struct foo_priv *priv, void *buf, size_t count) + { + int ret; + + ret =3D pm_runtime_resume_and_get(priv->dev); + if (ret < 0) + return ret; + + /* Access hardware registers or perform data transfer... */ + ret =3D foo_hardware_transfer(priv, buf, count); + + /* + * Drop the usage counter and schedule an autosuspend once + * the delay expires. Note that pm_runtime_put_autosuspend() + * updates the last-access timestamp automatically. + */ + pm_runtime_put_autosuspend(priv->dev); + + return ret; + } + +Synchronous Completion +~~~~~~~~~~~~~~~~~~~~~~ + +When immediate suspension is desired -- such as before unregistering a +device or during shutdown -- synchronous put helpers can be used instead of +their asynchronous counterparts. Which helper to use depends on whether +autosuspend is configured: + +* For non-autosuspend devices, use pm_runtime_put_sync(). +* For devices that use autosuspend, use pm_runtime_put_sync_suspend(), whi= ch + ignores any configured autosuspend delay and forces immediate suspension. + +However, note several important caveats when relying on synchronous runtime +PM helpers for power-down: + +* **Parents and Suppliers**: While the target device itself is suspended + synchronously, the PM core handles idle notifications for parents and + device link suppliers asynchronously. As a result, parent devices or + power domain suppliers are not guaranteed to be powered off when the + function returns. +* **User Policy ("Forbidden")**: Runtime PM helpers respect system policy. + If user space has set ``/sys/devices/.../power/control`` to ``on`` + (pm_runtime_forbid()), the PM core holds an extra reference on the + device, meaning dropping the driver's usage counter will not trigger a + suspend. + +Because of these constraints, synchronous put helpers may not be suitable +when a driver functionally requires hardware to be powered off +synchronously (for example, to perform a hardware reset or power cycle). +Such requirements may necessitate other methods, such as disabling runtime +PM with pm_runtime_disable() and explicitly executing the hardware +power-down sequence. + +Interrupt Handling with Conditional Get +--------------------------------------- + +Interrupt handlers (especially in atomic or hardirq context) cannot typica= lly +invoke pm_runtime_resume_and_get(), because runtime-resume may sleep. More= over, +if an interrupt arrives while the device is suspended or transitioning to = low +power (e.g., on a shared interrupt line or spurious wakeups), attempting to +read hardware registers could trigger a bus fault or system hang. + +To handle this safely, drivers can conditionally acquire a runtime PM refe= rence +using pm_runtime_get_if_in_use() or pm_runtime_get_if_active(): + +.. code-block:: c + + static irqreturn_t foo_irq_handler(int irq, void *dev_id) + { + struct foo_priv *priv =3D dev_id; + irqreturn_t ret =3D IRQ_NONE; + + /* + * Check if the device is active before reading hardware + * registers. If the device is suspended, this interrupt + * cannot belong to us (or was already serviced). + * + * Note that this also will drop interrupts while runtime PM is + * disabled. + */ + if (pm_runtime_get_if_active(priv->dev) <=3D 0) + return IRQ_NONE; + + /* Hardware is active and usage count is incremented */ + if (foo_has_pending_irq(priv)) { + foo_service_irq(priv); + ret =3D IRQ_HANDLED; + } + + /* + * Release the reference acquired by pm_runtime_get_if_active(). + * For autosuspend devices, use pm_runtime_put_autosuspend(); + * for non-autosuspend devices, use pm_runtime_put(). + */ + pm_runtime_put_autosuspend(priv->dev); + + return ret; + } + +Both pm_runtime_get_if_in_use() and pm_runtime_get_if_active() are safe to= use +from an interrupt routine. One example where a device might be active but = not +"in use" is if autosuspend is used. A device will stay active for a while = with +no users. If interrupts should still be serviced for a device in this stat= e, +pm_runtime_get_if_active() should be used. --=20 2.55.0.979.g7e5102b832-goog