[PATCH v4 5/6] PM / core: Direct handling of DPM_FLAG_LEAVE_SUSPENDED
From: Rafael J. Wysocki Make the PM core handle DPM_FLAG_LEAVE_SUSPENDED directly for devices whose "noirq", "late" and "early" driver callbacks are invoked directly by it. Namely, make it skip all of the system-wide resume callbacks for such devices with DPM_FLAG_LEAVE_SUSPENDED set if they are in runtime suspend during the "noirq" phase of system-wide suspend (or analogous) transitions or the system transition under way is a proper suspend (rather than anything related to hibernation) and the device's wakeup settings are compatible with runtime PM (that is, the device cannot generate wakeup signals at all or it is allowed to wake up the system from sleep). Signed-off-by: Rafael J. Wysocki --- v3 -> v4: Rebase on the v4 of patch [1/6], add a forward declaration of dpm_subsys_suspend_late_cb() dropped from the [4/6]. v2 -> v3: Rebase on the v3 of patch [1/6]. --- Documentation/driver-api/pm/devices.rst |9 + drivers/base/power/main.c | 51 2 files changed, 55 insertions(+), 5 deletions(-) Index: linux-pm/drivers/base/power/main.c === --- linux-pm.orig/drivers/base/power/main.c +++ linux-pm/drivers/base/power/main.c @@ -525,6 +525,10 @@ static void dpm_watchdog_clear(struct dp #define dpm_watchdog_clear(x) #endif +static pm_callback_t dpm_subsys_suspend_late_cb(struct device *dev, + pm_message_t state, + const char **info_p); + /*- Resume routines -*/ /** @@ -581,6 +585,7 @@ static int device_resume_noirq(struct de { pm_callback_t callback; const char *info; + bool skip_resume; int error = 0; TRACE_DEVICE(dev); @@ -594,17 +599,27 @@ static int device_resume_noirq(struct de dpm_wait_for_superior(dev, async); + skip_resume = dev_pm_may_skip_resume(dev); + callback = dpm_subsys_resume_noirq_cb(dev, state, &info); + if (callback) + goto Run; + + if (skip_resume) + goto Skip; if (!callback && dev->driver && dev->driver->pm) { info = "noirq driver "; callback = pm_noirq_op(dev->driver->pm, state); } +Run: error = dpm_run_callback(callback, dev, state, info); + +Skip: dev->power.is_noirq_suspended = false; - if (dev_pm_may_skip_resume(dev)) { + if (skip_resume) { /* * The device is going to be left in suspend, but it might not * have been in runtime suspend before the system suspended, so @@ -617,7 +632,7 @@ static int device_resume_noirq(struct de dev->power.is_suspended = false; } - Out: +Out: complete_all(&dev->power.completion); TRACE_RESUME(error); return error; @@ -1193,6 +1208,7 @@ static int __device_suspend_noirq(struct { pm_callback_t callback; const char *info; + bool direct_cb = false; int error = 0; TRACE_DEVICE(dev); @@ -1212,12 +1228,17 @@ static int __device_suspend_noirq(struct goto Complete; callback = dpm_subsys_suspend_noirq_cb(dev, state, &info); + if (callback) + goto Run; - if (!callback && dev->driver && dev->driver->pm) { + direct_cb = true; + + if (dev->driver && dev->driver->pm) { info = "noirq driver "; callback = pm_noirq_op(dev->driver->pm, state); } +Run: error = dpm_run_callback(callback, dev, state, info); if (error) { async_error = error; @@ -1227,13 +1248,33 @@ static int __device_suspend_noirq(struct dev->power.is_noirq_suspended = true; if (dev_pm_test_driver_flags(dev, DPM_FLAG_LEAVE_SUSPENDED)) { + pm_message_t resume_msg = resume_event(state); + bool skip_resume; + + if (direct_cb && + !dpm_subsys_suspend_late_cb(dev, state, NULL) && + !dpm_subsys_resume_early_cb(dev, resume_msg, NULL) && + !dpm_subsys_resume_noirq_cb(dev, resume_msg, NULL)) { + /* +* If all of the device driver's "noirq", "late" and +* "early" callbacks are invoked directly by the core, +* the decision to allow the device to stay in suspend +* can be based on its current runtime PM status and its +* wakeup settings. +*/ + skip_resume = pm_runtime_status_suspended(dev) || + (resume_msg.event == PM_EVENT_RESUME && +(!device_can_wakeup(dev) || + device_may_wakeup(dev))); +
[PATCH v4 6/6] PM / core: DPM_FLAG_SMART_SUSPEND optimization
From: Rafael J. Wysocki Make the PM core avoid invoking the "late" and "noirq" system-wide suspend (or analogous) callbacks for devices that are in runtime suspend during the corresponding phases of system-wide suspend (or analogous) transitions. The underlying observation is that runtime PM is disabled for devices during those system-wide suspend phases, so their runtime PM status should not change going forward and if it has not changed so far, their state should be compatible with the target system sleep state. This change really makes it possible for, say, platform device drivers to re-use runtime PM suspend and resume callbacks by pointing ->suspend_late and ->resume_early, respectively (and possibly the analogous hibernation-related callback pointers too), to them without adding any extra "is the device already suspended?" type of checks to the callback routines, as long as they will be invoked directly by the core. Signed-off-by: Rafael J. Wysocki --- v3 -> v4: Add a forward declaration of dpm_subsys_suspend_noirq_cb() dropped from patch [4/6]. v2 -> v3: No changes. --- Documentation/driver-api/pm/devices.rst | 18 drivers/base/power/main.c | 66 +--- 2 files changed, 70 insertions(+), 14 deletions(-) Index: linux-pm/drivers/base/power/main.c === --- linux-pm.orig/drivers/base/power/main.c +++ linux-pm/drivers/base/power/main.c @@ -525,6 +525,10 @@ static void dpm_watchdog_clear(struct dp #define dpm_watchdog_clear(x) #endif +static pm_callback_t dpm_subsys_suspend_noirq_cb(struct device *dev, +pm_message_t state, +const char **info_p); + static pm_callback_t dpm_subsys_suspend_late_cb(struct device *dev, pm_message_t state, const char **info_p); @@ -532,6 +536,24 @@ static pm_callback_t dpm_subsys_suspend_ /*- Resume routines -*/ /** + * suspend_event - Return a "suspend" message for given "resume" one. + * @resume_msg: PM message representing a system-wide resume transition. + */ +static pm_message_t suspend_event(pm_message_t resume_msg) +{ + switch (resume_msg.event) { + case PM_EVENT_RESUME: + return PMSG_SUSPEND; + case PM_EVENT_THAW: + case PM_EVENT_RESTORE: + return PMSG_FREEZE; + case PM_EVENT_RECOVER: + return PMSG_HIBERNATE; + } + return PMSG_ON; +} + +/** * dev_pm_may_skip_resume - System-wide device resume optimization check. * @dev: Target device. * @@ -605,6 +627,25 @@ static int device_resume_noirq(struct de if (callback) goto Run; + if (dev_pm_smart_suspend_and_suspended(dev)) { + pm_message_t suspend_msg = suspend_event(state); + + /* +* If "freeze" callbacks have been skipped during a transition +* related to hibernation, the subsequent "thaw" callbacks must +* be skipped too or bad things may happen. Otherwise, if the +* device is to be resumed, its runtime PM status must be +* changed to reflect the new configuration. +*/ + if (!dpm_subsys_suspend_late_cb(dev, suspend_msg, NULL) && + !dpm_subsys_suspend_noirq_cb(dev, suspend_msg, NULL)) { + if (state.event == PM_EVENT_THAW) + skip_resume = true; + else if (!skip_resume) + pm_runtime_set_active(dev); + } + } + if (skip_resume) goto Skip; @@ -1231,7 +1272,10 @@ static int __device_suspend_noirq(struct if (callback) goto Run; - direct_cb = true; + direct_cb = !dpm_subsys_suspend_late_cb(dev, state, NULL); + + if (dev_pm_smart_suspend_and_suspended(dev) && direct_cb) + goto Skip; if (dev->driver && dev->driver->pm) { info = "noirq driver "; @@ -1245,6 +1289,7 @@ Run: goto Complete; } +Skip: dev->power.is_noirq_suspended = true; if (dev_pm_test_driver_flags(dev, DPM_FLAG_LEAVE_SUSPENDED)) { @@ -1252,7 +1297,6 @@ Run: bool skip_resume; if (direct_cb && - !dpm_subsys_suspend_late_cb(dev, state, NULL) && !dpm_subsys_resume_early_cb(dev, resume_msg, NULL) && !dpm_subsys_resume_noirq_cb(dev, resume_msg, NULL)) { /* @@ -1449,17 +1493,27 @@ static int __device_suspend_late(struct goto Complete; callback = dpm_subsys_suspend_late_cb(dev, state, &info); + if (callback)
[PATCH v4 3/6] ACPI / PM: Support for LEAVE_SUSPENDED driver flag in ACPI PM domain
From: Rafael J. Wysocki Add support for DPM_FLAG_LEAVE_SUSPENDED to the ACPI PM domain by making it (a) set the power.may_skip_resume status bit for devices that, from its perspective, may be left in suspend after system wakeup from sleep and (b) return early from acpi_subsys_resume_noirq() for devices whose remaining resume callbacks during the transition under way are going to be skipped by the PM core. Signed-off-by: Rafael J. Wysocki Acked-by: Greg Kroah-Hartman --- v2 -> v4: No changes. --- drivers/acpi/device_pm.c | 27 --- 1 file changed, 24 insertions(+), 3 deletions(-) Index: linux-pm/drivers/acpi/device_pm.c === --- linux-pm.orig/drivers/acpi/device_pm.c +++ linux-pm/drivers/acpi/device_pm.c @@ -990,7 +990,7 @@ void acpi_subsys_complete(struct device * the sleep state it is going out of and it has never been resumed till * now, resume it in case the firmware powered it up. */ - if (dev->power.direct_complete && pm_resume_via_firmware()) + if (pm_runtime_suspended(dev) && pm_resume_via_firmware()) pm_request_resume(dev); } EXPORT_SYMBOL_GPL(acpi_subsys_complete); @@ -1039,10 +1039,28 @@ EXPORT_SYMBOL_GPL(acpi_subsys_suspend_la */ int acpi_subsys_suspend_noirq(struct device *dev) { - if (dev_pm_smart_suspend_and_suspended(dev)) + int ret; + + if (dev_pm_smart_suspend_and_suspended(dev)) { + dev->power.may_skip_resume = true; return 0; + } - return pm_generic_suspend_noirq(dev); + ret = pm_generic_suspend_noirq(dev); + if (ret) + return ret; + + /* +* If the target system sleep state is suspend-to-idle, it is sufficient +* to check whether or not the device's wakeup settings are good for +* runtime PM. Otherwise, the pm_resume_via_firmware() check will cause +* acpi_subsys_complete() to take care of fixing up the device's state +* anyway, if need be. +*/ + dev->power.may_skip_resume = device_may_wakeup(dev) || + !device_can_wakeup(dev); + + return 0; } EXPORT_SYMBOL_GPL(acpi_subsys_suspend_noirq); @@ -1052,6 +1070,9 @@ EXPORT_SYMBOL_GPL(acpi_subsys_suspend_no */ int acpi_subsys_resume_noirq(struct device *dev) { + if (dev_pm_may_skip_resume(dev)) + return 0; + /* * Devices with DPM_FLAG_SMART_SUSPEND may be left in runtime suspend * during system suspend, so update their runtime PM status to "active" -- To unsubscribe from this list: send the line "unsubscribe linux-doc" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v4 1/6] PM / core: Add LEAVE_SUSPENDED driver flag
From: Rafael J. Wysocki Define and document a new driver flag, DPM_FLAG_LEAVE_SUSPENDED, to instruct the PM core and middle-layer (bus type, PM domain, etc.) code that it is desirable to leave the device in runtime suspend after system-wide transitions to the working state (for example, the device may be slow to resume and it may be better to avoid resuming it right away). Generally, the middle-layer code involved in the handling of the device is expected to indicate to the PM core whether or not the device may be left in suspend with the help of the device's power.may_skip_resume status bit. That has to happen in the "noirq" phase of the preceding system suspend (or analogous) transition. The middle layer is then responsible for handling the device as appropriate in its "noirq" resume callback which is executed regardless of whether or not the device may be left suspended, but the other resume callbacks (except for ->complete) will be skipped automatically by the core if the device really can be left in suspend. The additional power.must_resume status bit introduced for the implementation of this mechanisn is used internally by the PM core to track the requirement to resume the device (which may depend on its children etc). Signed-off-by: Rafael J. Wysocki Acked-by: Greg Kroah-Hartman --- v3 -> v4: Fix the dev->power.usage_count check added in v3, clarify documentation, add comment to explain why the runtime PM status is changed in device_resume_noirq() and make the description of the NEVER_SKIP flag more precise. v2 -> v3: Take dev->power.usage_count when updating power.must_resume in __device_suspend_noirq(). --- Documentation/driver-api/pm/devices.rst | 27 ++- drivers/base/power/main.c | 73 +--- include/linux/pm.h | 16 +-- 3 files changed, 105 insertions(+), 11 deletions(-) Index: linux-pm/include/linux/pm.h === --- linux-pm.orig/include/linux/pm.h +++ linux-pm/include/linux/pm.h @@ -556,9 +556,10 @@ struct pm_subsys_data { * These flags can be set by device drivers at the probe time. They need not be * cleared by the drivers as the driver core will take care of that. * - * NEVER_SKIP: Do not skip system suspend/resume callbacks for the device. + * NEVER_SKIP: Do not skip all system suspend/resume callbacks for the device. * SMART_PREPARE: Check the return value of the driver's ->prepare callback. * SMART_SUSPEND: No need to resume the device from runtime suspend. + * LEAVE_SUSPENDED: Avoid resuming the device during system resume if possible. * * Setting SMART_PREPARE instructs bus types and PM domains which may want * system suspend/resume callbacks to be skipped for the device to return 0 from @@ -572,10 +573,14 @@ struct pm_subsys_data { * necessary from the driver's perspective. It also may cause them to skip * invocations of the ->suspend_late and ->suspend_noirq callbacks provided by * the driver if they decide to leave the device in runtime suspend. + * + * Setting LEAVE_SUSPENDED informs the PM core and middle-layer code that the + * driver prefers the device to be left in suspend after system resume. */ -#define DPM_FLAG_NEVER_SKIPBIT(0) -#define DPM_FLAG_SMART_PREPARE BIT(1) -#define DPM_FLAG_SMART_SUSPEND BIT(2) +#define DPM_FLAG_NEVER_SKIPBIT(0) +#define DPM_FLAG_SMART_PREPARE BIT(1) +#define DPM_FLAG_SMART_SUSPEND BIT(2) +#define DPM_FLAG_LEAVE_SUSPENDED BIT(3) struct dev_pm_info { pm_message_tpower_state; @@ -597,6 +602,8 @@ struct dev_pm_info { boolwakeup_path:1; boolsyscore:1; boolno_pm_callbacks:1; /* Owned by the PM core */ + unsigned intmust_resume:1; /* Owned by the PM core */ + unsigned intmay_skip_resume:1; /* Set by subsystems */ #else unsigned intshould_wakeup:1; #endif @@ -765,6 +772,7 @@ extern int pm_generic_poweroff_late(stru extern int pm_generic_poweroff(struct device *dev); extern void pm_generic_complete(struct device *dev); +extern bool dev_pm_may_skip_resume(struct device *dev); extern bool dev_pm_smart_suspend_and_suspended(struct device *dev); #else /* !CONFIG_PM_SLEEP */ Index: linux-pm/drivers/base/power/main.c === --- linux-pm.orig/drivers/base/power/main.c +++ linux-pm/drivers/base/power/main.c @@ -528,6 +528,18 @@ static void dpm_watchdog_clear(struct dp /*- Resume routines -*/ /** + * dev_pm_may_skip_resume - System-wide device resume optimization check. + * @dev: Target device. + * + * Checks whether or not the device may be left in suspend after a system-wide + * transition to the working state. + */
[PATCH v4 2/6] PCI / PM: Support for LEAVE_SUSPENDED driver flag
From: Rafael J. Wysocki Add support for DPM_FLAG_LEAVE_SUSPENDED to the PCI bus type by making it (a) set the power.may_skip_resume status bit for devices that, from its perspective, may be left in suspend after system wakeup from sleep and (b) return early from pci_pm_resume_noirq() for devices whose remaining resume callbacks during the transition under way are going to be skipped by the PM core. Signed-off-by: Rafael J. Wysocki Acked-by: Greg Kroah-Hartman Acked-by: Bjorn Helgaas --- v3 -> v4: No changes. v2 -> v3: Add the Acked-by from Bjorn, no changes in the patch. --- Documentation/power/pci.txt | 11 +++ drivers/pci/pci-driver.c| 19 +-- 2 files changed, 28 insertions(+), 2 deletions(-) Index: linux-pm/drivers/pci/pci-driver.c === --- linux-pm.orig/drivers/pci/pci-driver.c +++ linux-pm/drivers/pci/pci-driver.c @@ -699,7 +699,7 @@ static void pci_pm_complete(struct devic pm_generic_complete(dev); /* Resume device if platform firmware has put it in reset-power-on */ - if (dev->power.direct_complete && pm_resume_via_firmware()) { + if (pm_runtime_suspended(dev) && pm_resume_via_firmware()) { pci_power_t pre_sleep_state = pci_dev->current_state; pci_update_current_state(pci_dev, pci_dev->current_state); @@ -783,8 +783,10 @@ static int pci_pm_suspend_noirq(struct d struct pci_dev *pci_dev = to_pci_dev(dev); const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; - if (dev_pm_smart_suspend_and_suspended(dev)) + if (dev_pm_smart_suspend_and_suspended(dev)) { + dev->power.may_skip_resume = true; return 0; + } if (pci_has_legacy_pm_support(pci_dev)) return pci_legacy_suspend_late(dev, PMSG_SUSPEND); @@ -838,6 +840,16 @@ static int pci_pm_suspend_noirq(struct d Fixup: pci_fixup_device(pci_fixup_suspend_late, pci_dev); + /* +* If the target system sleep state is suspend-to-idle, it is sufficient +* to check whether or not the device's wakeup settings are good for +* runtime PM. Otherwise, the pm_resume_via_firmware() check will cause +* pci_pm_complete() to take care of fixing up the device's state +* anyway, if need be. +*/ + dev->power.may_skip_resume = device_may_wakeup(dev) || + !device_can_wakeup(dev); + return 0; } @@ -847,6 +859,9 @@ static int pci_pm_resume_noirq(struct de struct device_driver *drv = dev->driver; int error = 0; + if (dev_pm_may_skip_resume(dev)) + return 0; + /* * Devices with DPM_FLAG_SMART_SUSPEND may be left in runtime suspend * during system suspend, so update their runtime PM status to "active" Index: linux-pm/Documentation/power/pci.txt === --- linux-pm.orig/Documentation/power/pci.txt +++ linux-pm/Documentation/power/pci.txt @@ -994,6 +994,17 @@ into D0 going forward), but if it is in the function will set the power.direct_complete flag for it (to make the PM core skip the subsequent "thaw" callbacks for it) and return. +Setting the DPM_FLAG_LEAVE_SUSPENDED flag means that the driver prefers the +device to be left in suspend after system-wide transitions to the working state. +This flag is checked by the PM core, but the PCI bus type informs the PM core +which devices may be left in suspend from its perspective (that happens during +the "noirq" phase of system-wide suspend and analogous transitions) and next it +uses the dev_pm_may_skip_resume() helper to decide whether or not to return from +pci_pm_resume_noirq() early, as the PM core will skip the remaining resume +callbacks for the device during the transition under way and will set its +runtime PM status to "suspended" if dev_pm_may_skip_resume() returns "true" for +it. + 3.2. Device Runtime Power Management In addition to providing device power management callbacks PCI device drivers -- To unsubscribe from this list: send the line "unsubscribe linux-doc" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v4 4/6] PM / core: Add helpers for subsystem callback selection
From: Rafael J. Wysocki Add helper routines to find and return a suitable subsystem callback during the "noirq" phases of system suspend/resume (or analogous) transitions as well as during the "late" phase of system suspend and the "early" phase of system resume (or analogous) transitions. The helpers will be called from additional sites going forward. Signed-off-by: Rafael J. Wysocki Reviewed-by: Ulf Hansson --- v3 -> v4: Move forward declarations of two functions to subsequent patches, add Reviewed-by from Ulf. v2 -> v3: No changes. --- drivers/base/power/main.c | 188 +++--- 1 file changed, 128 insertions(+), 60 deletions(-) Index: linux-pm/drivers/base/power/main.c === --- linux-pm.orig/drivers/base/power/main.c +++ linux-pm/drivers/base/power/main.c @@ -539,6 +539,35 @@ bool dev_pm_may_skip_resume(struct devic return !dev->power.must_resume && pm_transition.event != PM_EVENT_RESTORE; } +static pm_callback_t dpm_subsys_resume_noirq_cb(struct device *dev, + pm_message_t state, + const char **info_p) +{ + pm_callback_t callback; + const char *info; + + if (dev->pm_domain) { + info = "noirq power domain "; + callback = pm_noirq_op(&dev->pm_domain->ops, state); + } else if (dev->type && dev->type->pm) { + info = "noirq type "; + callback = pm_noirq_op(dev->type->pm, state); + } else if (dev->class && dev->class->pm) { + info = "noirq class "; + callback = pm_noirq_op(dev->class->pm, state); + } else if (dev->bus && dev->bus->pm) { + info = "noirq bus "; + callback = pm_noirq_op(dev->bus->pm, state); + } else { + return NULL; + } + + if (info_p) + *info_p = info; + + return callback; +} + /** * device_resume_noirq - Execute a "noirq resume" callback for given device. * @dev: Device to handle. @@ -550,8 +579,8 @@ bool dev_pm_may_skip_resume(struct devic */ static int device_resume_noirq(struct device *dev, pm_message_t state, bool async) { - pm_callback_t callback = NULL; - const char *info = NULL; + pm_callback_t callback; + const char *info; int error = 0; TRACE_DEVICE(dev); @@ -565,19 +594,7 @@ static int device_resume_noirq(struct de dpm_wait_for_superior(dev, async); - if (dev->pm_domain) { - info = "noirq power domain "; - callback = pm_noirq_op(&dev->pm_domain->ops, state); - } else if (dev->type && dev->type->pm) { - info = "noirq type "; - callback = pm_noirq_op(dev->type->pm, state); - } else if (dev->class && dev->class->pm) { - info = "noirq class "; - callback = pm_noirq_op(dev->class->pm, state); - } else if (dev->bus && dev->bus->pm) { - info = "noirq bus "; - callback = pm_noirq_op(dev->bus->pm, state); - } + callback = dpm_subsys_resume_noirq_cb(dev, state, &info); if (!callback && dev->driver && dev->driver->pm) { info = "noirq driver "; @@ -693,6 +710,35 @@ void dpm_resume_noirq(pm_message_t state dpm_noirq_end(); } +static pm_callback_t dpm_subsys_resume_early_cb(struct device *dev, + pm_message_t state, + const char **info_p) +{ + pm_callback_t callback; + const char *info; + + if (dev->pm_domain) { + info = "early power domain "; + callback = pm_late_early_op(&dev->pm_domain->ops, state); + } else if (dev->type && dev->type->pm) { + info = "early type "; + callback = pm_late_early_op(dev->type->pm, state); + } else if (dev->class && dev->class->pm) { + info = "early class "; + callback = pm_late_early_op(dev->class->pm, state); + } else if (dev->bus && dev->bus->pm) { + info = "early bus "; + callback = pm_late_early_op(dev->bus->pm, state); + } else { + return NULL; + } + + if (info_p) + *info_p = info; + + return callback; +} + /** * device_resume_early - Execute an "early resume" callback for given device. * @dev: Device to handle. @@ -703,8 +749,8 @@ void dpm_resume_noirq(pm_message_t state */ static int device_resume_early(struct device *dev, pm_message_t state, bool async) { - pm_callback_t callback = NULL; - const char *info = NULL; + pm_callback_t callback; + const char *info; int error = 0; TRACE_DEVICE(dev); @@ -718,19 +764,7 @@ static int device_resume_early(struct de
Re: [PATCH v4 0/6] PM / sleep: Driver flags for system suspend/resume (part 2)
Hi All, The following still applies: > On Wednesday, November 8, 2017 1:41:35 AM CET Rafael J. Wysocki wrote: > > > > This is a follow-up for the first part of the PM driver flags series > > sent previously some time ago with an intro as follows: > > > > On Saturday, October 28, 2017 12:11:55 AM CET Rafael J. Wysocki wrote: > > > The following part of the original cover letter still applies: > > > > > > On Monday, October 16, 2017 3:12:35 AM CEST Rafael J. Wysocki wrote: > > > > > > > > This work was triggered by attempts to fix and optimize PM in the > > > > i2c-designware-platdev driver that ended up with adding a couple of > > > > flags to the driver's internal data structures for the tracking of > > > > device state (https://marc.info/?l=linux-acpi&m=150629646805636&w=2). > > > > That approach is sort of suboptimal, though, because other drivers will > > > > probably want to do similar things and if all of them need to use > > > > internal > > > > flags for that, quite a bit of code duplication may ensue at least. > > > > > > > > That can be avoided in a couple of ways and one of them is to provide a > > > > means > > > > for drivers to tell the core what to do and to make the core take care > > > > of it > > > > if told to do so. Hence, the idea to use driver flags for system-wide > > > > PM > > > > that was briefly discussed during the LPC in LA last month. > > > > > > [...] > > > > > > > What can work (and this is the only strategy that can work AFAICS) is to > > > > point different callback pointers *in* *a* *driver* to the same routine > > > > if the driver wants to reuse that code. That actually will work for PCI > > > > and USB drivers today, at least most of the time, but unfortunately > > > > there > > > > are problems with it for, say, platform devices. > > > > > > > > The first problem is the requirement to track the status of the device > > > > (suspended vs not suspended) in the callbacks, because the system-wide > > > > PM > > > > code in the PM core doesn't do that. The runtime PM framework does it, > > > > so > > > > this means adding some extra code which isn't necessary for runtime PM > > > > to > > > > the callback routines and that is not particularly nice. > > > > > > > > The second problem is that, if the driver wants to do anything in its > > > > ->suspend callback, it generally has to prevent runtime suspend of the > > > > device from taking place in parallel with that, which is quite > > > > cumbersome. > > > > Usually, that is taken care of by resuming the device from runtime > > > > suspend > > > > upfront, but generally doing that is wasteful (there may be no real > > > > need to > > > > resume the device except for the fact that the code is designed this > > > > way). > > > > > > > > On top of the above, there are optimizations to be made, like leaving > > > > certain > > > > devices in suspend after system resume to avoid wasting time on waiting > > > > for > > > > them to resume before user space can run again and similar. > > > > > > > > This patch series focuses on addressing those problems so as to make it > > > > easier to reuse callback routines by pointing different callback > > > > pointers > > > > to them in device drivers. The flags introduced here are to instruct > > > > the > > > > PM core and middle layers (whatever they are) on how the driver wants > > > > the > > > > device to be handled and then the driver has to provide callbacks to > > > > match > > > > these instructions and the rest should be taken care of by the code > > > > above it. > > > > > > > > The flags are introduced one by one to avoid making too many changes in > > > > one go and to allow things to be explained better (hopefully). They > > > > mostly > > > > are mutually independent with some clearly documented exceptions. > > > > > > but I had to rework the core patches to address the problem pointed with > > > the > > > generic power domains (genpd) framework pointed out by Ulf. > > > > > > Namely, genpd expects its "noirq" callbacks to be invoked for devices in > > > runtime suspend too and it has valid reasons for that, so its "noirq" > > > callbacks can never be skipped, even for devices with the SMART_SUSPEND > > > flag set. For this reason, the logic related to DPM_FLAG_SMART_SUSPEND > > > had to be moved from the core to the PCI bus type and the ACPI PM domain > > > which are mostly affected by it anyway. The code after the changes looks > > > more straightforward to me, but it generally is more code and some > > > patterns > > > had to be repeated in a few places. > > > > I promised to send the rest of the series then: > > > > > I will send the core patches for the remaining two flags introduced by the > > > original series separately and the intel-lpss and i2c-designware ones will > > > be posted when the core patches have been reviewed and agreed on. > > > > and here it goes. > > > > It actually only adds support for one additional fl
[PATCH] doc: linux-wpan: Fulfill the description of missed 802.15.4 APIs
There are more functions and operations which must be used or implemented in each IEEE 802.15.4 device driver, but are not mentioned in the Device drivers API section of Documentation/networking/ieee802154.txt. Therefore, I want to fulfill the missed part into the documentation with this patch. Signed-off-by: Jian-Hong Pan --- Documentation/networking/ieee802154.txt | 40 + 1 file changed, 40 insertions(+) diff --git a/Documentation/networking/ieee802154.txt b/Documentation/networking/ieee802154.txt index 057e9fdbfac9..e74d8e1da0e2 100644 --- a/Documentation/networking/ieee802154.txt +++ b/Documentation/networking/ieee802154.txt @@ -97,6 +97,46 @@ The include/net/mac802154.h defines following functions: - void ieee802154_unregister_hw(struct ieee802154_hw *hw): freeing registered PHY + - void ieee802154_rx_irqsafe(struct ieee802154_hw *hw, struct sk_buff *skb, + u8 lqi): + telling 802.15.4 module there is a new received frame in the skb with + the RF Link Quality Indicator (LQI) from the hardware device + + - void ieee802154_xmit_complete(struct ieee802154_hw *hw, struct sk_buff *skb, + bool ifs_handling): + telling 802.15.4 module the frame in the skb is or going to be + transmitted through the hardware device + +The device driver must implement the following callbacks in the IEEE 802.15.4 +operations structure at least: +struct ieee802154_ops { + ... + int (*start)(struct ieee802154_hw *hw); + void(*stop)(struct ieee802154_hw *hw); + ... + int (*xmit_async)(struct ieee802154_hw *hw, struct sk_buff *skb); + int (*ed)(struct ieee802154_hw *hw, u8 *level); + int (*set_channel)(struct ieee802154_hw *hw, u8 page, u8 channel); + ... +}; + + - int start(struct ieee802154_hw *hw): + handler that 802.15.4 module calls for the hardware device initialization. + + - void stop(struct ieee802154_hw *hw): + handler that 802.15.4 module calls for the hardware device cleanup. + + - int xmit_async(struct ieee802154_hw *hw, struct sk_buff *skb): + handler that 802.15.4 module calls for each frame in the skb going to be + transmitted through the hardware device. + + - int ed(struct ieee802154_hw *hw, u8 *level): + handler that 802.15.4 module calls for Energy Detection from the hardware + device. + + - int set_channel(struct ieee802154_hw *hw, u8 page, u8 channel): + set radio for listening on specific channel of the hardware device. + Moreover IEEE 802.15.4 device operations structure should be filled. Fake drivers -- 2.15.0 -- To unsubscribe from this list: send the line "unsubscribe linux-doc" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 06/15] ima: add parser of digest lists metadata
Hi Serge, On Fri, 2017-11-17 at 22:20 -0600, Serge E. Hallyn wrote: > On Tue, Nov 07, 2017 at 11:37:01AM +0100, Roberto Sassu wrote: > > from a predefined position (/etc/ima/digest_lists/metadata), when rootfs > > becomes available. Digest lists must be loaded before IMA appraisal is in > > enforcing mode. > > I'm sure there's a good reason for it, but this seems weird to me. > Why read it from a file on disk instead of accepting it through say > a securityfile write? Assuming that the concept of a white list is something we want to support, then at minimum the list needs to be signed and verified. Instead of defining a new Kconfig pathname option, a securityfs file could read it, like the IMA policy. Mimi -- To unsubscribe from this list: send the line "unsubscribe linux-doc" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html